Commit aee511ba authored by czd890's avatar czd890 Committed by Jason Song

init i18n support

parent 5cfdd0d1
...@@ -271,7 +271,7 @@ public class AuthConfiguration { ...@@ -271,7 +271,7 @@ public class AuthConfiguration {
http.csrf().disable(); http.csrf().disable();
http.headers().frameOptions().sameOrigin(); http.headers().frameOptions().sameOrigin();
http.authorizeRequests() http.authorizeRequests()
.antMatchers("/prometheus/**","/metrics/**","/openapi/**", "/vendor/**", "/styles/**", "/scripts/**", "/views/**", "/img/**").permitAll() .antMatchers("/prometheus/**","/metrics/**","/openapi/**", "/vendor/**", "/styles/**", "/scripts/**", "/views/**", "/img/**", "/i18n/**").permitAll()
.antMatchers("/**").hasAnyRole(USER_ROLE); .antMatchers("/**").hasAnyRole(USER_ROLE);
http.formLogin().loginPage("/signin").defaultSuccessUrl("/", true).permitAll().failureUrl("/signin?#/error").and() http.formLogin().loginPage("/signin").defaultSuccessUrl("/", true).permitAll().failureUrl("/signin?#/error").and()
.httpBasic(); .httpBasic();
...@@ -403,7 +403,7 @@ public class AuthConfiguration { ...@@ -403,7 +403,7 @@ public class AuthConfiguration {
http.csrf().disable(); http.csrf().disable();
http.headers().frameOptions().sameOrigin(); http.headers().frameOptions().sameOrigin();
http.authorizeRequests() http.authorizeRequests()
.antMatchers("/prometheus/**","/metrics/**","/openapi/**", "/vendor/**", "/styles/**", "/scripts/**", "/views/**", "/img/**").permitAll() .antMatchers("/prometheus/**","/metrics/**","/openapi/**", "/vendor/**", "/styles/**", "/scripts/**", "/views/**", "/img/**", "/i18n/**").permitAll()
.antMatchers("/**").authenticated(); .antMatchers("/**").authenticated();
http.formLogin().loginPage("/signin").defaultSuccessUrl("/", true).permitAll().failureUrl("/signin?#/error").and() http.formLogin().loginPage("/signin").defaultSuccessUrl("/", true).permitAll().failureUrl("/signin?#/error").and()
.httpBasic(); .httpBasic();
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
<link rel="stylesheet" type="text/css" media='all' href="vendor/angular/loading-bar.min.css"> <link rel="stylesheet" type="text/css" media='all' href="vendor/angular/loading-bar.min.css">
<link rel="stylesheet" type="text/css" href="styles/common-style.css"> <link rel="stylesheet" type="text/css" href="styles/common-style.css">
<title>新建项目</title> <title>{{'App.CreateProject' | translate }}</title>
</head> </head>
<body> <body>
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
<div class="col-md-8 col-md-offset-2"> <div class="col-md-8 col-md-offset-2">
<div class="panel"> <div class="panel">
<header class="panel-heading"> <header class="panel-heading">
创建项目 {{'App.CreateProject' | translate }}
</header> </header>
<form class="form-horizontal panel-body" name="appForm" ng-controller="CreateAppController" <form class="form-horizontal panel-body" name="appForm" ng-controller="CreateAppController"
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label"> <label class="col-sm-3 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
部门</label> {{'Common.Department' | translate }}</label>
<div class="col-sm-3"> <div class="col-sm-3">
<select id="organization"> <select id="organization">
<option></option> <option></option>
...@@ -41,43 +41,44 @@ ...@@ -41,43 +41,44 @@
<div class="form-group" valdr-form-group> <div class="form-group" valdr-form-group>
<label class="col-sm-3 control-label"> <label class="col-sm-3 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
应用Id</label> {{'Common.AppId' | translate }}</label>
<div class="col-sm-3"> <div class="col-sm-3">
<input type="text" class="form-control" name="appId" ng-model="app.appId"> <input type="text" class="form-control" name="appId" ng-model="app.appId">
<small>(应用唯一标识)</small> <small>{{'App.AppIdTips' | translate }}
</small>
</div> </div>
</div> </div>
<div class="form-group" valdr-form-group> <div class="form-group" valdr-form-group>
<label class="col-sm-3 control-label"> <label class="col-sm-3 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
应用名称</label> {{'Common.AppName' | translate }}</label>
<div class="col-sm-5"> <div class="col-sm-5">
<input type="text" class="form-control" name="appName" ng-model="app.name"> <input type="text" class="form-control" name="appName" ng-model="app.name">
<small>(建议格式 xx-yy-zz 例:apollo-server)</small> <small>{{'App.AppNameTips' | translate }}</small>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label"> <label class="col-sm-3 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
应用负责人</label> {{'Common.AppOwner' | translate }}</label>
<div class="col-sm-6 J_ownerSelectorPanel"> <div class="col-sm-6 J_ownerSelectorPanel">
<apollouserselector apollo-id="'ownerSelector'" disabled="isOpenManageAppMasterRoleLimit"></apollouserselector> <apollouserselector apollo-id="'ownerSelector'" disabled="isOpenManageAppMasterRoleLimit"></apollouserselector>
<small style="color: maroon" ng-if="isOpenManageAppMasterRoleLimit">(开启项目管理员分配权限控制后,应用负责人和项目管理员默认为本账号,不可选择)</small> <small style="color: maroon" ng-if="isOpenManageAppMasterRoleLimit">{{'App.AppOwnerTips' | translate }}</small>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">项目管理员<br> <label class="col-sm-3 control-label">{{'Common.AppAdmin' | translate }}<br>
</label> </label>
<div class="col-sm-9 J_adminSelectorPanel"> <div class="col-sm-9 J_adminSelectorPanel">
<apollomultipleuserselector apollo-id="'adminSelector'" ng-disabled="isOpenManageAppMasterRoleLimit"></apollomultipleuserselector> <apollomultipleuserselector apollo-id="'adminSelector'" ng-disabled="isOpenManageAppMasterRoleLimit"></apollomultipleuserselector>
<br> <br>
<small>(应用负责人默认具有项目管理员权限,</small> <small>{{'App.AppAdminTips1' | translate }}</small>
<br> <br>
<small>项目管理员可以创建Namespace和集群、分配用户权限)</small> <small>{{'App.AppAdminTips2' | translate }}</small>
</div> </div>
</div> </div>
...@@ -86,7 +87,7 @@ ...@@ -86,7 +87,7 @@
<div class="col-sm-offset-3 col-sm-9"> <div class="col-sm-offset-3 col-sm-9">
<button type="submit" class="btn btn-primary" <button type="submit" class="btn btn-primary"
ng-disabled="appForm.$invalid || submitBtnDisabled">提交 ng-disabled="appForm.$invalid || submitBtnDisabled">{{'Common.Submit' | translate }}
</button> </button>
</div> </div>
</div> </div>
...@@ -104,6 +105,11 @@ ...@@ -104,6 +105,11 @@
<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>
<script src="vendor/angular/angular-cookies.min.js"></script>
<script src="vendor/angular/angular-translate.2.18.1/angular-translate.min.js"></script>
<script src="vendor/angular/angular-translate.2.18.1/angular-translate-loader-static-files.min.js"></script>
<script src="vendor/angular/angular-translate.2.18.1/angular-translate-storage-cookie.min.js"></script>
<!-- jquery.js --> <!-- jquery.js -->
<script src="vendor/jquery.min.js" type="text/javascript"></script> <script src="vendor/jquery.min.js" type="text/javascript"></script>
......
<!doctype html> <!doctype html>
<html ng-app="setting"> <html ng-app="setting">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="icon" href="../img/config.png"> <link rel="icon" href="../img/config.png">
...@@ -9,24 +10,25 @@ ...@@ -9,24 +10,25 @@
<link rel="stylesheet" type="text/css" media='all' href="../vendor/angular/loading-bar.min.css"> <link rel="stylesheet" type="text/css" media='all' href="../vendor/angular/loading-bar.min.css">
<link rel="stylesheet" type="text/css" href="../styles/common-style.css"> <link rel="stylesheet" type="text/css" href="../styles/common-style.css">
<link rel="stylesheet" type="text/css" href="../vendor/select2/select2.min.css"> <link rel="stylesheet" type="text/css" href="../vendor/select2/select2.min.css">
<title>项目管理</title> <title>{{'App.Setting.Title' | translate }}</title>
</head> </head>
<body> <body>
<apollonav></apollonav> <apollonav></apollonav>
<div class="container-fluid apollo-container project-setting" ng-controller="SettingController"> <div class="container-fluid apollo-container project-setting" ng-controller="SettingController">
<section class="col-md-10 col-md-offset-1 panel hidden"> <section class="col-md-10 col-md-offset-1 panel hidden">
<header class="panel-heading"> <header class="panel-heading">
<div class="row"> <div class="row">
<div class="col-md-7"> <div class="col-md-7">
<h4 class="modal-title">项目管理 ( AppId:<label ng-bind="pageContext.appId"></label> ) <h4 class="modal-title">{{'App.Setting.Title' | translate }} (
{{'Common.AppId' | translate }}:<label ng-bind="pageContext.appId"></label> )
</h4> </h4>
</div> </div>
<div class="col-md-5 text-right"> <div class="col-md-5 text-right">
<a type="button" class="btn btn-info" data-dismiss="modal" <a type="button" class="btn btn-info" data-dismiss="modal"
href="/config.html?#appid={{pageContext.appId}}">返回到项目首页 href="/config.html?#appid={{pageContext.appId}}">{{'Common.ReturnToIndex' | translate }}
</a> </a>
</div> </div>
</div> </div>
...@@ -37,9 +39,9 @@ ...@@ -37,9 +39,9 @@
<section class="context" ng-show="hasAssignUserPermission"> <section class="context" ng-show="hasAssignUserPermission">
<!--project admin--> <!--project admin-->
<section class="form-horizontal" ng-show="hasManageAppMasterPermission"> <section class="form-horizontal" ng-show="hasManageAppMasterPermission">
<h5>管理员 <h5>{{'App.Setting.Admin' | translate }}
<small> <small>
(项目管理员具有以下权限: 1. 创建Namespace 2. 创建集群 3. 管理项目、Namespace权限) {{'App.Setting.AdminTips' | translate }}
</small> </small>
</h5> </h5>
<hr> <hr>
...@@ -50,7 +52,7 @@ ...@@ -50,7 +52,7 @@
<apollouserselector apollo-id="userSelectWidgetId"></apollouserselector> <apollouserselector apollo-id="userSelectWidgetId"></apollouserselector>
</div> </div>
<button type="submit" class="btn btn-default" style="margin-left: 20px;" <button type="submit" class="btn btn-default" style="margin-left: 20px;"
ng-disabled="submitBtnDisabled">添加 ng-disabled="submitBtnDisabled">{{'App.Setting.Add' | translate }}
</button> </button>
</form> </form>
<!-- Split button --> <!-- Split button -->
...@@ -73,15 +75,15 @@ ...@@ -73,15 +75,15 @@
<!--application info--> <!--application info-->
<section> <section>
<h5>基本信息</h5> <h5>{{'App.Setting.BasicInfo' | translate }}</h5>
<hr> <hr>
<form class="form-horizontal" name="appForm" valdr-type="App" <form class="form-horizontal" name="appForm" valdr-type="App" ng-submit="updateAppInfo()">
ng-submit="updateAppInfo()">
<div class="form-group" valdr-form-group> <div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
AppId</label> {{'Common.AppId' | translate }}
</label>
<div class="col-sm-3"> <div class="col-sm-3">
<label class="form-control-static" ng-bind="pageContext.appId"> <label class="form-control-static" ng-bind="pageContext.appId">
</label> </label>
...@@ -90,7 +92,8 @@ ...@@ -90,7 +92,8 @@
<div class="form-group"> <div class="form-group">
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
部门</label> {{'Common.Department' | translate }}
</label>
<div class="col-sm-3"> <div class="col-sm-3">
<select id="organization" ng-disabled="!display.app.edit"> <select id="organization" ng-disabled="!display.app.edit">
<option></option> <option></option>
...@@ -101,39 +104,38 @@ ...@@ -101,39 +104,38 @@
<div class="form-group" valdr-form-group> <div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
项目名称</label> {{'App.Setting.ProjectName' | translate }}
</label>
<div class="col-sm-4"> <div class="col-sm-4">
<input type="text" class="form-control" name="appName" ng-model="viewApp.name" <input type="text" class="form-control" name="appName" ng-model="viewApp.name"
ng-disabled="!display.app.edit"> ng-disabled="!display.app.edit">
<small>(建议格式 xx-yy-zz 例:apollo-server)</small> <small>{{'App.Setting.ProjectNameTips' | translate }}</small>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
项目负责人</label> {{'App.Setting.ProjectOwner' | translate }}
</label>
<div class="col-sm-6 J_ownerSelectorPanel"> <div class="col-sm-6 J_ownerSelectorPanel">
<apollouserselector apollo-id="'ownerSelector'" <apollouserselector apollo-id="'ownerSelector'" disabled="!display.app.edit">
disabled="!display.app.edit"></apollouserselector> </apollouserselector>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="col-sm-offset-2 col-sm-9"> <div class="col-sm-offset-2 col-sm-9">
<button type="button" class="btn btn-primary" <button type="button" class="btn btn-primary" ng-show="!display.app.edit"
ng-show="!display.app.edit"
ng-click="toggleEditStatus()"> ng-click="toggleEditStatus()">
修改项目信息 {{'App.Setting.Modify' | translate }}
</button> </button>
<button type="button" class="btn btn-warning" <button type="button" class="btn btn-warning" ng-show="display.app.edit"
ng-show="display.app.edit"
ng-click="toggleEditStatus()"> ng-click="toggleEditStatus()">
取消修改 {{'App.Setting.Cancel' | translate }}
</button> </button>
<button type="submit" class="btn btn-primary" <button type="submit" class="btn btn-primary" ng-show="display.app.edit"
ng-show="display.app.edit"
ng-disabled="appForm.$invalid || submitBtnDisabled"> ng-disabled="appForm.$invalid || submitBtnDisabled">
提交 {{'Common.Submit' | translate }}
</button> </button>
</div> </div>
</div> </div>
...@@ -145,56 +147,61 @@ ...@@ -145,56 +147,61 @@
<section class="context" ng-show="!hasAssignUserPermission"> <section class="context" ng-show="!hasAssignUserPermission">
<div class="panel-body text-center"> <div class="panel-body text-center">
<h4>您没有权限操作,请找 [{{admins.join(',')}}] 开通权限</h4> <h4 translate="App.Setting.NoPermissonTips" translate-value-users="{{admins.join(',')}}"></h4>
</div> </div>
</section> </section>
</div> </div>
<apolloconfirmdialog apollo-dialog-id="'warning'" apollo-title="'删除管理员'" <apolloconfirmdialog apollo-dialog-id="'warning'" apollo-title="'App.Setting.DeleteAdmin' | translate"
apollo-detail="'不能删除所有的管理员'" apollo-detail="'App.Setting.CanNotDeleteAllAdmin' | translate" apollo-show-cancel-btn="false">
apollo-show-cancel-btn="false"></apolloconfirmdialog> </apolloconfirmdialog>
</section> </section>
</div> </div>
<div ng-include="'../views/common/footer.html'"></div> <div ng-include="'../views/common/footer.html'"></div>
<!-- jquery.js --> <!-- jquery.js -->
<script src="../vendor/jquery.min.js" type="text/javascript"></script> <script src="../vendor/jquery.min.js" type="text/javascript"></script>
<!--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-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>
<script src="../vendor/angular/angular-cookies.min.js"></script>
<!--valdr--> <script src="../vendor/angular/angular-translate.2.18.1/angular-translate.min.js"></script>
<script src="../vendor/valdr/valdr.min.js" type="text/javascript"></script> <script src="../vendor/angular/angular-translate.2.18.1/angular-translate-loader-static-files.min.js"></script>
<script src="../vendor/valdr/valdr-message.min.js" type="text/javascript"></script> <script src="../vendor/angular/angular-translate.2.18.1/angular-translate-storage-cookie.min.js"></script>
<!--valdr-->
<script src="../vendor/valdr/valdr.min.js" type="text/javascript"></script>
<script src="../vendor/valdr/valdr-message.min.js" type="text/javascript"></script>
<!-- bootstrap.js --> <!-- bootstrap.js -->
<script src="../vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script> <script src="../vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
<script src="../vendor/lodash.min.js"></script> <script src="../vendor/lodash.min.js"></script>
<script src="../vendor/select2/select2.min.js" type="text/javascript"></script> <script src="../vendor/select2/select2.min.js" type="text/javascript"></script>
<!--biz--> <!--biz-->
<!--must import--> <!--must import-->
<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/UserService.js"></script>
<script type="application/javascript" src="../scripts/services/CommonService.js"></script> <script type="application/javascript" src="../scripts/services/CommonService.js"></script>
<script type="application/javascript" src="../scripts/services/PermissionService.js"></script> <script type="application/javascript" src="../scripts/services/PermissionService.js"></script>
<script type="application/javascript" src="../scripts/services/OrganizationService.js"></script> <script type="application/javascript" src="../scripts/services/OrganizationService.js"></script>
<script type="application/javascript" src="../scripts/services/PermissionService.js"></script> <script type="application/javascript" src="../scripts/services/PermissionService.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/PageCommon.js"></script> <script type="application/javascript" src="../scripts/PageCommon.js"></script>
<script type="application/javascript" src="../scripts/directive/directive.js"></script> <script type="application/javascript" src="../scripts/directive/directive.js"></script>
<script type="application/javascript" src="../scripts/valdr.js"></script> <script type="application/javascript" src="../scripts/valdr.js"></script>
<script type="application/javascript" src="../scripts/controller/SettingController.js"></script> <script type="application/javascript" src="../scripts/controller/SettingController.js"></script>
</body> </body>
</html> </html>
\ No newline at end of file
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<link rel="stylesheet" type="text/css" href="vendor/select2/select2.min.css"> <link rel="stylesheet" type="text/css" href="vendor/select2/select2.min.css">
<link rel="stylesheet" type="text/css" media='all' href="vendor/angular/loading-bar.min.css"> <link rel="stylesheet" type="text/css" media='all' href="vendor/angular/loading-bar.min.css">
<link rel="stylesheet" type="text/css" href="styles/common-style.css"> <link rel="stylesheet" type="text/css" href="styles/common-style.css">
<title>新建集群</title> <title>{{'Cluster.CreateCluster' | translate }}</title>
</head> </head>
<body> <body>
...@@ -23,10 +23,10 @@ ...@@ -23,10 +23,10 @@
<header class="panel-heading"> <header class="panel-heading">
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<h4>创建集群</h4> <h4>{{'Cluster.CreateCluster' | translate }}</h4>
</div> </div>
<div class="col-md-6 text-right"> <div class="col-md-6 text-right">
<a type="button" class="btn btn-info" href="/config.html?#/appid={{appId}}">返回到项目首页 <a type="button" class="btn btn-info" href="/config.html?#/appid={{appId}}">{{'Common.ReturnToIndex' | translate }}
</a> </a>
</div> </div>
</div> </div>
...@@ -39,13 +39,10 @@ ...@@ -39,13 +39,10 @@
<div class="alert alert-info no-radius" role="alert"> <div class="alert alert-info no-radius" role="alert">
<strong>Tips:</strong> <strong>Tips:</strong>
<ul> <ul>
<li>通过添加集群,可以使同一份程序在不同的集群(如不同的数据中心)使用不同的配置</li> <li>{{'Cluster.Tips.1' | translate }}</li>
<li>如果不同集群使用一样的配置,则没有必要创建集群</li> <li>{{'Cluster.Tips.2' | translate }}</li>
<li> <li>{{'Cluster.Tips.3' | translate }}</li>
Apollo默认会读取机器上/opt/settings/server.properties(linux)或C:\opt\settings\server.properties(windows)文件中的idc属性作为集群名字, <li>{{'Cluster.Tips.4' | translate }}</li>
如SHAJQ(金桥数据中心)、SHAOY(欧阳数据中心)
</li>
<li>在这里创建的集群名字需要和机器上server.properties中的idc属性一致</li>
</ul> </ul>
</div> </div>
<form class="form-horizontal" name="clusterForm" valdr-type="Cluster" ng-show="step == 1" <form class="form-horizontal" name="clusterForm" valdr-type="Cluster" ng-show="step == 1"
...@@ -53,7 +50,7 @@ ...@@ -53,7 +50,7 @@
<div class="form-group"> <div class="form-group">
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
应用AppId</label> {{'Common.AppId' | translate }}</label>
<div class="col-sm-6"> <div class="col-sm-6">
<label class="form-control-static" ng-bind="appId"></label> <label class="form-control-static" ng-bind="appId"></label>
</div> </div>
...@@ -61,16 +58,16 @@ ...@@ -61,16 +58,16 @@
<div class="form-group" valdr-form-group> <div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
集群名称</label> {{'Common.ClusterName' | translate }}</label>
<div class="col-sm-6"> <div class="col-sm-6">
<input type="text" class="form-control" name="clusterName" ng-model="clusterName"> <input type="text" class="form-control" name="clusterName" ng-model="clusterName">
<small>(部署集群如:SHAJQ,SHAOY 或自定义集群如:SHAJQ-xx,SHAJQ-yy)</small> <small>{{'Cluster.CreaterNameTips' | translate }}</small>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
选择环境</label> {{'Cluster.ChooseEnvironment' | translate }}</label>
<div class="col-sm-5"> <div class="col-sm-5">
<table class="table table-hover" style="width: 100px"> <table class="table table-hover" style="width: 100px">
<tbody> <tbody>
...@@ -89,14 +86,14 @@ ...@@ -89,14 +86,14 @@
<div class="col-sm-offset-2 col-sm-10"> <div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary" <button type="submit" class="btn btn-primary"
ng-disabled="clusterForm.$invalid || submitBtnDisabled">提交 ng-disabled="clusterForm.$invalid || submitBtnDisabled">{{'Common.Submit' | translate }}
</button> </button>
</div> </div>
</div> </div>
</form> </form>
<div class="row text-center" ng-show="step == 2"> <div class="row text-center" ng-show="step == 2">
<img src="img/sync-succ.png" style="height: 100px; width: 100px"> <img src="img/sync-succ.png" style="height: 100px; width: 100px">
<h3>创建成功!</h3> <h3>{{'Common.Created' | translate }}!</h3>
</div> </div>
</div> </div>
</div> </div>
...@@ -111,6 +108,11 @@ ...@@ -111,6 +108,11 @@
<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>
<script src="vendor/angular/angular-cookies.min.js"></script>
<script src="vendor/angular/angular-translate.2.18.1/angular-translate.min.js"></script>
<script src="vendor/angular/angular-translate.2.18.1/angular-translate-loader-static-files.min.js"></script>
<script src="vendor/angular/angular-translate.2.18.1/angular-translate-storage-cookie.min.js"></script>
<!-- jquery.js --> <!-- jquery.js -->
<script src="vendor/jquery.min.js" type="text/javascript"></script> <script src="vendor/jquery.min.js" type="text/javascript"></script>
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Apollo配置中心</title> <title>{{'Config.Title' | translate }}</title>
<link rel="icon" href="./img/config.png"> <link rel="icon" href="./img/config.png">
<link rel="stylesheet" type="text/css" href="vendor/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" type="text/css" href="vendor/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="vendor/angular/angular-toastr-1.4.1.min.css"> <link rel="stylesheet" type="text/css" href="vendor/angular/angular-toastr-1.4.1.min.css">
...@@ -15,30 +15,30 @@ ...@@ -15,30 +15,30 @@
<body> <body>
<apollonav></apollonav> <apollonav></apollonav>
<div id="config-info" class="apollo-container app"> <div id="config-info" class="apollo-container app">
<div ng-controller="ConfigBaseInfoController"> <div ng-controller="ConfigBaseInfoController">
<div class="J_appNotFound hidden row text-center app-not-found" ng-show="notFoundApp"> <div class="J_appNotFound hidden row text-center app-not-found" ng-show="notFoundApp">
<img src="img/404.png"> <img src="img/404.png">
<br> <br>
<p> <p>
<span ng-bind="pageContext.appId"></span> 不存在,<a href="/app.html">点击创建</a> <span ng-bind="pageContext.appId"></span> {{'Config.AppIdNotFound' | translate }}<a
href="/app.html">{{'Config.ClickByCreate' | translate }}</a>
</p> </p>
</div> </div>
<div class="side-bar" <div class="side-bar" ng-class="{'position-absolute': viewMode == 1, 'position-fixed': viewMode == 2}">
ng-class="{'position-absolute': viewMode == 1, 'position-fixed': viewMode == 2}">
<div class="J_appFound hidden" <div class="J_appFound hidden"
ng-show="!notFoundApp && (viewMode == 1 || (viewMode == 2 && showSideBar))"> ng-show="!notFoundApp && (viewMode == 1 || (viewMode == 2 && showSideBar))">
<!--env list--> <!--env list-->
<section class="panel"> <section class="panel">
<header class="panel-heading"> <header class="panel-heading">
环境列表 {{'Config.EnvList' | translate }}
<span class="pull-right" <span class="pull-right" data-tooltip="tooltip" data-placement="bottom"
data-tooltip="tooltip" data-placement="bottom" title="通过切换环境、集群来管理不同环境、集群的配置"> title="{{'Config.EnvListTips' | translate }}">
<img src="img/question.png" class="i-20"/> <img src="img/question.png" class="i-20" />
</span> </span>
</header> </header>
<div id="treeview" class="no-radius"></div> <div id="treeview" class="no-radius"></div>
...@@ -48,60 +48,61 @@ ...@@ -48,60 +48,61 @@
<!--app info--> <!--app info-->
<section class="panel"> <section class="panel">
<header class="panel-heading"> <header class="panel-heading">
项目信息 {{'Config.ProjectInfo' | translate }}
<span class="pull-right"> <span class="pull-right">
<a href="/app/setting.html?#/appid={{pageContext.appId}}" <a href="/app/setting.html?#/appid={{pageContext.appId}}"
style="margin-right: 5px;text-decoration:none;"> style="margin-right: 5px;text-decoration:none;">
<img src="img/edit.png" class="i-20 cursor-pointer" <img src="img/edit.png" class="i-20 cursor-pointer" data-tooltip="tooltip"
data-tooltip="tooltip" data-placement="bottom" title="修改项目基本信息"/> data-placement="bottom"
title="{{'Config.ModifyBasicProjectInfo' | translate }}" />
</a> </a>
<img src="img/unlike.png" class="i-20 cursor-pointer" <img src="img/unlike.png" class="i-20 cursor-pointer" ng-if="!favoriteId"
ng-if="!favoriteId" ng-click="addFavorite()" ng-click="addFavorite()" data-tooltip="tooltip" data-placement="bottom"
data-tooltip="tooltip" data-placement="bottom" title="收藏"/> title="{{'Config.Favorite' | translate }}" />
<img src="img/like.png" class="i-20 cursor-pointer" <img src="img/like.png" class="i-20 cursor-pointer" ng-if="favoriteId"
ng-if="favoriteId" ng-click="deleteFavorite()" ng-click="deleteFavorite()" data-tooltip="tooltip" data-placement="bottom"
data-tooltip="tooltip" data-placement="bottom" title="取消收藏"/> title="{{'Config.CancelFavorite' | translate }}" />
</span> </span>
</header> </header>
<div class="panel-body"> <div class="panel-body">
<table class="project-info"> <table class="project-info">
<tbody class="text-left"> <tbody class="text-left">
<tr> <tr>
<th>AppId:</th> <th>{{'Common.Department' | translate }}:</th>
<td ng-bind="appBaseInfo.appId"></td> <td ng-bind="appBaseInfo.appId"></td>
</tr> </tr>
<tr> <tr>
<th>应用名:</th> <th>{{'Common.AppName' | translate }}:</th>
<td> <td>
<small ng-bind="appBaseInfo.name"></small> <small ng-bind="appBaseInfo.name"></small>
</td> </td>
</tr> </tr>
<tr> <tr>
<th>部门:</th> <th>{{'Common.Department' | translate }}:</th>
<td ng-bind="appBaseInfo.orgInfo"></td> <td ng-bind="appBaseInfo.orgInfo"></td>
</tr> </tr>
<tr> <tr>
<th>负责人:</th> <th>{{'Common.AppOwner' | translate }}:</th>
<td ng-bind="appBaseInfo.ownerName"></td> <td ng-bind="appBaseInfo.ownerName"></td>
</tr> </tr>
<tr> <tr>
<th>邮箱:</th> <th>{{'Common.Email' | translate }}:</th>
<td> <td>
<small ng-bind="appBaseInfo.ownerEmail"></small> <small ng-bind="appBaseInfo.ownerEmail"></small>
</td> </td>
</tr> </tr>
<tr ng-show="missEnvs.length > 0"> <tr ng-show="missEnvs.length > 0">
<th>缺失的环境:</th> <th>{{'Config.MissEnv' | translate }}:</th>
<td> <td>
<span ng-repeat="env in missEnvs" ng-bind="env"> <span ng-repeat="env in missEnvs" ng-bind="env">
</span> </span>
</td> </td>
</tr> </tr>
<tr ng-show="missingNamespaces.length > 0"> <tr ng-show="missingNamespaces.length > 0">
<th>缺失的Namespace:</th> <th>{{'Config.MissNamespace' | translate }}:</th>
<td> <td>
<span ng-repeat="namespace in missingNamespaces" ng-bind="namespace"> <span ng-repeat="namespace in missingNamespaces" ng-bind="namespace">
</span> </span>
...@@ -115,40 +116,42 @@ ...@@ -115,40 +116,42 @@
<!--operation entrance--> <!--operation entrance-->
<section> <section>
<apolloentrance apollo-title="'管理项目'" apollo-img-src="'project-manage'" <apolloentrance apollo-title="'Config.ProjectManage' | translate"
apollo-img-src="'project-manage'"
apollo-href="'/app/setting.html?#/appid=' + pageContext.appId"></apolloentrance> apollo-href="'/app/setting.html?#/appid=' + pageContext.appId"></apolloentrance>
<a class="list-group-item" ng-show="missEnvs.length > 0" ng-click="createAppInMissEnv()"> <a class="list-group-item" ng-show="missEnvs.length > 0" ng-click="createAppInMissEnv()">
<div class="row icon-text icon-plus-orange"> <div class="row icon-text icon-plus-orange">
<p class="btn-title ng-binding">补缺环境</p> <p class="btn-title ng-binding">{{'Config.CreateAppMissEnv' | translate }}</p>
</div> </div>
</a> </a>
<a class="list-group-item" ng-show="missingNamespaces.length > 0" ng-click="createMissingNamespaces()"> <a class="list-group-item" ng-show="missingNamespaces.length > 0"
ng-click="createMissingNamespaces()">
<div class="row icon-text icon-plus-orange"> <div class="row icon-text icon-plus-orange">
<p class="btn-title ng-binding">补缺Namespace</p> <p class="btn-title ng-binding">{{'Config.CreateAppMissNamespace' | translate }}</p>
</div> </div>
</a> </a>
<apolloentrance apollo-title="'添加集群'" apollo-img-src="'plus-orange'" <apolloentrance apollo-title="'Config.AddCluster' | translate" apollo-img-src="'plus-orange'"
apollo-href="'cluster.html?#/appid=' + pageContext.appId" apollo-href="'cluster.html?#/appid=' + pageContext.appId"
ng-show="hasCreateClusterPermission"></apolloentrance> ng-show="hasCreateClusterPermission"></apolloentrance>
<div class="list-group-item cursor-pointer hover" ng-click="showMasterPermissionTips()" <div class="list-group-item cursor-pointer hover" ng-click="showMasterPermissionTips()"
ng-show="!hasCreateClusterPermission"> ng-show="!hasCreateClusterPermission">
<div class="row icon-text icon-plus-orange"> <div class="row icon-text icon-plus-orange">
<p class="btn-title">添加集群</p> <p class="btn-title">{{'Config.AddCluster' | translate }}</p>
</div> </div>
</div> </div>
<apolloentrance apollo-title="'添加Namespace'" apollo-img-src="'plus-orange'" <apolloentrance apollo-title="'Config.AddNamespace' | translate" apollo-img-src="'plus-orange'"
apollo-href="'namespace.html?#/appid=' + pageContext.appId" apollo-href="'namespace.html?#/appid=' + pageContext.appId"
ng-show="hasCreateNamespacePermission"></apolloentrance> ng-show="hasCreateNamespacePermission"></apolloentrance>
<div class="list-group-item cursor-pointer hover" ng-click="showMasterPermissionTips()" <div class="list-group-item cursor-pointer hover" ng-click="showMasterPermissionTips()"
ng-show="!hasCreateNamespacePermission"> ng-show="!hasCreateNamespacePermission">
<div class="row icon-text icon-plus-orange"> <div class="row icon-text icon-plus-orange">
<p class="btn-title">添加Namespace</p> <p class="btn-title">{{'Config.AddNamespace' | translate }}</p>
</div> </div>
</div> </div>
...@@ -161,171 +164,154 @@ ...@@ -161,171 +164,154 @@
<!--具体配置信息--> <!--具体配置信息-->
<!--namespaces--> <!--namespaces-->
<div class="config-item-container hide" <div class="config-item-container hide" ng-class="{'view-mode-1': viewMode == 1, 'view-mode-2': viewMode == 2}"
ng-class="{'view-mode-1': viewMode == 1, 'view-mode-2': viewMode == 2}"
ng-controller="ConfigNamespaceController"> ng-controller="ConfigNamespaceController">
<h4 class="text-center" ng-show="viewMode == 2"> <h4 class="text-center" ng-show="viewMode == 2">
当前操作环境:{{pageContext.env}}, 集群:{{pageContext.clusterName}} {{'Config.CurrentlyOperatorEnv' | translate }}:{{pageContext.env}},
{{'Common.Cluster' | translate }}:{{pageContext.clusterName}}
</h4> </h4>
<div class="alert alert-info alert-dismissible" role="alert" <div class="alert alert-info alert-dismissible" role="alert"
ng-show="(!hideTip || !hideTip[pageContext.appId][pageContext.clusterName]) && envMapClusters[pageContext.env]"> ng-show="(!hideTip || !hideTip[pageContext.appId][pageContext.clusterName]) && envMapClusters[pageContext.env]">
<button class="btn btn-sm btn-default pull-right" style="margin-top: -7px;margin-right:-15px;" <button class="btn btn-sm btn-default pull-right" style="margin-top: -7px;margin-right:-15px;"
ng-click="closeTip(pageContext.clusterName)">不再提示 ng-click="closeTip(pageContext.clusterName)">{{'Config.DoNotRemindAgain' | translate }}
</button> </button>
<!--default cluster tip --> <!--default cluster tip -->
<div ng-show="pageContext.clusterName == 'default'"> <div ng-show="pageContext.clusterName == 'default'">
<strong>注意: </strong>所有不属于 <strong>{{'Config.Note' | translate }}:</strong>
<span ng-bind="envMapClusters[pageContext.env]"></span> <span translate="Config.ClusterIsDefualtTipContent"
集群的实例会使用default集群(当前页面)的配置,属于 translate-value-name="{{envMapClusters[pageContext.env]}}"></span>
<span ng-bind="envMapClusters[pageContext.env]"></span>
的实例会使用对应集群的配置!
</div> </div>
<!--custom cluster tip--> <!--custom cluster tip-->
<div ng-show="pageContext.clusterName != 'default'"> <div ng-show="pageContext.clusterName != 'default'">
<strong>注意:</strong>属于 <strong>{{'Config.Note' | translate }}:</strong>
<span ng-bind="pageContext.clusterName"></span> <span translate="Config.ClusterIsCustomTipContent"
集群的实例只会使用 translate-value-name="{{pageContext.clusterName}}"></span>
<span ng-bind="pageContext.clusterName"></span>
集群(当前页面)的配置,只有当对应namespace在当前集群没有发布过配置时,才会使用default集群的配置。
</div> </div>
</div> </div>
<div class="alert alert-info" <div class="alert alert-info" ng-if="hasNotPublishNamespace">
ng-if="hasNotPublishNamespace"> <p><b>{{'Config.Note' | translate }}:</b> {{'Config.HasNotPublishNamespace' | translate }}</p>
<p><b>注意:</b> 以下环境/集群有未发布的配置,客户端获取不到未发布的配置,请及时发布。</p>
<p> <p>
<mark ng-bind="namespacePublishInfo.join(',')"></mark> <mark ng-bind="namespacePublishInfo.join(',')"></mark>
</p> </p>
</div> </div>
<apollonspanel ng-repeat="namespace in namespaces" <apollonspanel ng-repeat="namespace in namespaces" namespace="namespace" app-id="pageContext.appId"
namespace="namespace" env="pageContext.env" lock-check="lockCheck" cluster="pageContext.clusterName" user="currentUser"
app-id="pageContext.appId" pre-release-ns="prepareReleaseNamespace" create-item="createItem" edit-item="editItem"
env="pageContext.env" pre-delete-item="preDeleteItem" show-text="showText"
lock-check="lockCheck" show-no-modify-permission-dialog="showNoModifyPermissionDialog" show-body="namespaces.length < 3"
cluster="pageContext.clusterName" lazy-load="namespaces.length > 10" pre-create-branch="preCreateBranch"
user="currentUser"
pre-release-ns="prepareReleaseNamespace"
create-item="createItem" edit-item="editItem"
pre-delete-item="preDeleteItem"
show-text="showText"
show-no-modify-permission-dialog="showNoModifyPermissionDialog"
show-body="namespaces.length < 3"
lazy-load="namespaces.length > 10"
pre-create-branch="preCreateBranch"
pre-delete-branch="preDeleteBranch"> pre-delete-branch="preDeleteBranch">
</apollonspanel> </apollonspanel>
<releasemodal app-id="pageContext.appId" <releasemodal app-id="pageContext.appId" env="pageContext.env" cluster="pageContext.clusterName">
env="pageContext.env"
cluster="pageContext.clusterName">
</releasemodal> </releasemodal>
<itemmodal to-operation-namespace="toOperationNamespace" <itemmodal to-operation-namespace="toOperationNamespace" app-id="pageContext.appId" env="pageContext.env"
app-id="pageContext.appId" cluster="pageContext.clusterName" item="item">
env="pageContext.env"
cluster="pageContext.clusterName"
item="item">
</itemmodal> </itemmodal>
<showtextmodal text="text"></showtextmodal> <showtextmodal text="text"></showtextmodal>
<rollbackmodal app-id="pageContext.appId" <rollbackmodal app-id="pageContext.appId" env="pageContext.env" cluster="pageContext.clusterName">
env="pageContext.env"
cluster="pageContext.clusterName">
</rollbackmodal> </rollbackmodal>
<rulesmodal app-id="pageContext.appId" <rulesmodal app-id="pageContext.appId" env="pageContext.env" cluster="pageContext.clusterName">
env="pageContext.env"
cluster="pageContext.clusterName">
</rulesmodal> </rulesmodal>
<mergeandpublishmodal app-id="pageContext.appId" <mergeandpublishmodal app-id="pageContext.appId" env="pageContext.env" cluster="pageContext.clusterName">
env="pageContext.env"
cluster="pageContext.clusterName">
</mergeandpublishmodal> </mergeandpublishmodal>
<publishdenymodal env="pageContext.env"></publishdenymodal> <publishdenymodal env="pageContext.env"></publishdenymodal>
<deletenamespacemodal env="pageContext.env"></deletenamespacemodal> <deletenamespacemodal env="pageContext.env"></deletenamespacemodal>
<apolloconfirmdialog apollo-dialog-id="'deleteConfirmDialog'" apollo-title="'删除配置'" <apolloconfirmdialog apollo-dialog-id="'deleteConfirmDialog'"
apollo-detail="'您正在删除 Key 为 <b>' + config.key + '</b> Value 为 <b>' + config.value + '</b> 的配置.<br>确定要删除配置吗?'" apollo-title="'Config.DeleteItem.DialogTitle' | translate"
apollo-show-cancel-btn="true" apollo-confirm="deleteItem"></apolloconfirmdialog> apollo-detail="'Config.DeleteItem.DialogContent' | translate:this" apollo-show-cancel-btn="true"
apollo-confirm="deleteItem"></apolloconfirmdialog>
<apolloconfirmdialog apollo-dialog-id="'releaseNoPermissionDialog'" apollo-title="'发布'" <apolloconfirmdialog apollo-dialog-id="'releaseNoPermissionDialog'"
apollo-detail="'您没有发布权限哦~ 请找项目管理员 ' + masterUsers + ' 分配发布权限'" apollo-title="'Config.PublishNoPermission.DialogTitle' | translate"
apollo-show-cancel-btn="false"></apolloconfirmdialog> apollo-detail="'Config.PublishNoPermission.DialogContent' | translate:this"
apollo-show-cancel-btn="false">
</apolloconfirmdialog>
<apolloconfirmdialog apollo-dialog-id="'modifyNoPermissionDialog'" apollo-title="'申请配置权限'" <apolloconfirmdialog apollo-dialog-id="'modifyNoPermissionDialog'"
apollo-detail="'请找项目管理员 ' + masterUsers + ' 分配编辑或发布权限'" apollo-title="'Config.ModifyNoPermission.DialogTitle' | translate"
apollo-show-cancel-btn="false"></apolloconfirmdialog> apollo-detail="'Config.ModifyNoPermission.DialogContent' | translate:this"
apollo-show-cancel-btn="false">
</apolloconfirmdialog>
<apolloconfirmdialog apollo-dialog-id="'masterNoPermissionDialog'" apollo-title="'申请配置权限'" <apolloconfirmdialog apollo-dialog-id="'masterNoPermissionDialog'"
apollo-detail="'您不是项目管理员, 只有项目管理员才有添加集群、namespace的权限。 apollo-title="'Config.MasterNoPermission.DialogTitle' | translate"
如需管理员权限,请找项目管理员 ' + masterUsers + ' 分配管理员权限'" apollo-detail="'Config.MasterNoPermission.DialogContent' | translate:this"
apollo-show-cancel-btn="false"></apolloconfirmdialog> apollo-show-cancel-btn="false">
</apolloconfirmdialog>
<apolloconfirmdialog apollo-dialog-id="'namespaceLockedDialog'" apollo-title="'编辑受限'" <apolloconfirmdialog apollo-dialog-id="'namespaceLockedDialog'"
apollo-detail="'当前namespace正在被 ' + lockOwner + ' 编辑,一次发布只能被一个人修改.'" apollo-title="'Config.NamespaceLocked.DialogTitle' | translate"
apollo-show-cancel-btn="false"></apolloconfirmdialog> apollo-detail="'Config.NamespaceLocked.DialogContent' | translate:this" apollo-show-cancel-btn="false">
</apolloconfirmdialog>
<apolloconfirmdialog apollo-dialog-id="'rollbackAlertDialog'" apollo-title="'回滚'" <apolloconfirmdialog apollo-dialog-id="'rollbackAlertDialog'"
apollo-detail="'确定要回滚吗?'" apollo-title="'Config.RollbackAlert.DialogTitle' | translate"
apollo-show-cancel-btn="true" apollo-confirm="rollback"></apolloconfirmdialog> apollo-detail="'Config.RollbackAlert.DialogContent' | translate" apollo-show-cancel-btn="true"
apollo-confirm="rollback"></apolloconfirmdialog>
<apolloconfirmdialog apollo-dialog-id="'emergencyPublishAlertDialog'" apollo-title="'紧急发布'" <apolloconfirmdialog apollo-dialog-id="'emergencyPublishAlertDialog'"
apollo-detail="'确定要紧急发布吗?'" apollo-title="'Config.EmergencyPublishAlert.DialogTitle' | translate"
apollo-show-cancel-btn="true" apollo-confirm="emergencyPublish"></apolloconfirmdialog> apollo-detail="'Config.EmergencyPublishAlert.DialogContent' | translate" apollo-show-cancel-btn="true"
apollo-confirm="emergencyPublish">
</apolloconfirmdialog>
<apolloconfirmdialog apollo-dialog-id="'deleteBranchDialog'" apollo-title="'删除灰度'" <apolloconfirmdialog apollo-dialog-id="'deleteBranchDialog'"
apollo-detail="'删除灰度会丢失灰度的配置,确定要删除吗?'" apollo-title="'Config.DeleteBranch.DialogTitle' | translate"
apollo-show-cancel-btn="true" apollo-confirm="deleteBranch"></apolloconfirmdialog> apollo-detail="'Config.DeleteBranch.DialogContent' | translate" apollo-show-cancel-btn="true"
apollo-confirm="deleteBranch">
</apolloconfirmdialog>
<apolloconfirmdialog apollo-dialog-id="'updateRuleTips'" apollo-title="'更新灰度规则提示'" <apolloconfirmdialog apollo-dialog-id="'updateRuleTips'"
apollo-detail="'灰度规则已生效,但发现灰度版本有未发布的配置,这些配置需要手动灰度发布才会生效'"></apolloconfirmdialog> apollo-title="'Config.UpdateRuleTips.DialogTitle' | translate"
apollo-detail="'Config.UpdateRuleTips.DialogContent' | translate"></apolloconfirmdialog>
<apolloconfirmdialog apollo-dialog-id="'mergeAndReleaseDenyDialog'" apollo-title="'全量发布'" <apolloconfirmdialog apollo-dialog-id="'mergeAndReleaseDenyDialog'"
apollo-detail="'namespace主版本有未发布的配置,请先发布主版本配置'"></apolloconfirmdialog> apollo-title="'Config.MergeAndReleaseDeny.DialogTitle' | translate"
apollo-detail="'Config.MergeAndReleaseDeny.DialogContent' | translate"></apolloconfirmdialog>
<apolloconfirmdialog apollo-dialog-id="'grayReleaseWithoutRulesTips'" apollo-title="'缺失灰度规则提示'" <apolloconfirmdialog apollo-dialog-id="'grayReleaseWithoutRulesTips'"
apollo-detail="'灰度版本还没有配置任何灰度规则,请配置灰度规则'"> apollo-title="'Config.GrayReleaseWithoutRulesTips.DialogTitle' | translate"
apollo-detail="'Config.GrayReleaseWithoutRulesTips.DialogContent' | translate">
</apolloconfirmdialog> </apolloconfirmdialog>
<apolloconfirmdialog apollo-dialog-id="'deleteNamespaceDenyForMasterInstanceDialog'" <apolloconfirmdialog apollo-dialog-id="'deleteNamespaceDenyForMasterInstanceDialog'"
apollo-title="'删除Namespace警告信息'" apollo-title="'Config.DeleteNamespaceDenyForMasterInstance.DialogTitle' | translate"
apollo-detail="'发现有 <b>' + deleteNamespaceContext.namespace.instancesCount + apollo-detail="'Config.DeleteNamespaceDenyForMasterInstance.DialogContent' | translate:this"
'</b> 个实例正在使用Namespace(' + deleteNamespaceContext.namespace.baseInfo.namespaceName +
'),删除Namespace将导致实例获取不到配置。<br>
请到 <ins>“实例列表”</ins> 确认实例信息,如确认相关实例都已经不再使用该Namespace配置,可以联系Apollo相关负责人删除实例信息(InstanceConfig)或等待实例24小时自动过期后再来删除。'"
apollo-confirm="continueDeleteNamespace"> apollo-confirm="continueDeleteNamespace">
</apolloconfirmdialog> </apolloconfirmdialog>
<apolloconfirmdialog apollo-dialog-id="'deleteNamespaceDenyForBranchInstanceDialog'" <apolloconfirmdialog apollo-dialog-id="'deleteNamespaceDenyForBranchInstanceDialog'"
apollo-title="'删除Namespace警告信息'" apollo-title="'Config.DeleteNamespaceDenyForBranchInstance.DialogTitle' | translate"
apollo-detail="'发现有 <b>' + deleteNamespaceContext.namespace.branch.latestReleaseInstances.total apollo-detail="'Config.DeleteNamespaceDenyForBranchInstance.DialogContent' | translate:this"
+ '</b> 个实例正在使用Namespace(' + deleteNamespaceContext.namespace.baseInfo.namespaceName +
')灰度版本的配置,删除Namespace将导致实例获取不到配置。<br>
请到 <ins>“灰度版本” => “实例列表”</ins> 确认实例信息,如确认相关实例都已经不再使用该Namespace配置,可以联系Apollo相关负责人删除实例信息(InstanceConfig)或等待实例24小时自动过期后再来删除。'"
apollo-confirm="continueDeleteNamespace"> apollo-confirm="continueDeleteNamespace">
</apolloconfirmdialog> </apolloconfirmdialog>
<apolloconfirmdialog apollo-dialog-id="'deleteNamespaceDenyForPublicNamespaceDialog'" <apolloconfirmdialog apollo-dialog-id="'deleteNamespaceDenyForPublicNamespaceDialog'"
apollo-title="'删除Namespace失败提示'" apollo-title="'Config.DeleteNamespaceDenyForPublicNamespace.DialogTitle' | translate"
apollo-detail="deleteNamespaceContext.detailReason"> apollo-detail="deleteNamespaceContext.detailReason">
</apolloconfirmdialog> </apolloconfirmdialog>
<apolloconfirmdialog apollo-dialog-id="'syntaxCheckFailedDialog'" <apolloconfirmdialog apollo-dialog-id="'syntaxCheckFailedDialog'"
apollo-title="'语法检查错误'" apollo-title="'Config.SyntaxCheckFailed.DialogTitle' | translate"
apollo-detail="syntaxCheckContext.syntaxCheckMessage" apollo-detail="syntaxCheckContext.syntaxCheckMessage" apollo-extra-class="'pre'">
apollo-extra-class="'pre'">
</apolloconfirmdialog> </apolloconfirmdialog>
...@@ -335,117 +321,111 @@ ...@@ -335,117 +321,111 @@
<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">创建灰度须知</h4> <h4 class="modal-title">{{'Config.CreateBranchTips.DialogTitle' | translate}}</h4>
</div> </div>
<div class="modal-body"> <div class="modal-body" ng-bind-html="'Config.CreateBranchTips.DialogContent' | translate">
通过创建灰度版本,您可以对某些配置做灰度测试<br>
灰度流程为:<br>
&nbsp;&nbsp;1.创建灰度版本 <br>
&nbsp;&nbsp;2.配置灰度配置项<br>
&nbsp;&nbsp;3.配置灰度规则.如果是私有的namespace可以按照客户端的IP进行灰度,如果是公共的namespace则可以同时按AppId和客户端的IP进行灰度<br>
&nbsp;&nbsp;4.灰度发布<br>
灰度版本最终有两种结果:<b>全量发布和放弃灰度</b><br>
<b>全量发布</b>:灰度的配置合到主版本并发布,所有的客户端都会使用合并后的配置<br>
<b>放弃灰度</b>:删除灰度版本,所有的客户端都会使用回主版本的配置<br>
注意事项:<br>
&nbsp;&nbsp;1.如果灰度版本已经有灰度发布过,那么修改灰度规则后,无需再次灰度发布就立即生效<br>
</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">{{'Common.Cancel' | translate}}</button>
<button type="button" class="btn btn-primary" data-dismiss="modal" <button type="button" class="btn btn-primary" data-dismiss="modal"
ng-click="createBranch()"> ng-click="createBranch()">{{'Common.Ok' | translate}}</button>
确定 </div>
</button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>
<div ng-include="'views/common/footer.html'"></div> <div ng-include="'views/common/footer.html'"></div>
<!-- jquery.js --> <!-- jquery.js -->
<script src="vendor/jquery.min.js" type="text/javascript"></script> <script src="vendor/jquery.min.js" type="text/javascript"></script>
<script src="vendor/select2/select2.min.js" type="text/javascript"></script> <script src="vendor/select2/select2.min.js" type="text/javascript"></script>
<script src="vendor/jquery-plugin/jquery.textareafullscreen.js" type="text/javascript"></script> <script src="vendor/jquery-plugin/jquery.textareafullscreen.js" type="text/javascript"></script>
<!--lodash.js--> <!--lodash.js-->
<script src="vendor/lodash.min.js" type="text/javascript"></script> <script src="vendor/lodash.min.js" type="text/javascript"></script>
<!--angular--> <!--angular-->
<script src="vendor/angular/angular.min.js"></script> <script src="vendor/angular/angular.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>
<script src="vendor/angular/angular-cookies.min.js"></script>
<script src="vendor/angular/angular-sanitize.min.js"></script>
<!-- bootstrap.js --> <script src="vendor/angular/angular-translate.2.18.1/angular-translate.min.js"></script>
<script src="vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script> <script src="vendor/angular/angular-translate.2.18.1/angular-translate-loader-static-files.min.js"></script>
<script src="vendor/bootstrap/js/bootstrap-treeview.min.js" type="text/javascript"></script> <script src="vendor/angular/angular-translate.2.18.1/angular-translate-storage-cookie.min.js"></script>
<!-- bootstrap.js -->
<script src="vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
<script src="vendor/bootstrap/js/bootstrap-treeview.min.js" type="text/javascript"></script>
<script src="vendor/diff.min.js" type="text/javascript"></script> <script src="vendor/diff.min.js" type="text/javascript"></script>
<script src="vendor/clipboard.min.js" type="text/javascript"></script> <script src="vendor/clipboard.min.js" type="text/javascript"></script>
<script src="vendor/ui-ace/ace.js" type="text/javascript"></script> <script src="vendor/ui-ace/ace.js" type="text/javascript"></script>
<script src="vendor/ui-ace/ui-ace.min.js" type="text/javascript"></script> <script src="vendor/ui-ace/ui-ace.min.js" type="text/javascript"></script>
<script src="vendor/ui-ace/mode-properties.js" type="text/javascript"></script> <script src="vendor/ui-ace/mode-properties.js" type="text/javascript"></script>
<script src="vendor/ui-ace/mode-xml.js" type="text/javascript"></script> <script src="vendor/ui-ace/mode-xml.js" type="text/javascript"></script>
<script src="vendor/ui-ace/mode-yaml.js" type="text/javascript"></script> <script src="vendor/ui-ace/mode-yaml.js" type="text/javascript"></script>
<script src="vendor/ui-ace/mode-json.js" type="text/javascript"></script> <script src="vendor/ui-ace/mode-json.js" type="text/javascript"></script>
<script src="vendor/ui-ace/worker-json.js" type="text/javascript"></script> <script src="vendor/ui-ace/worker-json.js" type="text/javascript"></script>
<script src="vendor/ui-ace/worker-xml.js" type="text/javascript"></script> <script src="vendor/ui-ace/worker-xml.js" type="text/javascript"></script>
<!--valdr--> <!--valdr-->
<script src="vendor/valdr/valdr.min.js" type="text/javascript"></script> <script src="vendor/valdr/valdr.min.js" type="text/javascript"></script>
<script src="vendor/valdr/valdr-message.min.js" type="text/javascript"></script> <script src="vendor/valdr/valdr-message.min.js" type="text/javascript"></script>
<!--biz script--> <!--biz script-->
<script type="application/javascript" src="scripts/app.js"></script> <script type="application/javascript" src="scripts/app.js"></script>
<!--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/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/UserService.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/services/ReleaseService.js"></script> <script type="application/javascript" src="scripts/services/ReleaseService.js"></script>
<script type="application/javascript" src="scripts/services/PermissionService.js"></script> <script type="application/javascript" src="scripts/services/PermissionService.js"></script>
<script type="application/javascript" src="scripts/services/NamespaceService.js"></script> <script type="application/javascript" src="scripts/services/NamespaceService.js"></script>
<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/CommonService.js"></script> <script type="application/javascript" src="scripts/services/CommonService.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/services/FavoriteService.js"></script>
<script type="application/javascript" src="scripts/services/NamespaceBranchService.js"></script> <script type="application/javascript" src="scripts/services/NamespaceBranchService.js"></script>
<script type="application/javascript" src="scripts/services/EventManager.js"></script> <script type="application/javascript" src="scripts/services/EventManager.js"></script>
<script type="application/javascript" src="scripts/AppUtils.js"></script> <script type="application/javascript" src="scripts/AppUtils.js"></script>
<!--directive--> <!--directive-->
<script type="application/javascript" src="scripts/directive/directive.js"></script> <script type="application/javascript" src="scripts/directive/directive.js"></script>
<script type="application/javascript" src="scripts/directive/namespace-panel-directive.js"></script> <script type="application/javascript" src="scripts/directive/namespace-panel-directive.js"></script>
<script type="application/javascript" src="scripts/directive/diff-directive.js"></script> <script type="application/javascript" src="scripts/directive/diff-directive.js"></script>
<script type="application/javascript" src="scripts/directive/release-modal-directive.js"></script> <script type="application/javascript" src="scripts/directive/release-modal-directive.js"></script>
<script type="application/javascript" src="scripts/directive/item-modal-directive.js"></script> <script type="application/javascript" src="scripts/directive/item-modal-directive.js"></script>
<script type="application/javascript" src="scripts/directive/show-text-modal-directive.js"></script> <script type="application/javascript" src="scripts/directive/show-text-modal-directive.js"></script>
<script type="application/javascript" src="scripts/directive/rollback-modal-directive.js"></script> <script type="application/javascript" src="scripts/directive/rollback-modal-directive.js"></script>
<script type="application/javascript" src="scripts/directive/gray-release-rules-modal-directive.js"></script> <script type="application/javascript" src="scripts/directive/gray-release-rules-modal-directive.js"></script>
<script type="application/javascript" src="scripts/directive/merge-and-publish-modal-directive.js"></script> <script type="application/javascript" src="scripts/directive/merge-and-publish-modal-directive.js"></script>
<script type="application/javascript" src="scripts/directive/publish-deny-modal-directive.js"></script> <script type="application/javascript" src="scripts/directive/publish-deny-modal-directive.js"></script>
<script type="application/javascript" src="scripts/directive/delete-namespace-modal-directive.js"></script> <script type="application/javascript" src="scripts/directive/delete-namespace-modal-directive.js"></script>
<!--controller--> <!--controller-->
<script type="application/javascript" src="scripts/controller/config/ConfigNamespaceController.js"></script> <script type="application/javascript" src="scripts/controller/config/ConfigNamespaceController.js"></script>
<script type="application/javascript" src="scripts/controller/config/ConfigBaseInfoController.js"></script> <script type="application/javascript" src="scripts/controller/config/ConfigBaseInfoController.js"></script>
<script type="application/javascript" src="scripts/PageCommon.js"></script> <script type="application/javascript" src="scripts/PageCommon.js"></script>
<script src="scripts/valdr.js" type="text/javascript"></script> <script src="scripts/valdr.js" type="text/javascript"></script>
</body> </body>
</html> </html>
\ No newline at end of file
<!doctype html> <!doctype html>
<html ng-app="diff_item"> <html ng-app="diff_item">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="icon" href="../img/config.png"> <link rel="icon" href="../img/config.png">
...@@ -9,11 +10,12 @@ ...@@ -9,11 +10,12 @@
<link rel="stylesheet" type="text/css" media='all' href="../vendor/angular/loading-bar.min.css"> <link rel="stylesheet" type="text/css" media='all' href="../vendor/angular/loading-bar.min.css">
<link rel="stylesheet" type="text/css" href="../styles/common-style.css"> <link rel="stylesheet" type="text/css" href="../styles/common-style.css">
<link rel="stylesheet" type="text/css" href="../vendor/select2/select2.min.css"> <link rel="stylesheet" type="text/css" href="../vendor/select2/select2.min.css">
<title>比较配置</title> <title>{{'Config.Diff.Title' | translate }}</title>
<style> <style>
.comment-toggle { .comment-toggle {
margin-left: 8px !important; margin-left: 8px !important;
} }
.diff-content { .diff-content {
margin-top: 12px; margin-top: 12px;
} }
...@@ -22,27 +24,27 @@ ...@@ -22,27 +24,27 @@
<body> <body>
<apollonav></apollonav> <apollonav></apollonav>
<div class="container-fluid apollo-container" ng-controller="DiffItemController"> <div class="container-fluid apollo-container" ng-controller="DiffItemController">
<section class="panel col-md-offset-1 col-md-10"> <section class="panel col-md-offset-1 col-md-10">
<header class="panel-heading"> <header class="panel-heading">
<div class="row"> <div class="row">
<div class="col-md-7"> <div class="col-md-7">
<h4 class="modal-title">比较配置 <h4 class="modal-title">{{'Config.Diff.Title' | translate }}
<small ng-show="syncItemStep == 1">(第一步:选择比较信息)</small> <small ng-show="syncItemStep == 1">{{'Config.Diff.FirstStep' | translate }}</small>
<small ng-show="syncItemStep == 2">(第二步:查看差异配置)</small> <small ng-show="syncItemStep == 2">{{'Config.Diff.SecondStep' | translate }}</small>
</h4> </h4>
</div> </div>
<div class="col-md-5 text-right"> <div class="col-md-5 text-right">
<button type="button" class="btn btn-primary" ng-show="syncItemStep > 1 && syncItemStep < 3" <button type="button" class="btn btn-primary" ng-show="syncItemStep > 1 && syncItemStep < 3"
ng-click="syncItemNextStep(-1)">上一步 ng-click="syncItemNextStep(-1)">{{'Config.Diff.PreviousStep' | translate }}
</button> </button>
<button type="button" class="btn btn-primary" ng-show="syncItemStep < 2" <button type="button" class="btn btn-primary" ng-show="syncItemStep < 2"
ng-click="diff()">下一步 ng-click="diff()">{{'Config.Diff.NextStep' | translate }}
</button> </button>
<button type="button" class="btn btn-info" data-dismiss="modal" <button type="button" class="btn btn-info" data-dismiss="modal"
ng-click="backToAppHomePage()">返回到项目首页 ng-click="backToAppHomePage()">{{'Common.ReturnToIndex' | translate }}
</button> </button>
</div> </div>
</div> </div>
...@@ -50,17 +52,17 @@ ...@@ -50,17 +52,17 @@
<div class="panel-body"> <div class="panel-body">
<div class="row" ng-show="syncItemStep == 1"> <div class="row" ng-show="syncItemStep == 1">
<div class="alert-info alert no-radius"> <div class="alert-info alert no-radius">
<strong>Tips:</strong> <strong>{{'Config.Diff.TipsTitle' | translate }}:</strong>
<ul> <ul>
<li>通过比较配置功能,可以查看多个环境、集群间的配置差异</li> <li>{{'Config.Diff.Tips' | translate }}</li>
</ul> </ul>
</div> </div>
<div class="form-horizontal"> <div class="form-horizontal">
<div class="form-group"> <div class="form-group">
<label class="col-sm-2 control-label">要比较的集群</label> <label class="col-sm-2 control-label">{{'Config.Diff.DiffCluster' | translate }}</label>
<div class="col-sm-6"> <div class="col-sm-6">
<apolloclusterselector apollo-app-id="pageContext.appId" apollo-default-all-checked="false" <apolloclusterselector apollo-app-id="pageContext.appId"
apollo-select="collectSelectedClusters" apollo-default-all-checked="false" apollo-select="collectSelectedClusters"
apollo-default-checked-env="pageContext.env" apollo-default-checked-env="pageContext.env"
apollo-default-checked-cluster="pageContext.clusterName"></apolloclusterselector> apollo-default-checked-cluster="pageContext.clusterName"></apolloclusterselector>
</div> </div>
...@@ -75,11 +77,9 @@ ...@@ -75,11 +77,9 @@
<div class="form-horizontal"> <div class="form-horizontal">
<div class="col-sm-12"> <div class="col-sm-12">
<label class="control-label"> <label class="control-label">
<input type="checkbox" <input type="checkbox" class="comment-toggle" ng-checked="showCommentDiff"
class="comment-toggle"
ng-checked="showCommentDiff"
ng-click="showCommentDiff=!showCommentDiff"> ng-click="showCommentDiff=!showCommentDiff">
是否比较注释 {{'Config.Diff.HasDiffComment' | translate }}
</label> </label>
</div> </div>
<div class="col-sm-12 diff-content"> <div class="col-sm-12 diff-content">
...@@ -88,22 +88,24 @@ ...@@ -88,22 +88,24 @@
<tr> <tr>
<td>Key</td> <td>Key</td>
<td ng-repeat="cluster in syncData.syncToNamespaces" <td ng-repeat="cluster in syncData.syncToNamespaces"
ng-bind="cluster.env + ':' + cluster.clusterName + ':' + cluster.namespaceName + ':Value'" ng-bind="cluster.env + ':' + cluster.clusterName + ':' + cluster.namespaceName + ':Value'">
></td> </td>
<td ng-show="showCommentDiff" <td ng-show="showCommentDiff"
ng-repeat="cluster in syncData.syncToNamespaces" ng-repeat="cluster in syncData.syncToNamespaces"
ng-bind="cluster.env + ':' + cluster.clusterName + ':' + cluster.namespaceName + ':Comment'" ng-bind="cluster.env + ':' + cluster.clusterName + ':' + cluster.namespaceName + ':Comment'">
></td> </td>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr ng-repeat="(key, itemsKeyedByCluster) in itemsKeyedByKey"> <tr ng-repeat="(key, itemsKeyedByCluster) in itemsKeyedByKey">
<td width="15%" ng-bind="key"></td> <td width="15%" ng-bind="key"></td>
<td ng-repeat="cluster in syncData.syncToNamespaces" <td ng-repeat="cluster in syncData.syncToNamespaces"
ng-bind="(itemsKeyedByCluster[cluster.env + ':' + cluster.clusterName + ':' + cluster.namespaceName] || {}).value"></td> ng-bind="(itemsKeyedByCluster[cluster.env + ':' + cluster.clusterName + ':' + cluster.namespaceName] || {}).value">
</td>
<td ng-show="showCommentDiff" <td ng-show="showCommentDiff"
ng-repeat="cluster in syncData.syncToNamespaces" ng-repeat="cluster in syncData.syncToNamespaces"
ng-bind="(itemsKeyedByCluster[cluster.env + ':' + cluster.clusterName + ':' + cluster.namespaceName] || {}).comment"></td> ng-bind="(itemsKeyedByCluster[cluster.env + ':' + cluster.clusterName + ':' + cluster.namespaceName] || {}).comment">
</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
...@@ -114,42 +116,47 @@ ...@@ -114,42 +116,47 @@
</div> </div>
</section> </section>
<showtextmodal text="text"/> <showtextmodal text="text" />
</div> </div>
<div ng-include="'../views/common/footer.html'"></div> <div ng-include="'../views/common/footer.html'"></div>
<!-- jquery.js --> <!-- jquery.js -->
<script src="../vendor/jquery.min.js" type="text/javascript"></script> <script src="../vendor/jquery.min.js" type="text/javascript"></script>
<script src="../vendor/select2/select2.min.js" type="text/javascript"></script> <script src="../vendor/select2/select2.min.js" type="text/javascript"></script>
<!--angular--> <!--angular-->
<script src="../vendor/angular/angular.min.js"></script> <script src="../vendor/angular/angular.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>
<script src="../vendor/angular/angular-cookies.min.js"></script>
<script src="../vendor/angular/angular-translate.2.18.1/angular-translate.min.js"></script>
<script src="../vendor/angular/angular-translate.2.18.1/angular-translate-loader-static-files.min.js"></script>
<script src="../vendor/angular/angular-translate.2.18.1/angular-translate-storage-cookie.min.js"></script>
<!-- bootstrap.js --> <!-- bootstrap.js -->
<script src="../vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script> <script src="../vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
<script src="../vendor/clipboard.min.js" type="text/javascript"></script> <script src="../vendor/clipboard.min.js" type="text/javascript"></script>
<!--biz--> <!--biz-->
<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/ConfigService.js"></script> <script type="application/javascript" src="../scripts/services/ConfigService.js"></script>
<script type="application/javascript" src="../scripts/services/UserService.js"></script> <script type="application/javascript" src="../scripts/services/UserService.js"></script>
<script type="application/javascript" src="../scripts/services/CommonService.js"></script> <script type="application/javascript" src="../scripts/services/CommonService.js"></script>
<script type="application/javascript" src="../scripts/services/PermissionService.js"></script> <script type="application/javascript" src="../scripts/services/PermissionService.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/controller/config/DiffConfigController.js"></script> <script type="application/javascript" src="../scripts/controller/config/DiffConfigController.js"></script>
<script type="application/javascript" src="../scripts/PageCommon.js"></script> <script type="application/javascript" src="../scripts/PageCommon.js"></script>
<script type="application/javascript" src="../scripts/directive/directive.js"></script> <script type="application/javascript" src="../scripts/directive/directive.js"></script>
<script type="application/javascript" src="../scripts/directive/show-text-modal-directive.js"></script> <script type="application/javascript" src="../scripts/directive/show-text-modal-directive.js"></script>
</body> </body>
</html> </html>
\ No newline at end of file
<!doctype html > <!doctype html>
<html ng-app="release_history"> <html ng-app="release_history">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="icon" href="../img/config.png"> <link rel="icon" href="../img/config.png">
...@@ -9,47 +10,48 @@ ...@@ -9,47 +10,48 @@
<link rel="stylesheet" type="text/css" media='all' href="../vendor/angular/loading-bar.min.css"> <link rel="stylesheet" type="text/css" media='all' href="../vendor/angular/loading-bar.min.css">
<link rel="stylesheet" type="text/css" href="../styles/common-style.css"> <link rel="stylesheet" type="text/css" href="../styles/common-style.css">
<link rel="stylesheet" type="text/css" href="../vendor/select2/select2.min.css"> <link rel="stylesheet" type="text/css" href="../vendor/select2/select2.min.css">
<title>发布历史</title> <title>{{'Config.History.Title' | translate }}</title>
</head> </head>
<body> <body>
<apollonav></apollonav> <apollonav></apollonav>
<div class="container-fluid apollo-container" ng-controller="ReleaseHistoryController"> <div class="container-fluid apollo-container" ng-controller="ReleaseHistoryController">
<section class="release-history panel col-md-12 no-radius hidden"> <section class="release-history panel col-md-12 no-radius hidden">
<div class="panel-heading row"> <div class="panel-heading row">
<div class="operation-caption-container col-md-3"> <div class="operation-caption-container col-md-3">
<div class="operation-caption release-operation-normal text-center" <div class="operation-caption release-operation-normal text-center" style="left:0;">
style="left:0;"> <small>{{'Config.History.MasterVersionPublish' | translate }}</small>
<small>主版本发布</small>
</div> </div>
<div class="operation-caption release-operation-rollback text-center" <div class="operation-caption release-operation-rollback text-center" style="left: 80px;">
style="left: 80px;"> <small>{{'Config.History.MasterVersionRollback' | translate }}</small>
<small>主版本回滚</small>
</div> </div>
<div class="operation-caption release-operation-gray text-center" <div class="operation-caption release-operation-gray text-center" style="left: 160px;">
style="left: 160px;"> <small>{{'Config.History.GrayscaleOperator' | translate }}</small>
<small>灰度操作</small>
</div> </div>
</div> </div>
<div class="col-md-6 text-center"> <div class="col-md-6 text-center">
<h4>发布历史</h4> <h4>{{'Config.History.PublishHistory' | translate }}</h4>
<small>(AppId:{{pageContext.appId}}, ENV:{{pageContext.env}}, Cluster:{{pageContext.clusterName}}, <small>({{'Common.AppId' | translate }}:{{pageContext.appId}},
Namespace:{{pageContext.namespaceName}}) {{'Common.Environment' | translate }}:{{pageContext.env}},
{{'Common.Cluster' | translate }}:{{pageContext.clusterName}},
{{'Common.Namespace' | translate }}:{{pageContext.namespaceName}})
</small> </small>
</div> </div>
<div class="pull-right back-btn"> <div class="pull-right back-btn">
<a type="button" class="btn btn-info" href="/config.html?#/appid={{pageContext.appId}}">返回到项目首页 <a type="button" class="btn btn-info"
href="/config.html?#/appid={{pageContext.appId}}">{{'Common.ReturnToIndex' | translate }}
</a> </a>
</div> </div>
</div> </div>
<div class="release-history-container panel-body row" ng-show="!isConfigHidden && releaseHistories && releaseHistories.length > 0"> <div class="release-history-container panel-body row"
ng-show="!isConfigHidden && releaseHistories && releaseHistories.length > 0">
<div class="release-history-list col-md-3"> <div class="release-history-list col-md-3">
<div class="media hover" ng-class="{'active': releaseHistory.id == selectedReleaseHistory}" <div class="media hover" ng-class="{'active': releaseHistory.id == selectedReleaseHistory}"
...@@ -65,33 +67,40 @@ ...@@ -65,33 +67,40 @@
</h4> </h4>
<div class="media-body"> <div class="media-body">
<h5 class="col-md-7 word-break" ng-show="releaseHistory.operation == 0">普通发布</h5> <h5 class="col-md-7 word-break" ng-show="releaseHistory.operation == 0">
<h5 class="col-md-7 word-break" ng-show="releaseHistory.operation == 1">回滚</h5> {{'Config.History.OperationType0' | translate }}</h5>
<h5 class="col-md-7 word-break" ng-show="releaseHistory.operation == 2">灰度发布</h5> <h5 class="col-md-7 word-break" ng-show="releaseHistory.operation == 1">
<h5 class="col-md-7 word-break" ng-show="releaseHistory.operation == 3">更新灰度规则</h5> {{'Config.History.OperationType1' | translate }}</h5>
<h5 class="col-md-7 word-break" ng-show="releaseHistory.operation == 4">灰度全量发布</h5> <h5 class="col-md-7 word-break" ng-show="releaseHistory.operation == 2">
<h5 class="col-md-7 word-break" ng-show="releaseHistory.operation == 5">灰度发布(主版本发布)</h5> {{'Config.History.OperationType2' | translate }}</h5>
<h5 class="col-md-7 word-break" ng-show="releaseHistory.operation == 6">灰度发布(主版本回滚)</h5> <h5 class="col-md-7 word-break" ng-show="releaseHistory.operation == 3">
<h5 class="col-md-7 word-break" ng-show="releaseHistory.operation == 7">放弃灰度</h5> {{'Config.History.OperationType3' | translate }}</h5>
<h5 class="col-md-7 word-break" ng-show="releaseHistory.operation == 8">删除灰度(全量发布)</h5> <h5 class="col-md-7 word-break" ng-show="releaseHistory.operation == 4">
{{'Config.History.OperationType4' | translate }}</h5>
<h5 class="col-md-7 word-break" ng-show="releaseHistory.operation == 5">
{{'Config.History.OperationType5' | translate }}</h5>
<h5 class="col-md-7 word-break" ng-show="releaseHistory.operation == 6">
{{'Config.History.OperationType6' | translate }}</h5>
<h5 class="col-md-7 word-break" ng-show="releaseHistory.operation == 7">
{{'Config.History.OperationType7' | translate }}</h5>
<h5 class="col-md-7 word-break" ng-show="releaseHistory.operation == 8">
{{'Config.History.OperationType8' | translate }}</h5>
<h6 class="col-md-5 text-right" ng-bind="releaseHistory.releaseTimeFormatted"></h6> <h6 class="col-md-5 text-right" ng-bind="releaseHistory.releaseTimeFormatted"></h6>
<span class="label label-warning no-radius emergency-publish" <span class="label label-warning no-radius emergency-publish"
ng-if="releaseHistory.operationContext.isEmergencyPublish">紧急发布</span> ng-if="releaseHistory.operationContext.isEmergencyPublish">{{'Config.History.UrgentPublish' | translate }}</span>
</div> </div>
</div> </div>
<div class="load-more media panel-heading text-center hover" <div class="load-more media panel-heading text-center hover" ng-show="!hasLoadAll"
ng-show="!hasLoadAll"
ng-click="findReleaseHistory()"> ng-click="findReleaseHistory()">
加载更多 {{'Config.History.LoadingMore' | translate }}
</div> </div>
</div> </div>
<!--properties mode info--> <!--properties mode info-->
<div class="release-info col-md-9 panel panel-default no-radius" <div class="release-info col-md-9 panel panel-default no-radius" ng-show="!isTextNamespace">
ng-show="!isTextNamespace">
<div class="panel-heading"> <div class="panel-heading">
<span ng-bind="history.releaseTitle"></span> <span ng-bind="history.releaseTitle"></span>
...@@ -104,14 +113,14 @@ ...@@ -104,14 +113,14 @@
<div class="col-md-7 text-right"> <div class="col-md-7 text-right">
<div class="btn-group"> <div class="btn-group">
<button type="button" class="btn btn-default btn-sm" <button type="button" class="btn btn-default btn-sm"
ng-class="{'active':history.viewType == 'diff'}" ng-class="{'active':history.viewType == 'diff'}" data-tooltip="tooltip"
data-tooltip="tooltip" data-placement="bottom" title="查看此次发布与上次版本的变更" data-placement="bottom" title="查看此次发布与上次版本的变更"
ng-click="switchConfigViewType(history, 'diff')">变更的配置 ng-click="switchConfigViewType(history, 'diff')">{{'Config.History.ChangedItem' | translate }}
</button> </button>
<button type="button" class="btn btn-default btn-sm" <button type="button" class="btn btn-default btn-sm"
ng-class="{'active':history.viewType == 'all'}" ng-class="{'active':history.viewType == 'all'}" data-tooltip="tooltip"
data-tooltip="tooltip" data-placement="bottom" title="查看此次发布的所有配置信息" data-placement="bottom" title="查看此次发布的所有配置信息"
ng-click="switchConfigViewType(history, 'all')">全部配置 ng-click="switchConfigViewType(history, 'all')">{{'Config.History.AllItem' | translate }}
</button> </button>
</div> </div>
</div> </div>
...@@ -121,38 +130,44 @@ ...@@ -121,38 +130,44 @@
<div class="panel-body config"> <div class="panel-body config">
<section ng-show="history.viewType=='diff'"> <section ng-show="history.viewType=='diff'">
<h4 class="section-title">变更的配置</h4> <h4 class="section-title">{{'Config.History.ChangedItem' | translate }}</h4>
<div ng-show="history.changes && history.changes.length > 0"> <div ng-show="history.changes && history.changes.length > 0">
<table class="no-margin table table-striped table-hover table-bordered"> <table class="no-margin table table-striped table-hover table-bordered">
<thead> <thead>
<tr> <tr>
<th>Type</th> <th>{{'Config.History.ChangeType' | translate }}</th>
<th>Key</th> <th>{{'Config.History.ChangeKey' | translate }}</th>
<th>Old Value</th> <th>{{'Config.History.ChangeOldValue' | translate }}</th>
<th>New Value</th> <th>{{'Config.History.ChangeNewValue' | translate }}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr ng-repeat="change in history.changes"> <tr ng-repeat="change in history.changes">
<td width="10%"> <td width="10%">
<span ng-show="change.type == 'ADDED'">新增</span> <span
<span ng-show="change.type == 'MODIFIED'">修改</span> ng-show="change.type == 'ADDED'">{{'Config.History.ChangeTypeNew' | translate }}</span>
<span ng-show="change.type == 'DELETED'">删除</span> <span
ng-show="change.type == 'MODIFIED'">{{'Config.History.ChangeTypeModify' | translate }}</span>
<span
ng-show="change.type == 'DELETED'">{{'Config.History.ChangeTypeDelete' | translate }}</span>
</td> </td>
<td class="cursor-pointer" width="20%" <td class="cursor-pointer" width="20%"
ng-click="showText(change.entity.firstEntity.key)"> ng-click="showText(change.entity.firstEntity.key)">
<span ng-bind="change.entity.firstEntity.key | limitTo: 250"></span> <span ng-bind="change.entity.firstEntity.key | limitTo: 250"></span>
<span ng-bind="change.entity.firstEntity.key.length > 250 ? '...' :''"></span> <span
ng-bind="change.entity.firstEntity.key.length > 250 ? '...' :''"></span>
</td> </td>
<td class="cursor-pointer" width="35%" <td class="cursor-pointer" width="35%"
ng-click="showText(change.entity.firstEntity.value)"> ng-click="showText(change.entity.firstEntity.value)">
<span ng-bind="change.entity.firstEntity.value | limitTo: 250"></span> <span ng-bind="change.entity.firstEntity.value | limitTo: 250"></span>
<span ng-bind="change.entity.firstEntity.value.length > 250 ? '...' :''"></span> <span
ng-bind="change.entity.firstEntity.value.length > 250 ? '...' :''"></span>
</td> </td>
<td class="cursor-pointer" width="35%" <td class="cursor-pointer" width="35%"
ng-click="showText(change.entity.secondEntity.value)"> ng-click="showText(change.entity.secondEntity.value)">
<span ng-bind="change.entity.secondEntity.value | limitTo: 250"></span> <span ng-bind="change.entity.secondEntity.value | limitTo: 250"></span>
<span ng-bind="change.entity.secondEntity.value.length > 250 ? '...' :''"></span> <span
ng-bind="change.entity.secondEntity.value.length > 250 ? '...' :''"></span>
</td> </td>
</tr> </tr>
</tbody> </tbody>
...@@ -160,19 +175,19 @@ ...@@ -160,19 +175,19 @@
</div> </div>
<div class="text-center empty-container" <div class="text-center empty-container"
ng-show="!history.changes || history.changes.length == 0"> ng-show="!history.changes || history.changes.length == 0">
<h5>无配置更改</h5> <h5>{{'Config.History.NoChange' | translate }}</h5>
</div> </div>
</section> </section>
<section ng-show="history.viewType=='all'"> <section ng-show="history.viewType=='all'">
<h4 class="section-title">全部配置</h4> <h4 class="section-title">{{'Config.History.AllItem' | translate }}</h4>
<table class="no-margin table table-striped table-hover table-bordered" <table class="no-margin table table-striped table-hover table-bordered"
ng-show="history.configuration && history.configuration.length > 0"> ng-show="history.configuration && history.configuration.length > 0">
<thead> <thead>
<tr> <tr>
<th>Key</th> <th>{{'Config.History.ChangeKey' | translate }}</th>
<th>Value</th> <th>{{'Config.History.ChangeValue' | translate }}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
...@@ -190,20 +205,21 @@ ...@@ -190,20 +205,21 @@
</table> </table>
<div class="text-center empty-container" <div class="text-center empty-container"
ng-show="history.viewType=='all' && (!history.configuration || history.configuration.length == 0)"> ng-show="history.viewType=='all' && (!history.configuration || history.configuration.length == 0)">
<h5>无配置</h5> <h5>{{'Config.History.NoItem' | translate }}</h5>
</div> </div>
</section> </section>
<section ng-show="history.branchName != history.clusterName && history.operation != 8 && history.operation != 7"> <section
ng-show="history.branchName != history.clusterName && history.operation != 8 && history.operation != 7">
<hr> <hr>
<h4 class="section-title">灰度规则</h4> <h4 class="section-title">{{'Config.History.GrayscaleRule' | translate }}</h4>
<table class="no-margin table table-striped table-hover table-bordered" <table class="no-margin table table-striped table-hover table-bordered"
ng-show="history.operationContext.rules"> ng-show="history.operationContext.rules">
<thead> <thead>
<tr> <tr>
<th>灰度的AppId</th> <th>{{'Config.History.GrayscaleAppId' | translate }}</th>
<th>灰度的IP</th> <th>{{'Config.History.GrayscaleIp' | translate }}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
...@@ -214,7 +230,7 @@ ...@@ -214,7 +230,7 @@
</tbody> </tbody>
</table> </table>
<h5 class="text-center empty-container" ng-show="!history.operationContext.rules"> <h5 class="text-center empty-container" ng-show="!history.operationContext.rules">
无灰度规则 {{'Config.History.NoGrayscaleRule' | translate }}
</h5> </h5>
</section> </section>
...@@ -224,60 +240,65 @@ ...@@ -224,60 +240,65 @@
<!--text mode--> <!--text mode-->
<div class="release-info col-md-9" <div class="release-info col-md-9"
ng-show="isTextNamespace && history.changes && history.changes.length > 0"> ng-show="isTextNamespace && history.changes && history.changes.length > 0">
<apollodiff ng-repeat="change in history.changes" <apollodiff ng-repeat="change in history.changes" old-str="change.entity.firstEntity.value"
old-str="change.entity.firstEntity.value" new-str="change.entity.secondEntity.value" apollo-id="'releaseStrDiff'">
new-str="change.entity.secondEntity.value"
apollo-id="'releaseStrDiff'">
</apollodiff> </apollodiff>
</div> </div>
</div> </div>
<div class="panel-body" ng-show="isConfigHidden || !releaseHistories || releaseHistories.length == 0"> <div class="panel-body" ng-show="isConfigHidden || !releaseHistories || releaseHistories.length == 0">
<h4 class="text-center empty-container" ng-show="isConfigHidden">您不是该项目的管理员,也没有该Namespace的编辑或发布权限,无法查看发布历史</h4> <h4 class="text-center empty-container" ng-show="isConfigHidden">
<h4 class="text-center empty-container" ng-show="!isConfigHidden">无发布历史信息</h4> {{'Config.History.NoPermissonTips' | translate }}</h4>
<h4 class="text-center empty-container" ng-show="!isConfigHidden">
{{'Config.History.NoPublishHistory' | translate }}</h4>
</div> </div>
</section> </section>
<showtextmodal text="text"></showtextmodal> <showtextmodal text="text"></showtextmodal>
</div> </div>
<div ng-include="'../views/common/footer.html'"></div> <div ng-include="'../views/common/footer.html'"></div>
<!-- jquery.js --> <!-- jquery.js -->
<script src="../vendor/jquery.min.js" type="text/javascript"></script> <script src="../vendor/jquery.min.js" type="text/javascript"></script>
<script src="../vendor/select2/select2.min.js" type="text/javascript"></script> <script src="../vendor/select2/select2.min.js" type="text/javascript"></script>
<!--angular--> <!--angular-->
<script src="../vendor/angular/angular.min.js"></script> <script src="../vendor/angular/angular.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>
<script src="../vendor/angular/angular-cookies.min.js"></script>
<script src="../vendor/angular/angular-translate.2.18.1/angular-translate.min.js"></script>
<script src="../vendor/angular/angular-translate.2.18.1/angular-translate-loader-static-files.min.js"></script>
<script src="../vendor/angular/angular-translate.2.18.1/angular-translate-storage-cookie.min.js"></script>
<!-- bootstrap.js --> <!-- bootstrap.js -->
<script src="../vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script> <script src="../vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
<script src="../vendor/diff.min.js" type="text/javascript"></script> <script src="../vendor/diff.min.js" type="text/javascript"></script>
<!--biz--> <!--biz-->
<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/ReleaseService.js"></script> <script type="application/javascript" src="../scripts/services/ReleaseService.js"></script>
<script type="application/javascript" src="../scripts/services/UserService.js"></script> <script type="application/javascript" src="../scripts/services/UserService.js"></script>
<script type="application/javascript" src="../scripts/services/CommonService.js"></script> <script type="application/javascript" src="../scripts/services/CommonService.js"></script>
<script type="application/javascript" src="../scripts/services/ReleaseHistoryService.js"></script> <script type="application/javascript" src="../scripts/services/ReleaseHistoryService.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/services/PermissionService.js"></script> <script type="application/javascript" src="../scripts/services/PermissionService.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/controller/config/ReleaseHistoryController.js"></script> <script type="application/javascript" src="../scripts/controller/config/ReleaseHistoryController.js"></script>
<script type="application/javascript" src="../scripts/PageCommon.js"></script> <script type="application/javascript" src="../scripts/PageCommon.js"></script>
<script type="application/javascript" src="../scripts/directive/directive.js"></script> <script type="application/javascript" src="../scripts/directive/directive.js"></script>
<script type="application/javascript" src="../scripts/directive/show-text-modal-directive.js"></script> <script type="application/javascript" src="../scripts/directive/show-text-modal-directive.js"></script>
<script type="application/javascript" src="../scripts/directive/diff-directive.js"></script> <script type="application/javascript" src="../scripts/directive/diff-directive.js"></script>
</body> </body>
</html> </html>
\ No newline at end of file
<!doctype html> <!doctype html>
<html ng-app="sync_item"> <html ng-app="sync_item">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="icon" href="../img/config.png"> <link rel="icon" href="../img/config.png">
...@@ -9,35 +10,35 @@ ...@@ -9,35 +10,35 @@
<link rel="stylesheet" type="text/css" media='all' href="../vendor/angular/loading-bar.min.css"> <link rel="stylesheet" type="text/css" media='all' href="../vendor/angular/loading-bar.min.css">
<link rel="stylesheet" type="text/css" href="../styles/common-style.css"> <link rel="stylesheet" type="text/css" href="../styles/common-style.css">
<link rel="stylesheet" type="text/css" href="../vendor/select2/select2.min.css"> <link rel="stylesheet" type="text/css" href="../vendor/select2/select2.min.css">
<title>同步配置</title> <title>{{'Config.Sync.Title' | translate }}</title>
</head> </head>
<body> <body>
<apollonav></apollonav> <apollonav></apollonav>
<div class="container-fluid apollo-container hidden" ng-controller="SyncItemController"> <div class="container-fluid apollo-container hidden" ng-controller="SyncItemController">
<section class="panel col-md-offset-1 col-md-10"> <section class="panel col-md-offset-1 col-md-10">
<header class="panel-heading"> <header class="panel-heading">
<div class="row"> <div class="row">
<div class="col-md-7"> <div class="col-md-7">
<h4 class="modal-title">同步配置 <h4 class="modal-title">{{'Config.Sync.Title' | translate }}
<small ng-show="syncItemStep == 1">(第一步:选择同步信息)</small> <small ng-show="syncItemStep == 1">{{'Config.Sync.FistStep' | translate }}</small>
<small ng-show="syncItemStep == 2">(第二步:检查Diff)</small> <small ng-show="syncItemStep == 2">{{'Config.Sync.SecondStep' | translate }}</small>
</h4> </h4>
</div> </div>
<div class="col-md-5 text-right"> <div class="col-md-5 text-right">
<button type="button" class="btn btn-primary" ng-show="syncItemStep > 1 && syncItemStep < 3" <button type="button" class="btn btn-primary" ng-show="syncItemStep > 1 && syncItemStep < 3"
ng-click="syncItemNextStep(-1)">上一步 ng-click="syncItemNextStep(-1)">{{'Config.Sync.PreviousStep' | translate }}
</button> </button>
<button type="button" class="btn btn-primary" ng-show="syncItemStep < 2" <button type="button" class="btn btn-primary" ng-show="syncItemStep < 2"
ng-click="diff()">下一步 ng-click="diff()">{{'Config.Sync.NextStep' | translate }}
</button> </button>
<button type="button" class="btn btn-success" ng-show="syncItemStep == 2 && hasDiff" <button type="button" class="btn btn-success" ng-show="syncItemStep == 2 && hasDiff"
ng-click="syncItems()" ng-disabled="syncBtnDisabled">同步 ng-click="syncItems()" ng-disabled="syncBtnDisabled">{{'Config.Sync.Sync' | translate }}
</button> </button>
<button type="button" class="btn btn-info" data-dismiss="modal" <button type="button" class="btn btn-info" data-dismiss="modal"
ng-click="backToAppHomePage()">返回到项目首页 ng-click="backToAppHomePage()">{{'Common.ReturnToIndex' | translate }}
</button> </button>
</div> </div>
</div> </div>
...@@ -45,15 +46,15 @@ ...@@ -45,15 +46,15 @@
<div class="panel-body"> <div class="panel-body">
<div class="row" ng-show="syncItemStep == 1"> <div class="row" ng-show="syncItemStep == 1">
<div class="alert-info alert no-radius"> <div class="alert-info alert no-radius">
<strong>Tips:</strong> <strong>{{'Config.Sync.Tips' | translate }}:</strong>
<ul> <ul>
<li>通过同步配置功能,可以使多个环境、集群间的配置保持一致</li> <li>{{'Config.Sync.Tips1' | translate }}</li>
<li>需要注意的是,同步完之后需要发布后才会对应用生效</li> <li>{{'Config.Sync.Tips2' | translate }}</li>
</ul> </ul>
</div> </div>
<div class="form-horizontal"> <div class="form-horizontal">
<div class="form-group"> <div class="form-group">
<label class="col-sm-2 control-label">同步的Namespace</label> <label class="col-sm-2 control-label">{{'Config.Sync.SyncNamespace' | translate }}</label>
<div class="col-sm-6"> <div class="col-sm-6">
<h4 ng-bind="pageContext.namespaceName"></h4> <h4 ng-bind="pageContext.namespaceName"></h4>
</div> </div>
...@@ -61,10 +62,10 @@ ...@@ -61,10 +62,10 @@
</div> </div>
<div class="form-horizontal"> <div class="form-horizontal">
<div class="form-group"> <div class="form-group">
<label class="col-sm-2 control-label">同步到那个集群</label> <label class="col-sm-2 control-label">{{'Config.Sync.SyncToCluster' | translate }}</label>
<div class="col-sm-6"> <div class="col-sm-6">
<apolloclusterselector apollo-app-id="pageContext.appId" apollo-default-all-checked="true" <apolloclusterselector apollo-app-id="pageContext.appId"
apollo-select="collectSelectedClusters" apollo-default-all-checked="true" apollo-select="collectSelectedClusters"
apollo-not-checked-env="pageContext.env" apollo-not-checked-env="pageContext.env"
apollo-not-checked-cluster="pageContext.clusterName"></apolloclusterselector> apollo-not-checked-cluster="pageContext.clusterName"></apolloclusterselector>
</div> </div>
...@@ -76,30 +77,33 @@ ...@@ -76,30 +77,33 @@
<div class="row" ng-show="syncItemStep == 1" style="margin-top: 10px;"> <div class="row" ng-show="syncItemStep == 1" style="margin-top: 10px;">
<div class="form-horizontal"> <div class="form-horizontal">
<div class="col-sm-2 text-right"> <div class="col-sm-2 text-right">
<label class="control-label">需要同步的配置</label> <label class="control-label">{{'Config.Sync.NeedToSyncItem' | translate }}</label>
</div> </div>
<div class="col-sm-10"> <div class="col-sm-10">
<div class="row text-right" style="margin-bottom: 5px; margin-right: 0px;"> <div class="row text-right" style="margin-bottom: 5px; margin-right: 0px;">
按最后更新时间过滤 {{'Config.Sync.SortByLastModifyTime' | translate }}
开始时间:<input type="date" ng-model="filterBeginTime"> 结束时间: <input type="date" ng-model="filterEndTime"> {{'Config.Sync.BeginTime' | translate }}:<input type="date" ng-model="filterBeginTime">
<button class="btn btn-sm btn-primary" ng-click="filter()">过滤</button> {{'Config.Sync.EndTime' | translate }}: <input type="date" ng-model="filterEndTime">
<button class="btn btn-sm btn-default" ng-click="resetFilter()">重置</button> <button class="btn btn-sm btn-primary"
ng-click="filter()">{{'Config.Sync.Filter' | translate }}</button>
<button class="btn btn-sm btn-default"
ng-click="resetFilter()">{{'Config.Sync.Rest' | translate }}</button>
</div> </div>
<table class="table table-bordered table-striped table-hover"> <table class="table table-bordered table-striped table-hover">
<thead> <thead>
<tr> <tr>
<td><input type="checkbox" ng-click="toggleItemsCheckedStatus()"></td> <td><input type="checkbox" ng-click="toggleItemsCheckedStatus()"></td>
<td class="hover" ng-click="col='key';desc=!desc;"> <td class="hover" ng-click="col='key';desc=!desc;">
Key {{'Config.Sync.ItemKey' | translate }}
<span class="glyphicon glyphicon-sort"></span> <span class="glyphicon glyphicon-sort"></span>
</td> </td>
<td>Value</td> <td>{{'Config.Sync.ItemValue' | translate }}</td>
<td class="hover" ng-click="col='dataChangeCreatedTime';desc=!desc;"> <td class="hover" ng-click="col='dataChangeCreatedTime';desc=!desc;">
Create Time {{'Config.Sync.ItemCreateTime' | translate }}
<span class="glyphicon glyphicon-sort"></span> <span class="glyphicon glyphicon-sort"></span>
</td> </td>
<td class="hover" ng-click="col='dataChangeLastModifiedTime';desc=!desc;"> <td class="hover" ng-click="col='dataChangeLastModifiedTime';desc=!desc;">
Update Time {{'Config.Sync.ItemUpdateTime' | translate }}
<span class="glyphicon glyphicon-sort"></span> <span class="glyphicon glyphicon-sort"></span>
</td> </td>
</tr> </tr>
...@@ -117,10 +121,12 @@ ...@@ -117,10 +121,12 @@
<span ng-bind="item.value.length > 250 ? '...' : ''"></span> <span ng-bind="item.value.length > 250 ? '...' : ''"></span>
</td> </td>
<td width="15%"> <td width="15%">
<span ng-bind="item.dataChangeCreatedTime | date: 'yyyy-MM-dd HH:mm:ss'"></span> <span
ng-bind="item.dataChangeCreatedTime | date: 'yyyy-MM-dd HH:mm:ss'"></span>
</td> </td>
<td width="15%"> <td width="15%">
<span ng-bind="item.dataChangeLastModifiedTime | date: 'yyyy-MM-dd HH:mm:ss'"></span> <span
ng-bind="item.dataChangeLastModifiedTime | date: 'yyyy-MM-dd HH:mm:ss'"></span>
</td> </td>
</tr> </tr>
</tbody> </tbody>
...@@ -134,15 +140,17 @@ ...@@ -134,15 +140,17 @@
<!--step 2--> <!--step 2-->
<div class="row" ng-show="syncItemStep == 2" ng-repeat="clusterDiff in clusterDiffs"> <div class="row" ng-show="syncItemStep == 2" ng-repeat="clusterDiff in clusterDiffs">
<h4 class="text-center"> <h4 class="text-center">
环境:<span ng-bind="clusterDiff.namespace.env"></span> {{'Common.Environment' | translate }}:<span ng-bind="clusterDiff.namespace.env"></span>
集群:<span ng-bind="clusterDiff.namespace.clusterName"></span> {{'Common.Cluster' | translate }}:<span ng-bind="clusterDiff.namespace.clusterName"></span>
<span ng-show="!clusterDiff.extInfo">Namespace:{{pageContext.namespaceName}}</span> <span
ng-show="!clusterDiff.extInfo">{{'Common.Namespace' | translate }}:{{pageContext.namespaceName}}</span>
</h4> </h4>
<div class="text-center" <div class="text-center"
ng-show="clusterDiff.diffs.createItems.length + clusterDiff.diffs.updateItems.length == 0 || clusterDiff.extInfo"> ng-show="clusterDiff.diffs.createItems.length + clusterDiff.diffs.updateItems.length == 0 || clusterDiff.extInfo">
<span ng-show="clusterDiff.diffs.createItems.length + clusterDiff.diffs.updateItems.length == 0 && !clusterDiff.extInfo">没有更新的配置</span> <span
ng-show="clusterDiff.diffs.createItems.length + clusterDiff.diffs.updateItems.length == 0 && !clusterDiff.extInfo">{{'Config.Sync.NoNeedSyncItem' | translate }}</span>
<span ng-show="clusterDiff.extInfo" ng-bind="clusterDiff.extInfo"></span> <span ng-show="clusterDiff.extInfo" ng-bind="clusterDiff.extInfo"></span>
,忽略同步 ,{{'Config.Sync.IgnoreSync' | translate }}
</div> </div>
<div class="row" style="margin-top: 10px;" <div class="row" style="margin-top: 10px;"
...@@ -152,35 +160,37 @@ ...@@ -152,35 +160,37 @@
<table class="table table-bordered table-striped table-hover"> <table class="table table-bordered table-striped table-hover">
<thead> <thead>
<tr> <tr>
<td>Type</td> <td>{{'Config.Sync.Step2Type' | translate }}</td>
<td>Key</td> <td>{{'Config.Sync.Step2Key' | translate }}</td>
<td>同步前</td> <td>{{'Config.Sync.Step2SyncBefore' | translate }}</td>
<td>同步后</td> <td>{{'Config.Sync.Step2SyncAfter' | translate }}</td>
<td>Comment</td> <td>{{'Config.Sync.Step2Comment' | translate }}</td>
<td>操作</td> <td>{{'Config.Sync.Step2Operator' | translate }}</td>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr ng-repeat="createItem in clusterDiff.diffs.createItems"> <tr ng-repeat="createItem in clusterDiff.diffs.createItems">
<td width="5%">新增</td> <td width="5%">{{'Config.Sync.NewAdd' | translate }}</td>
<td width="15%" ng-bind="createItem.key"></td> <td width="15%" ng-bind="createItem.key"></td>
<td width="30%"></td> <td width="30%"></td>
<td width="30%" ng-bind="createItem.value"></td> <td width="30%" ng-bind="createItem.value"></td>
<td width="15%" ng-bind="createItem.comment"></td> <td width="15%" ng-bind="createItem.comment"></td>
<td width="5%"> <td width="5%">
<a data-tooltip="tooltip" data-placement="bottom" title="不同步该配置" <a data-tooltip="tooltip" data-placement="bottom"
ng-click="removeItem(clusterDiff.diffs, 'create', createItem)">删除</a> title="{{'Config.Sync.NoSyncItem' | translate }}"
ng-click="removeItem(clusterDiff.diffs, 'create', createItem)">{{'Config.Sync.Delete' | translate }}</a>
</td> </td>
</tr> </tr>
<tr ng-repeat="updateItem in clusterDiff.diffs.updateItems"> <tr ng-repeat="updateItem in clusterDiff.diffs.updateItems">
<td width="5%">更新</td> <td width="5%">{{'Config.Sync.Update' | translate }}</td>
<td width="15%" ng-bind="updateItem.key"></td> <td width="15%" ng-bind="updateItem.key"></td>
<td width="30%" ng-bind="updateItem.oldValue"></td> <td width="30%" ng-bind="updateItem.oldValue"></td>
<td width="30%" ng-bind="updateItem.value"></td> <td width="30%" ng-bind="updateItem.value"></td>
<td width="15%" ng-bind="updateItem.comment"></td> <td width="15%" ng-bind="updateItem.comment"></td>
<td width="5%"> <td width="5%">
<a data-tooltip="tooltip" data-placement="bottom" title="不同步该配置" <a data-tooltip="tooltip" data-placement="bottom"
ng-click="removeItem(clusterDiff.diffs, 'update', updateItem)">删除</a> title="{{'Config.Sync.NoSyncItem' | translate }}"
ng-click="removeItem(clusterDiff.diffs, 'update', updateItem)">{{'Config.Sync.Delete' | translate }}</a>
</td> </td>
</tr> </tr>
</tbody> </tbody>
...@@ -195,52 +205,57 @@ ...@@ -195,52 +205,57 @@
<!--step 3--> <!--step 3-->
<div class="row text-center" ng-show="syncItemStep == 3 && syncSuccess"> <div class="row text-center" ng-show="syncItemStep == 3 && syncSuccess">
<img src="../img/sync-succ.png" style="height: 100px; width: 100px"> <img src="../img/sync-succ.png" style="height: 100px; width: 100px">
<h3>同步成功!</h3> <h3>{{'Config.Sync.SyncSuccessfully' | translate }}</h3>
</div> </div>
<div class="row text-center" ng-show="syncItemStep == 3 && !syncSuccess"> <div class="row text-center" ng-show="syncItemStep == 3 && !syncSuccess">
<img src="../img/sync-error.png" style="height: 100px; width: 100px"> <img src="../img/sync-error.png" style="height: 100px; width: 100px">
<h3>同步失败!</h3> <h3>{{'Config.Sync.SyncFailed' | translate }}</h3>
</div> </div>
</div> </div>
</section> </section>
<showtextmodal text="text"/> <showtextmodal text="text" />
</div> </div>
<div ng-include="'../views/common/footer.html'"></div> <div ng-include="'../views/common/footer.html'"></div>
<!-- jquery.js --> <!-- jquery.js -->
<script src="../vendor/jquery.min.js" type="text/javascript"></script> <script src="../vendor/jquery.min.js" type="text/javascript"></script>
<script src="../vendor/select2/select2.min.js" type="text/javascript"></script> <script src="../vendor/select2/select2.min.js" type="text/javascript"></script>
<!--angular--> <!--angular-->
<script src="../vendor/angular/angular.min.js"></script> <script src="../vendor/angular/angular.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>
<script src="../vendor/angular/angular-cookies.min.js"></script>
<script src="../vendor/angular/angular-translate.2.18.1/angular-translate.min.js"></script>
<script src="../vendor/angular/angular-translate.2.18.1/angular-translate-loader-static-files.min.js"></script>
<script src="../vendor/angular/angular-translate.2.18.1/angular-translate-storage-cookie.min.js"></script>
<!-- bootstrap.js --> <!-- bootstrap.js -->
<script src="../vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script> <script src="../vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
<script src="../vendor/clipboard.min.js" type="text/javascript"></script> <script src="../vendor/clipboard.min.js" type="text/javascript"></script>
<!--biz--> <!--biz-->
<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/ConfigService.js"></script> <script type="application/javascript" src="../scripts/services/ConfigService.js"></script>
<script type="application/javascript" src="../scripts/services/UserService.js"></script> <script type="application/javascript" src="../scripts/services/UserService.js"></script>
<script type="application/javascript" src="../scripts/services/CommonService.js"></script> <script type="application/javascript" src="../scripts/services/CommonService.js"></script>
<script type="application/javascript" src="../scripts/services/PermissionService.js"></script> <script type="application/javascript" src="../scripts/services/PermissionService.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/controller/config/SyncConfigController.js"></script> <script type="application/javascript" src="../scripts/controller/config/SyncConfigController.js"></script>
<script type="application/javascript" src="../scripts/PageCommon.js"></script> <script type="application/javascript" src="../scripts/PageCommon.js"></script>
<script type="application/javascript" src="../scripts/directive/directive.js"></script> <script type="application/javascript" src="../scripts/directive/directive.js"></script>
<script type="application/javascript" src="../scripts/directive/show-text-modal-directive.js"></script> <script type="application/javascript" src="../scripts/directive/show-text-modal-directive.js"></script>
</body> </body>
</html> </html>
\ No newline at end of file
<!doctype html> <!doctype html>
<html ng-app="delete_app_cluster_namespace"> <html ng-app="delete_app_cluster_namespace">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="icon" href="../img/config.png"> <link rel="icon" href="../img/config.png">
...@@ -9,23 +10,23 @@ ...@@ -9,23 +10,23 @@
<link rel="stylesheet" type="text/css" media='all' href="../vendor/angular/loading-bar.min.css"> <link rel="stylesheet" type="text/css" media='all' href="../vendor/angular/loading-bar.min.css">
<link rel="stylesheet" type="text/css" href="../styles/common-style.css"> <link rel="stylesheet" type="text/css" href="../styles/common-style.css">
<link rel="stylesheet" type="text/css" href="../vendor/select2/select2.min.css"> <link rel="stylesheet" type="text/css" href="../vendor/select2/select2.min.css">
<title>删除应用、集群、AppNamespace</title> <title>{{'Delete.Title' | translate }}</title>
</head> </head>
<body> <body>
<apollonav></apollonav> <apollonav></apollonav>
<div class="container-fluid" ng-controller="DeleteAppClusterNamespaceController"> <div class="container-fluid" ng-controller="DeleteAppClusterNamespaceController">
<div class="col-md-10 col-md-offset-1 panel"> <div class="col-md-10 col-md-offset-1 panel">
<section class="panel-body" ng-show="isRootUser"> <section class="panel-body" ng-show="isRootUser">
<!-- delete app --> <!-- delete app -->
<section class="row"> <section class="row">
<h5>删除应用 <h5>{{'Delete.DeleteApp' | translate }}
<small> <small>
(由于删除应用影响面较大,所以现在暂时只允许系统管理员删除,请确保没有客户端读取该应用的配置后再做删除动作) {{'Delete.DeleteAppTips' | translate }}
</small> </small>
</h5> </h5>
<hr> <hr>
...@@ -33,18 +34,19 @@ ...@@ -33,18 +34,19 @@
<div class="form-group" valdr-form-group> <div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
应用AppId</label> {{'Common.AppId' | translate }}
</label>
<div class="col-sm-5"> <div class="col-sm-5">
<input type="text" class="form-control" ng-model="app.appId"> <input type="text" class="form-control" ng-model="app.appId">
<small>(删除前请先查询应用信息)</small> <small> {{'Delete.AppIdTips' | translate }}</small>
</div> </div>
<div class="col-sm-1"> <div class="col-sm-1">
<button class="btn btn-info" ng-click="getAppInfo()">查询</button> <button class="btn btn-info" ng-click="getAppInfo()">{{'Common.Search' | translate }}</button>
</div> </div>
</div> </div>
<div class="form-group" valdr-form-group> <div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
应用信息</label> {{'Delete.AppInfo' | translate }}</label>
<div class="col-sm-5"> <div class="col-sm-5">
<h5 ng-show="app.info" ng-bind="app.info"></h5> <h5 ng-show="app.info" ng-bind="app.info"></h5>
</div> </div>
...@@ -52,10 +54,9 @@ ...@@ -52,10 +54,9 @@
<div class="form-group"> <div class="form-group">
<div class="col-sm-offset-2 col-sm-9"> <div class="col-sm-offset-2 col-sm-9">
<button type="submit" class="btn btn-primary" <button type="submit" class="btn btn-primary" ng-disabled="deleteAppBtnDisabled"
ng-disabled="deleteAppBtnDisabled"
ng-click="deleteApp()"> ng-click="deleteApp()">
删除应用 {{'Delete.DeleteApp' | translate }}
</button> </button>
</div> </div>
</div> </div>
...@@ -64,9 +65,9 @@ ...@@ -64,9 +65,9 @@
<!-- delete cluster --> <!-- delete cluster -->
<section class="row"> <section class="row">
<h5>删除集群 <h5>{{'Delete.DeleteCluster' | translate }}
<small> <small>
(由于删除集群影响面较大,所以现在暂时只允许系统管理员删除,请确保没有客户端读取该集群的配置后再做删除动作) {{'Delete.DeleteClusterTips' | translate }}
</small> </small>
</h5> </h5>
<hr> <hr>
...@@ -74,7 +75,8 @@ ...@@ -74,7 +75,8 @@
<div class="form-group" valdr-form-group> <div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
应用AppId</label> {{'Common.AppId' | translate }}
</label>
<div class="col-sm-5"> <div class="col-sm-5">
<input type="text" class="form-control" ng-model="cluster.appId"> <input type="text" class="form-control" ng-model="cluster.appId">
</div> </div>
...@@ -82,7 +84,8 @@ ...@@ -82,7 +84,8 @@
<div class="form-group" valdr-form-group> <div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
环境名称</label> {{'Delete.EnvName' | translate }}
</label>
<div class="col-sm-5"> <div class="col-sm-5">
<input type="text" class="form-control" ng-model="cluster.env"> <input type="text" class="form-control" ng-model="cluster.env">
</div> </div>
...@@ -90,18 +93,20 @@ ...@@ -90,18 +93,20 @@
<div class="form-group" valdr-form-group> <div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
集群名称</label> {{'Common.ClusterName' | translate }}
</label>
<div class="col-sm-5"> <div class="col-sm-5">
<input type="text" class="form-control" ng-model="cluster.name"> <input type="text" class="form-control" ng-model="cluster.name">
<small>(删除前请先查询应用集群信息)</small> <small>{{'Delete.ClusterNameTips' | translate }}</small>
</div> </div>
<div class="col-sm-1"> <div class="col-sm-1">
<button class="btn btn-info" ng-click="getClusterInfo()">查询</button> <button class="btn btn-info"
ng-click="getClusterInfo()">{{'Common.Search' | translate }}</button>
</div> </div>
</div> </div>
<div class="form-group" viv clform-group> <div class="form-group" viv clform-group>
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
集群信息</label> {{'Delete.ClusterInfo' | translate }}</label>
<div class="col-sm-5"> <div class="col-sm-5">
<h5 ng-show="cluster.info" ng-bind="cluster.info"></h5> <h5 ng-show="cluster.info" ng-bind="cluster.info"></h5>
</div> </div>
...@@ -109,10 +114,9 @@ ...@@ -109,10 +114,9 @@
<div class="form-group"> <div class="form-group">
<div class="col-sm-offset-2 col-sm-9"> <div class="col-sm-offset-2 col-sm-9">
<button type="submit" class="btn btn-primary" <button type="submit" class="btn btn-primary" ng-disabled="deleteClusterBtnDisabled"
ng-disabled="deleteClusterBtnDisabled"
ng-click="deleteCluster()"> ng-click="deleteCluster()">
删除集群 {{'Delete.DeleteCluster' | translate }}
</button> </button>
</div> </div>
</div> </div>
...@@ -121,18 +125,19 @@ ...@@ -121,18 +125,19 @@
<!-- delete app namespace --> <!-- delete app namespace -->
<section class="row"> <section class="row">
<h5>删除AppNamespace <h5>{{'Delete.DeleteNamespace' | translate }}
<small>(注意,所有环境的Namespace和AppNamespace都会被删除!如果只是要删除某个环境的Namespace,让用户到项目页面中自行删除!)</small> <small>{{'Delete.DeleteNamespaceTips' | translate }}</small>
</h5> </h5>
<small> <small>
目前用户可以自行删除关联的Namespace和私有的Namespace,不过无法删除AppNamespace元信息,因为删除AppNamespace影响面较大,所以现在暂时只允许系统管理员删除,对于公共Namespace需要确保没有应用关联了该AppNamespace。 {{'Delete.DeleteNamespaceTips2' | translate }}
</small> </small>
<hr> <hr>
<form class="form-horizontal"> <form class="form-horizontal">
<div class="form-group" valdr-form-group> <div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
应用AppId</label> {{'Common.AppId' | translate }}
</label>
<div class="col-sm-5"> <div class="col-sm-5">
<input type="text" class="form-control" ng-model="appNamespace.appId"> <input type="text" class="form-control" ng-model="appNamespace.appId">
</div> </div>
...@@ -140,18 +145,19 @@ ...@@ -140,18 +145,19 @@
<div class="form-group" valdr-form-group> <div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
AppNamespace名称</label> {{'Delete.AppNamespaceName' | translate }}
</label>
<div class="col-sm-5"> <div class="col-sm-5">
<input type="text" class="form-control" ng-model="appNamespace.name"> <input type="text" class="form-control" ng-model="appNamespace.name">
<small>(非properties类型的namespace请加上类型后缀,例如apollo.xml)</small> <small>{{'Delete.AppNamespaceNameTips' | translate }}</small>
</div> </div>
<div class="col-sm-1"> <div class="col-sm-1">
<button class="btn btn-info" ng-click="getAppNamespaceInfo()">查询</button> <button class="btn btn-info" ng-click="getAppNamespaceInfo()">{{'Common.Search' | translate }}</button>
</div> </div>
</div> </div>
<div class="form-group" viv clform-group> <div class="form-group" viv clform-group>
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
AppNamespace信息</label> {{'Delete.AppNamespaceInfo' | translate }}</label>
<div class="col-sm-5"> <div class="col-sm-5">
<h5 ng-show="appNamespace.info" ng-bind="appNamespace.info"></h5> <h5 ng-show="appNamespace.info" ng-bind="appNamespace.info"></h5>
</div> </div>
...@@ -160,9 +166,8 @@ ...@@ -160,9 +166,8 @@
<div class="form-group"> <div class="form-group">
<div class="col-sm-offset-2 col-sm-9"> <div class="col-sm-offset-2 col-sm-9">
<button type="submit" class="btn btn-primary" <button type="submit" class="btn btn-primary"
ng-disabled="deleteAppNamespaceBtnDisabled" ng-disabled="deleteAppNamespaceBtnDisabled" ng-click="deleteAppNamespace()">
ng-click="deleteAppNamespace()"> {{'Delete.DeleteNamespace' | translate }}
删除AppNamespace
</button> </button>
</div> </div>
</div> </div>
...@@ -171,51 +176,57 @@ ...@@ -171,51 +176,57 @@
</section> </section>
<section class="panel-body text-center" ng-if="!isRootUser"> <section class="panel-body text-center" ng-if="!isRootUser">
<h4>当前页面只对Apollo管理员开放</h4> <h4>{{'Common.IsRootUserTips' | translate }}</h4>
</section> </section>
</div> </div>
</div> </div>
<div ng-include="'../views/common/footer.html'"></div>
<div ng-include="'../views/common/footer.html'"></div> <!-- jquery.js -->
<script src="../vendor/jquery.min.js" type="text/javascript"></script>
<!-- jquery.js --> <!--angular-->
<script src="../vendor/jquery.min.js" type="text/javascript"></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-toastr-1.4.1.tpls.min.js"></script>
<script src="../vendor/angular/loading-bar.min.js"></script>
<script src="vendor/angular/angular-cookies.min.js"></script>
<!--angular--> <script src="vendor/angular/angular-translate.2.18.1/angular-translate.min.js"></script>
<script src="../vendor/angular/angular.min.js"></script> <script src="vendor/angular/angular-translate.2.18.1/angular-translate-loader-static-files.min.js"></script>
<script src="../vendor/angular/angular-route.min.js"></script> <script src="vendor/angular/angular-translate.2.18.1/angular-translate-storage-cookie.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/loading-bar.min.js"></script>
<!--valdr--> <!--valdr-->
<script src="../vendor/valdr/valdr.min.js" type="text/javascript"></script> <script src="../vendor/valdr/valdr.min.js" type="text/javascript"></script>
<script src="../vendor/valdr/valdr-message.min.js" type="text/javascript"></script> <script src="../vendor/valdr/valdr-message.min.js" type="text/javascript"></script>
<!-- bootstrap.js --> <!-- bootstrap.js -->
<script src="../vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script> <script src="../vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
<script src="../vendor/lodash.min.js"></script> <script src="../vendor/lodash.min.js"></script>
<script src="../vendor/select2/select2.min.js" type="text/javascript"></script> <script src="../vendor/select2/select2.min.js" type="text/javascript"></script>
<!--biz--> <!--biz-->
<!--must import--> <!--must import-->
<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/UserService.js"></script>
<script type="application/javascript" src="../scripts/services/CommonService.js"></script> <script type="application/javascript" src="../scripts/services/CommonService.js"></script>
<script type="application/javascript" src="../scripts/services/PermissionService.js"></script> <script type="application/javascript" src="../scripts/services/PermissionService.js"></script>
<script type="application/javascript" src="../scripts/services/ClusterService.js"></script> <script type="application/javascript" src="../scripts/services/ClusterService.js"></script>
<script type="application/javascript" src="../scripts/services/NamespaceService.js"></script> <script type="application/javascript" src="../scripts/services/NamespaceService.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/PageCommon.js"></script> <script type="application/javascript" src="../scripts/PageCommon.js"></script>
<script type="application/javascript" src="../scripts/directive/directive.js"></script> <script type="application/javascript" src="../scripts/directive/directive.js"></script>
<script type="application/javascript" src="../scripts/valdr.js"></script> <script type="application/javascript" src="../scripts/valdr.js"></script>
<script type="application/javascript" src="../scripts/controller/DeleteAppClusterNamespaceController.js"></script> <script type="application/javascript" src="../scripts/controller/DeleteAppClusterNamespaceController.js"></script>
</body> </body>
</html> </html>
\ No newline at end of file
{
"Common.Title": "Apollo Configuration Center",
"Common.Ctrip": "Ctrip",
"Common.CtripDepartment": "Framework R&D Department",
"Common.Nav.ShowNavBar": "Display navigation bar",
"Common.Nav.HideNavBar": "Hidden navigation bar",
"Common.Nav.Help": "Help",
"Common.Nav.AdminTools": "Admin Tools",
"Common.Nav.UserManage": "User Management",
"Common.Nav.SystemRoleManage": "System Permission Management",
"Common.Nav.OpenMange": "Open Platform Authorized Management",
"Common.Nav.SystemConfig": "System Parameter",
"Common.Nav.DeleteApp-Cluster-Namespace": "Delete Apps, Clusters, AppNamespace",
"Common.Nav.SystemInfo": "System Information",
"Common.Nav.Logout": "Exit",
"Common.Department": "Department",
"Common.Cluster": "Cluster",
"Common.Environment": "Environment",
"Common.Email": "Mail",
"Common.AppId": "AppId",
"Common.Namespace": "Namespace",
"Common.AppName": "AppName",
"Common.AppOwner": "App Leader",
"Common.AppAdmin": "App Owner",
"Common.ClusterName": "Cluster Name",
"Common.Submit": "Submit",
"Common.Save": "Save",
"Common.Created": "Created",
"Common.CreateFailed": "Create failed",
"Common.Deleted": "Deleted",
"Common.DeleteFailed": "Delete failed",
"Common.ReturnToIndex": "Return",
"Common.Cancel": "Cancel",
"Common.Ok": "OK",
"Common.Search": "Query",
"Common.IsRootUser": "The current page is only available for Apollo administrator.",
"Common.PelaseChooseDepartment": "Please select department.",
"Common.PelaseChooseOwner": "Please select App leader.",
"Common.LoginExprieTips": "Your login has expired. Please refresh the page and try again.",
"Component.DeleteNamespace.Title": "Delete Namespace",
"Component.DeleteNamespace.PublicContent": "Deleting Namespace will cause the instance can't get the configuration of this Namespace. Are you sure you want to delete it?",
"Component.DeleteNamespace.PrivateContent": "Deleting a private Namespace will cause the instance can’t get the configuration of this Namespace, and the page will prompt the missing Namespace (unless the AppNamespace is deleted by Admin tool). Are you sure you want to delete it?",
"Component.GrayscalePublishRule.Title": "Edit Grayscale Rule",
"Component.GrayscalePublishRule.AppId": "Grayscale AppId",
"Component.GrayscalePublishRule.AcceptRule": "Grayscale Application Rule",
"Component.GrayscalePublishRule.AcceptPartInstance": "Applied to some instances",
"Component.GrayscalePublishRule.AcceptAllInstance": "Applied to all instances",
"Component.GrayscalePublishRule.IP": "Grayscale IP",
"Component.GrayscalePublishRule.AppIdFilterTips": "(The list of instances is filtered by the typed AppId automatically)",
"Component.GrayscalePublishRule.IpTips": "Can't find the IP you wanted? OK",
"Component.GrayscalePublishRule.EnterIp": "Enter IP manually",
"Component.GrayscalePublishRule.EnterIpTips": "Enter the list of IP, use ',' to separate the IP, and then click the Add button.",
"Component.GrayscalePublishRule.Add": "Add",
"Component.ConfigItem.Title": "Add Configuration",
"Component.ConfigItem.TitleTips": "(Kindly reminder: Configuration can be added in batches through text mode)",
"Component.ConfigItem.AddGrayscaleItem": "Add Grayscale Configuration",
"Component.ConfigItem.ModifyItem": "Modify Configuration",
"Component.ConfigItem.ItemKey": "Key",
"Component.ConfigItem.ItemValue": "Value",
"Component.ConfigItem.ItemValueTips": "Note: Hidden characters (Spaces, Newline, Tab) easily cause configuration errors. If you need to check hidden characters in Value, Click here",
"Component.ConfigItem.ItemValueShowDetection": "Check Hidden Characters",
"Component.ConfigItem.ItemValueNotHiddenChars": "No Hidden Characters",
"Component.ConfigItem.ItemComment": "Comment",
"Component.ConfigItem.ChooseCluster": "Select Cluster",
"Component.MergePublish.Title": "Full Release",
"Component.MergePublish.Tips": "Full release will merge the configuration of grayscale version into the main branch and release it.",
"Component.MergePublish.NextStep": "After full release, you hope",
"Component.MergePublish.DeleteGrayscale": "Delete Grayscale Version",
"Component.MergePublish.ReservedGrayscale": "Keep Grayscale Version",
"Component.Namespace.Branch.IsChanged": "Modified",
"Component.Namespace.Branch.ChangeUser": "Current Modifier",
"Component.Namespace.Branch.ContinueGrayscalePublish": "Continue to Release Grayscale",
"Component.Namespace.Branch.GrayscalePublish": "Grayscale Release",
"Component.Namespace.Branch.MergeToMasterAndPublish": "Merge to the main version and release the main version configuration",
"Component.Namespace.Branch.AllPublish": "Full Release",
"Component.Namespace.Branch.DiscardGrayscaleVesion": "Drop Grayscale Version",
"Component.Namespace.Branch.DiscardGrayscale": "Drop Grayscale",
"Component.Namespace.Branch.NoPermissionTips": "You are not the administrator of the project, and you do not have editing or releasing right for the Namespace. You cannot check the configuration.",
"Component.Namespace.Branch.Tab.Configuration": "Configuration",
"Component.Namespace.Branch.Tab.GrayscaleRule": "Grayscale Rule",
"Component.Namespace.Branch.Tab.GrayscaleInstance": "Grayscale Instance List",
"Component.Namespace.Branch.Tab.ChangeHistory": "Modify History",
"Component.Namespace.Branch.Body.Item": "Grayscale Configuration",
"Component.Namespace.Branch.Body.AddedItem": "New Grayscale Configuration",
"Component.Namespace.Branch.Body.PublishState": "Release Status",
"Component.Namespace.Branch.Body.ItemSort": "Sort",
"Component.Namespace.Branch.Body.ItemKey": "Key",
"Component.Namespace.Branch.Body.ItemMasterValue": "Value of Main Version",
"Component.Namespace.Branch.Body.ItemGrayscaleValue": "Grayscale value",
"Component.Namespace.Branch.Body.ItemComment": "Comments",
"Component.Namespace.Branch.Body.ItemLastModify": "Final Modifier",
"Component.Namespace.Branch.Body.ItemLastModifyTime": "Final Modified Time",
"Component.Namespace.Branch.Body.ItemOperator": "Operation",
"Component.Namespace.Branch.Body.ClickToSeeItemValue": "Click to check released values",
"Component.Namespace.Branch.Body.ItemNoPublish": "Unreleased",
"Component.Namespace.Branch.Body.ItemPublished": "Released",
"Component.Namespace.Branch.Body.ItemEffective": "Effective Configuration",
"Component.Namespace.Branch.Body.ClickToSee": "Click to View",
"Component.Namespace.Branch.Body.DeletedItem": "Deleted Configuration",
"Component.Namespace.Branch.Body.Delete": "Delete",
"Component.Namespace.Branch.Body.ChangedFormMaster": "Modify the configuration of the main version",
"Component.Namespace.Branch.Body.ModifedItem": "Modified Configuration",
"Component.Namespace.Branch.Body.Modify": "Modify",
"Component.Namespace.Branch.Body.AddedByGrayscale": "Specific Configuration for Grayscale Version",
"Component.Namespace.Branch.Body.Added": "New",
"Component.Namespace.Branch.Body.Op.Modify": "Modify",
"Component.Namespace.Branch.Body.Op.Delete": "Delete",
"Component.Namespace.MasterBranch.Body.Title": "Configuration of the main version",
"Component.Namespace.MasterBranch.Body.PublishState": "Release Status",
"Component.Namespace.MasterBranch.Body.ItemKey": "Key",
"Component.Namespace.MasterBranch.Body.ItemValue": "Value",
"Component.Namespace.MasterBranch.Body.ItemComment": "Comments",
"Component.Namespace.MasterBranch.Body.ItemLastModify": "Final Modifier",
"Component.Namespace.MasterBranch.Body.ItemLastModifyTime": "Final Modified Time",
"Component.Namespace.MasterBranch.Body.ItemOperator": "Operation",
"Component.Namespace.MasterBranch.Body.ClickToSeeItemValue": "Click to check released values",
"Component.Namespace.MasterBranch.Body.ItemNoPublish": "Unreleased",
"Component.Namespace.MasterBranch.Body.ItemEffective": "Effective Configuration",
"Component.Namespace.MasterBranch.Body.ItemPublished": "Released",
"Component.Namespace.MasterBranch.Body.AddedItem": "New Configuration",
"Component.Namespace.MasterBranch.Body.ModifyItem": "Modify the Grayscale Configuration",
"Component.Namespace.Branch.GrayScaleRule.NoPermissonTips": "You do not have the right to edit grayscale rule. Only those who have the right to modify or release namespace can edit grayscale rule. If you need to edit grayscale rule, please contact the project administrator to apply for the permission.",
"Component.Namespace.Branch.GrayScaleRule.AppId": "Grayscale AppId",
"Component.Namespace.Branch.GrayScaleRule.IpList": "Grayscale IP List",
"Component.Namespace.Branch.GrayScaleRule.Operator": "Operation",
"Component.Namespace.Branch.GrayScaleRule.ApplyToAllInstances": "ALL",
"Component.Namespace.Branch.GrayScaleRule.Modify": "Modify",
"Component.Namespace.Branch.GrayScaleRule.Delete": "Delete",
"Component.Namespace.Branch.GrayScaleRule.AddNewRule": "New Rules",
"Component.Namespace.Branch.Instance.RefreshList": "Refresh List",
"Component.Namespace.Branch.Instance.ItemToSee": "View Configuration",
"Component.Namespace.Branch.Instance.InstanceAppId": "App ID",
"Component.Namespace.Branch.Instance.InstanceClusterName": "Cluster Name",
"Component.Namespace.Branch.Instance.InstanceDataCenter": "Data Center",
"Component.Namespace.Branch.Instance.InstanceIp": "IP",
"Component.Namespace.Branch.Instance.InstanceGetItemTime": "Configure Getting Time",
"Component.Namespace.Branch.Instance.LoadingMore": "Refresh List",
"Component.Namespace.Branch.Instance.NoInstance": "No instance information",
"Component.Namespace.Branch.History.ItemType": "Type",
"Component.Namespace.Branch.History.ItemKey": "Key",
"Component.Namespace.Branch.History.ItemOldValue": "Old Value",
"Component.Namespace.Branch.History.ItemNewValue": "New Value",
"Component.Namespace.Branch.History.ItemComment": "Comment",
"Component.Namespace.Branch.History.NewAdded": "Add",
"Component.Namespace.Branch.History.Modifed": "Update",
"Component.Namespace.Branch.History.Deleted": "Delete",
"Component.Namespace.Branch.History.LoadingMore": "Loading more",
"Component.Namespace.Branch.History.NoHistory": "No Change History",
"Component.Namespace.Header.Title.Private": "Private",
"Component.Namespace.Header.Title.PrivateTips": "The configuration of private namespace ({{namespace.baseInfo.namespaceName}}) can be only read by clients whose AppId is {{appId}}",
"Component.Namespace.Header.Title.Public": "Public",
"Component.Namespace.Header.Title.PublicTips": "The configuration of namespace ({{namespace. baseInfo. namespaceName}}) can be read by any client.",
"Component.Namespace.Header.Title.Extend": "Relation",
"Component.Namespace.Header.Title.ExtendTips": "The configuration of namespace ({{namespace.baseInfo.namespaceName}}) will override the configuration of the public namespace, and the combined configuration can only be read by clients whose AppId is {{appId}}.",
"Component.Namespace.Header.Title.ExpandAndCollapse": "[Extension/Contraction]",
"Component.Namespace.Header.Title.Master": "Main Version",
"Component.Namespace.Header.Title.Grayscale": "Grayscale Version",
"Component.Namespace.Master.LoadNamespace": "Load Namespace",
"Component.Namespace.Master.LoadNamespaceTips": "Load Namespace",
"Component.Namespace.Master.Items.Changed": "Modified",
"Component.Namespace.Master.Items.ChangedUser": "Current Modifier",
"Component.Namespace.Master.Items.Pubish": "Release",
"Component.Namespace.Master.Items.PubishTips": "Release Configuration",
"Component.Namespace.Master.Items.Rollback": "Rollback",
"Component.Namespace.Master.Items.RollbackTips": "Rollback released configuration",
"Component.Namespace.Master.Items.PubishHistory": "Release History",
"Component.Namespace.Master.Items.PubishHistoryTips": "View the release history",
"Component.Namespace.Master.Items.Grant": "Authorize",
"Component.Namespace.Master.Items.GrantTips": "Configuration Change, Release Authority",
"Component.Namespace.Master.Items.Grayscale": "Grayscale",
"Component.Namespace.Master.Items.GrayscaleTips": "Create a test version",
"Component.Namespace.Master.Items.RequestPermission": "Apply for Configuring Authority",
"Component.Namespace.Master.Items.RequestPermissionTips": "You do not have any configuring authority. Please apply.",
"Component.Namespace.Master.Items.DeleteNamespace": "Delete Namespace",
"Component.Namespace.Master.Items.NoPermissionTips": "You are not the administrator of the project, and you do not have editing or releasing authority for the Namespace. You cannot check the configuration information.",
"Component.Namespace.Master.Items.ItemList": "Table",
"Component.Namespace.Master.Items.ItemListByText": "Text",
"Component.Namespace.Master.Items.ItemHistory": "Change History",
"Component.Namespace.Master.Items.ItemInstance": "Instance List",
"Component.Namespace.Master.Items.CopyText": "Copy Text",
"Component.Namespace.Master.Items.GrammarCheck": "Grammar Checking",
"Component.Namespace.Master.Items.CancelChanged": "Cancel the Change",
"Component.Namespace.Master.Items.Change": "Modify Configuration",
"Component.Namespace.Master.Items.SummitChanged": "Submit the Change",
"Component.Namespace.Master.Items.SortByKey": "Filter the configuration by key",
"Component.Namespace.Master.Items.FilterItem": "Filter configuration",
"Component.Namespace.Master.Items.SyncItemTips": "Synchronize configuration among environments",
"Component.Namespace.Master.Items.SyncItem": "Synchronize Configuration",
"Component.Namespace.Master.Items.DiffItemTips": "Compare the configuration among environments",
"Component.Namespace.Master.Items.DiffItem": "Compare Configuration",
"Component.Namespace.Master.Items.AddItem": "Add Configuration",
"Component.Namespace.Master.Items.Body.ItemsNoPublishedTips": "Tips: This namespace has never been released. Apollo client will not be able to get the configuration and record 404 log information. Please release it in time.",
"Component.Namespace.Master.Items.Body.FilterByKey": "Input key for filtering",
"Component.Namespace.Master.Items.Body.PublishState": "Release Status",
"Component.Namespace.Master.Items.Body.Sort": "Sort",
"Component.Namespace.Master.Items.Body.ItemKey": "Key",
"Component.Namespace.Master.Items.Body.ItemValue": "Value",
"Component.Namespace.Master.Items.Body.ItemComment": "Comment",
"Component.Namespace.Master.Items.Body.ItemLastModify": "Final Modifier",
"Component.Namespace.Master.Items.Body.ItemLastModifyTime": "Final Modify Time",
"Component.Namespace.Master.Items.Body.ItemOperator": "Operation",
"Component.Namespace.Master.Items.Body.NoPublish": "Unreleased",
"Component.Namespace.Master.Items.Body.NoPublishTitle": "Click to view released values",
"Component.Namespace.Master.Items.Body.NoPublishTips": "New configuration, no released value",
"Component.Namespace.Master.Items.Body.Published": "Released",
"Component.Namespace.Master.Items.Body.PublishedTitle": "Effective Configuration",
"Component.Namespace.Master.Items.Body.ClickToSee": "Click to view",
"Component.Namespace.Master.Items.Body.Grayscale": "Gray",
"Component.Namespace.Master.Items.Body.HaveGrayscale": "This configuration has grayscale configuration. Click to view the value of grayscale.",
"Component.Namespace.Master.Items.Body.NewAdded": "New",
"Component.Namespace.Master.Items.Body.NewAddedTips": "New Configuration",
"Component.Namespace.Master.Items.Body.Modifed": "Modify",
"Component.Namespace.Master.Items.Body.ModifedTips": "Modified Configuration",
"Component.Namespace.Master.Items.Body.Deleted": "Delete",
"Component.Namespace.Master.Items.Body.DeletedTips": "Deleted Configuration",
"Component.Namespace.Master.Items.Body.ModifyTips": "Modify",
"Component.Namespace.Master.Items.Body.DeleteTips": "Delete",
"Component.Namespace.Master.Items.Body.Link.Title": "Included Configuration",
"Component.Namespace.Master.Items.Body.Link.NoCoverLinkItem": "Excluded Configuration",
"Component.Namespace.Master.Items.Body.Public.Title": "Public Configuration",
"Component.Namespace.Master.Items.Body.Public.Published": "Released Configuration",
"Component.Namespace.Master.Items.Body.Public.NoPublish": "Unreleased Configuration",
"Component.Namespace.Master.Items.Body.Public.NoPublicNamespaceTips1": "Owner of the current public namespace",
"Component.Namespace.Master.Items.Body.Public.NoPublicNamespaceTips2": "No association with this namespace, please contact the owner of {{namespace. parentAppId}} to associate with this namespace in the {{namespace. parentAppId}} project.",
"Component.Namespace.Master.Items.Body.Public.NoPublished": "Unreleased Configuration",
"Component.Namespace.Master.Items.Body.Public.PubishedAndCover": "Override this configuration",
"Component.Namespace.Master.Items.Body.NoPublished.Title": "No public configuration",
"Component.Namespace.Master.Items.Body.NoPublished.PublishedValue": "Released Value",
"Component.Namespace.Master.Items.Body.NoPublished.NoPublishedValue": "Unreleased Value",
"Component.Namespace.Master.Items.Body.HistoryView.ItemType": "Type",
"Component.Namespace.Master.Items.Body.HistoryView.ItemKey": "Key",
"Component.Namespace.Master.Items.Body.HistoryView.ItemOldValue": "Old Value",
"Component.Namespace.Master.Items.Body.HistoryView.ItemNewValue": " New Value",
"Component.Namespace.Master.Items.Body.HistoryView.ItemComment": "Comment",
"Component.Namespace.Master.Items.Body.HistoryView.NewAdded": "Add",
"Component.Namespace.Master.Items.Body.HistoryView.Updated": "Update",
"Component.Namespace.Master.Items.Body.HistoryView.Deleted": "Delete",
"Component.Namespace.Master.Items.Body.HistoryView.LoadingMore": "Loading more",
"Component.Namespace.Master.Items.Body.HistoryView.NoHistory": "Unchanged History",
"Component.Namespace.Master.Items.Body.Instance.Tips": "Instance Instruction: Only show the Apollo instance that is visited last day",
"Component.Namespace.Master.Items.Body.Instance.UsedNewItem": "Instance of using the latest configuration",
"Component.Namespace.Master.Items.Body.Instance.NoUsedNewItem": "Instance of using non-latest configuration",
"Component.Namespace.Master.Items.Body.Instance.AllInstance": "All Instances",
"Component.Namespace.Master.Items.Body.Instance.RefreshList": "Refresh List",
"Component.Namespace.Master.Items.Body.Instance.ToSeeItem": "View Configuration",
"Component.Namespace.Master.Items.Body.Instance.LoadingMore": "Loading more",
"Component.Namespace.Master.Items.Body.Instance.ItemAppId": "App ID",
"Component.Namespace.Master.Items.Body.Instance.ItemCluster": "Cluster Name",
"Component.Namespace.Master.Items.Body.Instance.ItemDataCenter": "Data Center",
"Component.Namespace.Master.Items.Body.Instance.ItemIp": "IP",
"Component.Namespace.Master.Items.Body.Instance.ItemGetTime": "Configure getting time",
"Component.Namespace.Master.Items.Body.Instance.NoInstanceTips": "No Instance Information",
"Component.PublishDeny.Title": "Release Restriction",
"Component.PublishDeny.Tips1": "You can't release ~{{env}} Editing environment configuration and releasing must be for different people, please ask someone who has the releasing authority of this namespace to operate the release.~",
"Component.PublishDeny.Tips2": "(If it is non working time or special situations, you may release by clicking the <mark> Emergency Release </mark> button.)",
"Component.PublishDeny.EmergencyPublish": "Emergency Release",
"Component.PublishDeny.Close": "Close",
"Component.Publish.Title": "Release",
"Component.Publish.Tips": "(Only the released configuration will be accessed by the client, and this release will only work in the current environment: {{env}})",
"Component.Publish.Grayscale": "Grayscale Release",
"Component.Publish.GrayscaleTips": "(The configuration of grayscale releasing only works on the configuring instances in grayscale rules)",
"Component.Publish.AllPublish": "Full Release",
"Component.Publish.AllPublishTips": "(Full release configuration works on all instances)",
"Component.Publish.ToSeeChange": "View changes",
"Component.Publish.PublishedValue": "Released values",
"Component.Publish.Changes": "Changes",
"Component.Publish.Key": "Key",
"Component.Publish.NoPublishedValue": "Unreleased values",
"Component.Publish.ModifyUser": "Modifier",
"Component.Publish.ModifyTime": "Modified Time",
"Component.Publish.NewAdded": "New",
"Component.Publish.NewAddedTips": "New Added Configuration",
"Component.Publish.Modifed": "Modify",
"Component.Publish.ModifedTips": "Modified Configuration",
"Component.Publish.Deleted": "Delete",
"Component.Publish.DeletedTips": "Deleted Configuration",
"Component.Publish.MasterValue": "Main version value",
"Component.Publish.GrayValue": "Grayscale version value",
"Component.Publish.GrayPublishedValue": "Released grayscale version value",
"Component.Publish.GrayNoPublishedValue": "Unreleased grayscale version value",
"Component.Publish.ItemNoChange": "No change on configuration",
"Component.Publish.GrayItemNoChange": "No change on grayscale configuration",
"Component.Publish.NoGrayItems": "Configuration Item without Grayscale",
"Component.Publish.Release": "Release Name",
"Component.Publish.ReleaseComment": "Comment",
"Component.Publish.OpPublish": "Release",
"Component.Rollback.Goto": "Roll back to",
"Component.Rollback.Tips": "This operation will roll back to the previous released version, and the current version is invalid, but no impact on the modifying configuration. You can check the current version on the releasing history page",
"Component.Rollback.ItemType": "Type",
"Component.Rollback.ItemKey": "Key",
"Component.Rollback.RollbackBeforeValue": "Before rollback",
"Component.Rollback.RollbackAfterValue": "After rollback",
"Component.Rollback.Added": "Add",
"Component.Rollback.Modifed": "Update",
"Component.Rollback.Deleted": "Delete",
"Component.Rollback.NoChange": "No change on configuration",
"Component.Rollback.OpRollback": "Rollback",
"Component.ShowText.Title": "View",
"Login.Login": "Login",
"Login.UserNameOrPasswordIncorrect": "Incorrect username or password",
"Login.LogoutSuccessfully": "Logout successfully",
"Index.MyProject": "My project",
"Index.CreateProject": "Create project",
"Index.LoadingMore": "Loading more",
"Index.FavoriteItems": "Collected items",
"Index.Topping": "Top",
"Index.FavoriteTip": "You haven't collected any items yet. You can collect items on the project homepage.~",
"Index.RecentyViewedItems": "Recently browsed items",
"Index.GetCreateAppRoleFailed": "Failed to get the information of creating application permission",
"Index.Topped": "Top successfully",
"Index.CancelledFavorite": "Cancel collection successfully",
"Cluster.Tips.1": "By adding clusters, the same program can use different configuration in different clusters (such as different data centers)",
"Cluster.Tips.2": "If the different clusters use the same configuration, there is no need to create clusters",
"Cluster.Tips.3": "By default, Apollo reads IDC attributes in /opt/settings/server. properties(Linux) or C:\\opt\\settings\\server.properties(Windows) files on the machine as cluster names, such as SHAJQ (Jinqiao Data Center), SHAOY (Ouyang Data Center)",
"Cluster.Tips.4": "The cluster name created at here needs to be consistent with the IDC attribute in server.properties on the machine",
"Cluster.CreaterNameTips": "(Deploy clusters such as SHAJQ, SHAOY or customized clusters such as SHAJQ-xx, SHAJQ-yy)",
"Cluster.ChooseEnvironment": "Select the environment",
"Cluster.LoadingEnvironmentError": "Error in loading environment information",
"Cluster.ClusterCreated": "Create cluster successfully",
"Cluster.ClusterCreateFailed": "Fail to create cluster",
"Cluster.PleaseChooseEnvironment": "Please select the environment",
"Config.Title": "Apollo Configuration Center",
"Config.AppIdNotFound": "Nothingness",
"Config.ClickByCreate": "Click to create",
"Config.EnvList": "Environment List",
"Config.EnvListTips": "Manage the configuration of different environments and clusters by switching environments and clusters",
"Config.ProjectInfo": "Project Information",
"Config.ModifyBasicProjectInfo": "Modify the basic information of project",
"Config.Favorite": "Collection",
"Config.CancelFavorite": "Cancel Collection",
"Config.MissEnv": "Lack of environment",
"Config.MissNamespace": "Lack of Namespace",
"Config.ProjectManage": "Manage Project",
"Config.CreateAppMissEnv": "Fill in environment",
"Config.CreateAppMissNamespace": "Fill in Namespace",
"Config.AddCluster": "Add Cluster",
"Config.AddNamespace": "Add Namespace",
"Config.CurrentlyOperatorEnv": "Current operating environment",
"Config.DoNotRemindAgain": "No longer prompt",
"Config.Note": "Note",
"Config.ClusterIsDefualtTipContent": "All instances that do not belong to the'{{name}}'cluster will use the default cluster (current page) configuration, and those that belong to the'{{name}}' cluster will use the corresponding cluster configuration!",
"Config.ClusterIsCustomTipContent": "Instances belonging to the'{{name}}'cluster only use the configuration of the'{{name}}' cluster (the current page), and the default cluster configuration is used only when the corresponding namespace has not been published in the current cluster.",
"Config.HasNotPublishNamespace": "The following environment/cluster has unpublished configuration, the client can not get unpublished configuration, please publish in time.",
"Config.DeleteItem.DialogTitle": "Delete configuration",
"Config.DeleteItem.DialogContent": "You are deleting the configuration whose Key is <b>'{{config.key}} </b> Value is <b>'{{config.value}} </b>. <br> Are you sure you want to delete the configuration?",
"Config.PublishNoPermission.DialogTitle": "Release",
"Config.PublishNoPermission.DialogContent": "You do not have publishing permissions. ~Ask the Project Administrator'{{masterUsers}}'to assign publishing permissions.",
"Config.ModifyNoPermission.DialogTitle": "Application for Configuration Permission",
"Config.ModifyNoPermission.DialogContent": "Assign editing or publishing permissions to project administrator'{{masterUsers}}'",
"Config.MasterNoPermission.DialogTitle": "Application for Configuration Permission",
"Config.MasterNoPermission.DialogContent": "You are not a project administrator. Only project administrators have the right to add clusters and namespaces. For administrator privileges, ask the project administrator'{{masterUsers}}'to assign administrator privileges",
"Config.NamespaceLocked.DialogTitle": "Editorial constraints",
"Config.NamespaceLocked.DialogContent": "Currently namespace is being edited by'{{lockOwner}}', and a publication can only be modified by one person.",
"Config.RollbackAlert.DialogTitle": "Rollback",
"Config.RollbackAlert.DialogContent": "Are you sure you want to roll back?",
"Config.EmergencyPublishAlert.DialogTitle": "Emergency release",
"Config.EmergencyPublishAlert.DialogContent": "Are you sure it needs to be released urgently?",
"Config.DeleteBranch.DialogTitle": "Delete grayscale",
"Config.DeleteBranch.DialogContent": "Deleting gray level will lose the configuration of gray level. Are you sure you want to delete it?",
"Config.UpdateRuleTips.DialogTitle": "Update gray rule prompt",
"Config.UpdateRuleTips.DialogContent": "Grayscale rules are in effect, but it is found that grayscale versions have unpublished configurations that require manual grayscale publishing to take effect.",
"Config.MergeAndReleaseDeny.DialogTitle": "Full release",
"Config.MergeAndReleaseDeny.DialogContent": "The main version of namespace has unpublished configuration. Please publish the main version configuration first.",
"Config.GrayReleaseWithoutRulesTips.DialogTitle": "Missing gray rule prompt",
"Config.GrayReleaseWithoutRulesTips.DialogContent": "The grayscale version has not been configured with any grayscale rules. Please configure the grayscale rules.",
"Config.DeleteNamespaceDenyForMasterInstance.DialogTitle": "Delete Namespace warning information",
"Config.DeleteNamespaceDenyForMasterInstance.DialogContent": "It was found that <B>'{{delete Namespace Context. namespace. instancesCount}}'</b> instances were using Namespace ('{{delete Namespace Context. namespace. baseInfo. namespace Name}}'), and deleting Namespace would result in instances not getting configuration. <br> Please go to <ins> \"Instance List\"</ins> to confirm the instance information. If you confirm that the relevant instances are no longer using the Namespace configuration, you can contact the Apollo responsible person to delete the instance information (Instance Config) or wait for the instance to expire automatically 24 hours before deleting.",
"Config.DeleteNamespaceDenyForBranchInstance.DialogTitle": "Delete Namespace warning information",
"Config.DeleteNamespaceDenyForBranchInstance.DialogContent": "It was found that <B>'{{delete Namespace Context. namespace. branch. latest Release Instances. total}}'</b> instances were using the gray level version of Namespace ('{{delete Namespace Context. namespace. baseInfo. namespace Name}}') configuration, and deleting Namespace would result in instances not getting the configuration. <br> Please go to <ins> \"gray version\"=> \"instance list\"</ins> to confirm the instance information. If you confirm that the relevant instances are no longer using the Namespace configuration, you can contact the Apollo responsible person to delete the instance information (Instance Config) or wait for the instance to expire automatically 24 hours before deleting.",
"Config.DeleteNamespaceDenyForPublicNamespace.DialogTitle": "Delete Namespace Failure Tip",
"Config.DeleteNamespaceDenyForPublicNamespace.DialogContent": "Delete Namespace Failure Tip",
"Config.DeleteNamespaceDenyForPublicNamespace.PleaseEnterAppId": "Please enter appId",
"Config.SyntaxCheckFailed.DialogTitle": "Grammar Checking Error",
"Config.SyntaxCheckFailed.DialogContent": "Delete Namespace Failure Tip",
"Config.CreateBranchTips.DialogTitle": "Creating Grayscale Notice",
"Config.CreateBranchTips.DialogContent": "By creating gray level version, you can do gray level test for some configurations <br> gray level process as follows: <br> &nbsp; &nbsp; (1) create gray level version <br> &nbsp; &nbsp; (2) configure gray level configuration items <br> &nbsp; &nbsp; (3) configure gray level rules. If it is private namespace, it can be gray level according to the IP of client, if it is public name. Gray level <br> &nbsp; &nbsp; &nbsp; 4. Gray level publishing <br> gray level version has two final results: <b> full publishing and abandoning gray level </b> <br> <b> full publishing </b>: gray level configuration is combined with the main version and distributed, all clients will use the combined configuration <br> <b> abandon gray level </b>: remove gray. In degree version, all clients will use the configuration <br> of the main version: <br> &nbsp; &nbsp; &nbsp; 1. If the gray level version has been published, then the gray level rules will be changed immediately without the need for gray level publication again.",
"Config.ProjectMissEnvInfos": "Current project has environment missing, please click on the left side of the page to fill in the missing environment to fill in the data.",
"Config.ProjectMissNamespaceInfos": "There is a missing Namespace in the current environment. Please click \"Fill in Namespace\" on the left side of the page to fill in the data.",
"Config.SystemError": "System error, please try again or contact the system manager",
"Config.FavoriteSuccessfully": "Successful collection",
"Config.FavoriteFailed": "Collection failure",
"Config.CancelledFavorite": "Successful Cancellation of Collection",
"Config.CanceFavoriteFailed": "Failure to Cancel Collection",
"Config.GetrUserInfoFailed": "Failed to obtain user login information",
"Config.LoadingAllNamespaceError": "Error loading configuration information",
"Config.CanceFavoriteError": "Failure to Cancel Collection",
"Config.Deleted": "Successful deletion",
"Config.DeleteFailed": "Delete failed",
"Config.GrayscaleCreated": "Creating Grayscale Successfully",
"Config.GrayscaleCreateFailed": "Failed to create grayscale",
"Config.BranchDeleted": "Branch deletion succeeded",
"Config.BranchDeleteFailed": "Branch deletion failed",
"Config.DeleteNamespaceFailedTips": "The following applications are associated with this public Namespace and must delete all associated Namespace before deleting the public Namespace",
"Config.DeleteNamespaceNoPermissionFailedTitle": "Delete failed",
"Config.DeleteNamespaceNoPermissionFailedTips": "You do not have Project Administrator privileges. Only Administrators can delete Namespace. Please find Project Administrator [{{usres}}] to delete Namespace.",
"Delete.Title": "Delete applications, clusters, AppNamespace",
"Delete.DeleteApp": "Delete applications",
"Delete.DeleteAppTips": "(Because deleting applications has a large impact, system administrators are only allowed to delete them for the time being. Make sure that no client reads the configuration of the application before deleting it.)",
"Delete.AppIdTips": "(Please query application information before deleting)",
"Delete.AppInfo": "Application information",
"Delete.DeleteCluster": "Delete clusters",
"Delete.DeleteClusterTips": "(Because deleting the cluster has a large impact, only system administrators are allowed to delete it for the time being. Make sure that no client reads the configuration of the cluster before deleting it.)",
"Delete.EnvName": "Environment Name",
"Delete.ClusterNameTips": "(Please query application cluster information before deleting)",
"Delete.ClusterInfo": "Cluster information",
"Delete.DeleteNamespace": "Delete AppNamespace",
"Delete.DeleteNamespaceTips": "(Note that Namespace and AppNamespace in all environments will be deleted! If you just want to delete the Namespace of an environment, let the user delete it on the project page!",
"Delete.DeleteNamespaceTips2": "At present, users can delete the associated Namespace and private Namespace by themselves, but they can not delete the meta-information of AppNamespace. Because deleting AppNamespace has a large impact, it is only allowed to be deleted by system administrators for the time being. For public Namespace, it is necessary to ensure that the associated AppNamespace is not applied.",
"Delete.AppNamespaceName": "AppNamespace name",
"Delete.AppNamespaceNameTips": "(For namespaces of non-property types, add type suffixes, such as apollo.xml)",
"Delete.AppNamespaceInfo": "AppNamespace Information",
"Delete.IsRootUserTips": "The current page is open only to Apollo administrators",
"Delete.PleaseEnterAppId": "Please enter appId",
"Delete.AppIdNotFound": "AppId:'{{appId}}'does not exist!",
"Delete.AppInfoContent": "Application name:'{{appName}}'department:'{{departmentName}} ({{departmentId}})'person in charge:'{{ownerName}}'",
"Delete.ConfirmDeleteAppId": "Confirm to delete AppId:'{{appId}}'?",
"Delete.Deleted": "Successful deletion",
"Delete.PleaseEnterAppIdAndEnvAndCluster": "Enter appId, environment, and cluster name",
"Delete.ClusterInfoContent": "AppId:'{{appId}}'environment:'{{env}}' cluster name:'{{cluster Name}}'",
"Delete.ConfirmDeleteCluster": "Confirm to delete the cluster? AppId:'{{appId}}'environment:'{{env}}' cluster name:'{{cluster Name}}'",
"Delete.PleaseEnterAppIdAndNamespace": "Please enter appId and AppNamespace names",
"Delete.AppNamespaceInfoContent": "AppId:'{{appId}}'AppNamespace name:'{{namespace}}' isPublic:'{{isPublic}}'",
"Delete.ConfirmDeleteNamespace": "Confirm to delete AppNamespace and Namespace for all environments? AppId:'{{appId}}'environment:'All environments' AppNamespace name:'{{namespace}}'",
"Namespace.Title": "New Namespace",
"Namespace.UnderstandMore": "(Click to learn more about Namespace)",
"Namespace.Link.Tips1": "Applications can override the configuration of a common Namespace by associating a common namespace",
"Namespace.Link.Tips2": "If the application does not need to override the configuration of the common Namespace, then there is no need to associate the common Namespace",
"Namespace.CreatePublic.Tips1": "The configuration of the public Namespace can be read by any project",
"Namespace.CreatePublic.Tips2": "Configuration of common components can be achieved by creating a common Namespace, and the need for multiple applications to share the same configuration can be achieved.",
"Namespace.CreatePublic.Tips3": "If other applications need to cover the configuration of the public part, you can associate the public Namespace with other applications, and then configure the configuration that needs to be covered in the associated Namespace.",
"Namespace.CreatePublic.Tips4": "If other applications do not need to cover the configuration of common parts, then there is no need to associate common Namespace with other applications.",
"Namespace.CreatePrivate.Tips1": "The configuration of private Namespace can only be obtained by the application to which it belongs.",
"Namespace.CreatePrivate.Tips2": "Group management configuration can be achieved by creating a private Namespace",
"Namespace.CreatePrivate.Tips3": "The format of private Namespace can be xml, yml, yaml, json, txt. You can get the content of Namespace in non-property format through the ConfigFile interface in apollo-client.",
"Namespace.CreatePrivate.Tips4": "The 1.3.0 and above versions of apollo-client provide better support for yaml/yml. Config objects can be obtained directly through ConfigService.getConfig (\"someNamespace.yml\"), or through @EnableApolloConfig (\"someNamespace.yml\") or apollo.bootstrap.namespaces=Namespace.yml to inject YML configuration into Spring/Spring Boot. Go in",
"Namespace.CreateNamespcae": "Create Namespace",
"Namespace.AssociationPublicNamespcae": "Associated Public Namespace",
"Namespace.ChooseCluster": "Select Cluster",
"Namespace.NamespaceName": "Name",
"Namespace.AutoAddDepartmentPrefix": "Automatically add Department prefix",
"Namespace.AutoAddDepartmentPrefixTips": "(The name of a public Namespace needs to be globally unique, and adding a department prefix helps ensure global uniqueness)",
"Namespace.NamespcaeType": "type",
"Namespace.NamespcaeType.Public": "Public",
"Namespace.NamespcaeType.Private": "Private",
"Namespace.Remark": "Remarks",
"Namespace.Namespace": "Namespace",
"Namespace.PleaseChooseNamespace": "Please select Namespace",
"Namespace.LoadingPublicNamespaceError": "Loading common namespace errors",
"Namespace.LoadingAppInfoError": "Error loading App information",
"Namespace.PleaseChooseCluster": "Select Cluster",
"Namespace.ChecknamespaceNameLengthTip": "The namespace name should not be greater than 100 characters. Department prefix:'{{department Length}}'characters, name {{namespace Length}} characters",
"SericeConfig.Title": "Application Configuration",
"SericeConfig.Tips": "(Maintain Apollo PortalDB.ServerConfig table data, override configuration items if they already exist, or create configuration items. Configuration updates take effect automatically in a minute)",
"SericeConfig.Key": "Key",
"SericeConfig.KeyTips": "(Please query the configuration information before modifying the configuration)",
"SericeConfig.Value": "Value",
"SericeConfig.Comment": "Comment",
"SericeConfig.Saved": "Successful Preservation",
"SericeConfig.SaveFailed": "Save failed",
"SericeConfig.PleaseEnterKey": "Please enter key",
"SericeConfig.KeyNotExistsAndCreateTip": "Key:'{{key}}'does not exist. Click Save to create the configuration item.",
"SericeConfig.KeyExistsAndSaveTip": "Key:'{{key}}'already exists. Clicking Save will override the configuration item.",
"SystemInfo.Title": "system information",
"SystemInfo.SystemVersion": "System version",
"SystemInfo.Tips1": "The environment list comes from the <strong>apollo.portal.envs</strong> configuration in Apollo PortalDB.ServerConfig, and can be accessed to <a href=\"{{serverConfigUrl}}\"> system parameters </a> page configuration. More information can be referred to <a href=\"{{wikiUrl}}\"> distributed deployment guide </a> in <strong>apollo.portal.envs-a supportable environment list.</ strong> chapters.",
"SystemInfo.Tips2": "The Meta server address shows the meta server information for this environment configuration. For more information, please refer to the <strong> meta service information for configuring apollo-portal </strong> section in <a href=\"{{wikiUrl}}\"> Distributed Deployment Guide </a>.",
"SystemInfo.Active": "Active",
"SystemInfo.ActiveTips": "(Current environment status is abnormal, please check with the system information below and Check Health results of AdminService)",
"SystemInfo.MetaServerAddress": "Meta server address",
"SystemInfo.ConfigServices": "Config Services",
"SystemInfo.ConfigServices.Name": "Name",
"SystemInfo.ConfigServices.InstanceId": "Instance Id",
"SystemInfo.ConfigServices.HomePageUrl": "Home Page Url",
"SystemInfo.ConfigServices.CheckHealth": "Check Health",
"SystemInfo.NoConfigServiceTips": "No config service found!",
"SystemInfo.Check": "Check",
"SystemInfo.AdminServices": "Admin Services",
"SystemInfo.AdminServices.Name": "Name",
"SystemInfo.AdminServices.InstanceId": "Instance Id",
"SystemInfo.AdminServices.HomePageUrl": "Home Page Url",
"SystemInfo.AdminServices.CheckHealth": "Check Health",
"SystemInfo.NoAdminServiceTips": "No admin service found!",
"SystemInfo.IsRootUser": "The current page is open only to Apollo administrators",
"SystemRole.Title": "System privilege management",
"SystemRole.AddCreateAppRoleToUser": "Create application privileges for users",
"SystemRole.AddCreateAppRoleToUserTips": "(When role.create-application.enabled=true is set in system configurations, only super admin and those accounts with Create application privileges can create application)",
"SystemRole.ChooseUser": "User Selection",
"SystemRole.Add": "Add to",
"SystemRole.AuthorizedUser": "Users with privileges",
"SystemRole.ModifyAppAdminUser": "Modify Application Administrator Allocation Permissions",
"SystemRole.ModifyAppAdminUserTips": "(When role.manage-app-master.enabled=true is set in system configurations, only super admin and those accounts with application administrator allocation permissions can modify the application's administrators)",
"SystemRole.AppIdTips": "(Please query the application information first)",
"SystemRole.AppInfo": "Application information",
"SystemRole.AllowAppMasterAssignRole": "Allow this user to add Master as an administrator",
"SystemRole.DeleteAppMasterAssignRole": "Prohibit this user from adding Master as an administrator",
"SystemRole.IsRootUser": "The current page is open only to Apollo administrators",
"SystemRole.PleaseChooseUser": "Please select a user name",
"SystemRole.Added": "Added Successfully",
"SystemRole.AddFailed": "Failure to add",
"SystemRole.Deleted": "Successful deletion",
"SystemRole.DeleteFailed": "Delete failed",
"SystemRole.GetCanCreateProjectUsersError": "Error getting user list with creation project",
"SystemRole.PleaseEnterAppId": "Please enter appId",
"SystemRole.AppIdNotFound": "AppId:'{{appId}}'does not exist!",
"SystemRole.AppInfoContent": "Application name:'{{appName}}'department:'{{departmentName}} ({{departmentId}})'person in charge:'{{ownerName}}",
"SystemRole.DeleteMasterAssignRoleTips": "Verify that the user who deleted AppId:'{{appId}}':'{{userId}}'assigns permissions to the application administrator?",
"SystemRole.DeletedMasterAssignRoleTips": "Delete AppId:'{{appId}}'User:'{{userId}}' Allocate Application Administrator's Privileges Successfully",
"SystemRole.AllowAppMasterAssignRoleTips": "Verify that the user who added AppId:'{{appId}}':'{{userId}}'assigns the permissions of the application administrator?",
"SystemRole.AllowedAppMasterAssignRoleTips": "Users who add AppId:'{{appId}}':'{{userId}}'Allocate Application Administrator's Privileges Successfully",
"UserMange.Title": "user management",
"UserMange.TitleTips": "(Only valid for the default Spring Security simple authentication method: - Dapollo_profile = github, auth)",
"UserMange.UserName": "User name",
"UserMange.UserNameTips": "If the user name entered does not exist, create a new one. If it already exists, it is updated.",
"UserMange.Pwd": "Password",
"UserMange.Email": "mailbox",
"UserMange.Created": "Create User Success",
"UserMange.CreateFailed": "Failed to create user",
"Open.Manage.Title": "Open Platform",
"Open.Manage.CreateThirdApp": "Creating third-party applications",
"Open.Manage.CreateThirdAppTips": "(Note: Third-party applications can manage configuration through Apollo Open Platform)",
"Open.Manage.ThirdAppId": "Third party application ID",
"Open.Manage.ThirdAppIdTips": "(Before creating, please check if third-party applications have been applied for)",
"Open.Manage.ThirdAppName": "Third party application name",
"Open.Manage.ThirdAppNameTips": "(Suggested format xx-yy-zz example: apollo-server)",
"Open.Manage.ProjectOwner": "Project Leader",
"Open.Manage.Create": "Establish",
"Open.Manage.GrantPermission": "Empowerment",
"Open.Manage.GrantPermissionTips": "Namespace level permissions include modifying and publishing Namespace. Application level permissions include creating Namespace, modifying or publishing any Namespace under an application.",
"Open.Manage.Token": "Token",
"Open.Manage.ManagedAppId": "Managed AppId",
"Open.Manage.ManagedNamespace": "Managed Namespace",
"Open.Manage.ManagedNamespaceTips": "(For namespaces of non-property types, add type suffixes, such as apollo.xml)",
"Open.Manage.GrantType": "Authorization type",
"Open.Manage.GrantType.Namespace": "Namespace",
"Open.Manage.GrantType.App": "App",
"Open.Manage.GrantEnv": "Environmental Science",
"Open.Manage.GrantEnvTips": "(If you don't select, all environments have permissions. If you prompt Namespace's role does not exist, open the authorization page of the Namespace to trigger the privilege initialization action.)",
"Open.Manage.PleaseEnterAppId": "Please enter appId",
"Open.Manage.AppNotCreated": "App ('{{appId}}') was not created, please create it first",
"Open.Manage.GrantSuccessfully": "Empowerment Success",
"Open.Manage.GrantFailed": "Failure in empowerment",
"Namespace.Role.Title": "Authority Management",
"Namespace.Role.GrantModifyTo": "Right to amend",
"Namespace.Role.GrantModifyTo2": "(Configuration can be modified)",
"Namespace.Role.AllEnv": "All environments",
"Namespace.Role.GrantPubishTo": "Right to issue",
"Namespace.Role.GrantPubishTo2": "(You can publish configurations)",
"Namespace.Role.Add": "Add to",
"Namespace.Role.NoPermisson": "You do not have permission yo!",
"Namespace.Role.InitNamespacePermissionError": "Error initializing authorization",
"Namespace.Role.GetEnvGrantUserError": "Authorized user error loading'{{env}}'",
"Namespace.Role.GetGrantUserError": "Error loading authorized user",
"Namespace.Role.PleaseChooseUser": "Please select the user",
"Namespace.Role.Added": "Added Successfully",
"Namespace.Role.AddFailed": "Failure to add",
"Namespace.Role.Deleted": "Successful deletion",
"Namespace.Role.DeleteFailed": "Delete failed",
"Config.Sync.Title": "Synchronization Configuration",
"Config.Sync.FistStep": "(Step 1: Select Synchronization Information)",
"Config.Sync.SecondStep": "(Step 2: Check Diff)",
"Config.Sync.PreviousStep": "The last step",
"Config.Sync.NextStep": "Next step",
"Config.Sync.Sync": "synchronization",
"Config.Sync.Tips": "Tips",
"Config.Sync.Tips1": "Configuration between multiple environments and clusters can be maintained by synchronous configuration function",
"Config.Sync.Tips2": "It should be noted that the application will not take effect until it is released after synchronization.",
"Config.Sync.SyncNamespace": "Synchronized Namespace",
"Config.Sync.SyncToCluster": "Synchronize to that cluster",
"Config.Sync.NeedToSyncItem": "Configuration requiring synchronization",
"Config.Sync.SortByLastModifyTime": "Filter by last update time",
"Config.Sync.BeginTime": "start time",
"Config.Sync.EndTime": "Ending time",
"Config.Sync.Filter": "filter",
"Config.Sync.Rest": "Reset",
"Config.Sync.ItemKey": "Key",
"Config.Sync.ItemValue": "Value",
"Config.Sync.ItemCreateTime": "Create Time",
"Config.Sync.ItemUpdateTime": "Update Time",
"Config.Sync.NoNeedSyncItem": "No updated configuration",
"Config.Sync.IgnoreSync": "Ignore synchronization",
"Config.Sync.Step2Type": "Type",
"Config.Sync.Step2Key": "Key",
"Config.Sync.Step2SyncBefore": "Synchronization front",
"Config.Sync.Step2SyncAfter": "After Synchronization",
"Config.Sync.Step2Comment": "Comment",
"Config.Sync.Step2Operator": "operation",
"Config.Sync.NewAdd": "Newly added",
"Config.Sync.NoSyncItem": "Asynchronize the configuration",
"Config.Sync.Delete": "delete",
"Config.Sync.Update": "To update",
"Config.Sync.SyncSuccessfully": "Synchronization success!",
"Config.Sync.SyncFailed": "Synchronization failed!",
"Config.Sync.LoadingItemsError": "Error loading configuration",
"Config.Sync.PleaseChooseNeedSyncItems": "Please select the configuration that needs synchronization",
"Config.Sync.PleaseChooseCluster": "Select Cluster",
"Config.History.Title": "Publish History",
"Config.History.MasterVersionPublish": "Main version release",
"Config.History.MasterVersionRollback": "Main version rollback",
"Config.History.GrayscaleOperator": "Grayscale operation",
"Config.History.PublishHistory": "Publish History",
"Config.History.OperationType0": "General release",
"Config.History.OperationType1": "Rollback",
"Config.History.OperationType2": "Grayscale Publishing",
"Config.History.OperationType3": "Updating gray rules",
"Config.History.OperationType4": "Full gray level Publishing",
"Config.History.OperationType5": "Grayscale Publishing (Main Version Publishing)",
"Config.History.OperationType6": "Grayscale publishing (main version rollback)",
"Config.History.OperationType7": "Abandon grayscale",
"Config.History.OperationType8": "Delete grayscale (full release)",
"Config.History.UrgentPublish": "Emergency release",
"Config.History.LoadingMore": "Load more",
"Config.History.ChangedItem": "Changed configuration",
"Config.History.AllItem": "Full configuration",
"Config.History.ChangeType": "Type",
"Config.History.ChangeKey": "Key",
"Config.History.ChangeValue": "Value",
"Config.History.ChangeOldValue": "Old Value",
"Config.History.ChangeNewValue": "New Value",
"Config.History.ChangeTypeNew": "Newly added",
"Config.History.ChangeTypeModify": "modify",
"Config.History.ChangeTypeDelete": "delete",
"Config.History.NoChange": "No configuration changes",
"Config.History.NoItem": "No configuration",
"Config.History.GrayscaleRule": "Grayscale rule",
"Config.History.GrayscaleAppId": "Grayscale AppId",
"Config.History.GrayscaleIp": "Grayscale IP",
"Config.History.NoGrayscaleRule": "Grayless rule",
"Config.History.NoPermissonTips": "You are not the administrator of the project, and you do not have editing or publishing rights for the Namespace. You cannot view the publishing history.",
"Config.History.NoPublishHistory": "No release of historical information",
"Config.History.LoadingHistoryError": "No release of historical information",
"Config.Diff.Title": "Comparative configuration",
"Config.Diff.FirstStep": "(Step 1: Select comparative information)",
"Config.Diff.SecondStep": "(Step 2: View the differential configuration)",
"Config.Diff.PreviousStep": "The last step",
"Config.Diff.NextStep": "Next step",
"Config.Diff.TipsTitle": "Tips",
"Config.Diff.Tips": "By comparing configuration functions, you can see configuration differences between multiple environments and clusters",
"Config.Diff.DiffCluster": "Clusters to be compared",
"Config.Diff.HasDiffComment": "Compare notes or not",
"Config.Diff.PleaseChooseTwoCluster": "Please select at least two clusters",
"App.CreateProject": "Create a project",
"App.AppIdTips": "(Apply unique identifiers)",
"App.AppNameTips": "(建议格式 xx-yy-zz 例:apollo-server)",
"App.AppOwnerTips": "(After enabling the application administrator allocation restrictions, the application manager and project administrator default to this account, not optional)",
"App.AppAdminTips1": "(The application manager defaults to project administrator privileges.",
"App.AppAdminTips2": "Project administrators can create Namespace, cluster, and assign user privileges)",
"App.Setting.Title": "project management",
"App.Setting.Admin": "Administrators",
"App.Setting.AdminTips": "(Project administrators have the following permissions: 1. Create Namespace 2. Create clusters 3. Manage projects, Namespace permissions)",
"App.Setting.Add": "Add to",
"App.Setting.BasicInfo": "Essential information",
"App.Setting.ProjectName": "entry name",
"App.Setting.ProjectNameTips": "(Suggested format xx-yy-zz example: apollo-server)",
"App.Setting.ProjectOwner": "Project Leader",
"App.Setting.Modify": "Modify project information",
"App.Setting.Cancel": "Cancel modification",
"App.Setting.NoPermissonTips": "You do not have permission to operate, please find [{{users}}] open permission",
"App.Setting.DeleteAdmin": "Delete Administrator",
"App.Setting.CanNotDeleteAllAdmin": "Cannot delete all administrators",
"App.Setting.PleaseChooseUser": "Please select the user",
"App.Setting.Added": "Added Successfully",
"App.Setting.AddFailed": "添加失败",
"App.Setting.Deleted": "删除成功",
"App.Setting.DeleteFailed": "Delete failed",
"App.Setting.Modifed": "Successful revision",
"Valdr.App.AppId.Size": "AppId cannot be longer than 32 characters",
"Valdr.App.AppId.Required": "AppId cannot be empty",
"Valdr.App.appName.Size": "The application name cannot be longer than 128 characters",
"Valdr.App.appName.Required": "Application name cannot be empty",
"Valdr.Cluster.ClusterName.Size": "Cluster names cannot be longer than 32 characters",
"Valdr.Cluster.ClusterName.Required": "Cluster name cannot be empty",
"Valdr.AppNamespace.NamespaceName.Size": "Namespace name cannot be longer than 100 characters",
"Valdr.AppNamespace.NamespaceName.Required": "Namespace name cannot be empty",
"Valdr.AppNamespace.Comment.Size": "Note length should not exceed 64 characters",
"Valdr.Item.Key.Size": "Key cannot be longer than 128 characters",
"Valdr.Item.Key.Required": "Key can't be empty",
"Valdr.Item.Comment.Size": "Note length should not exceed 64 characters",
"Valdr.Release.ReleaseName.Size": "Release Name cannot be longer than 64 characters",
"Valdr.Release.ReleaseName.Required": "Release Name cannot be empty",
"Valdr.Release.Comment.Size": "Note length should not exceed 64 characters",
"ApolloConfirmDialog.DefaultConfirmBtnName": "confirm",
"ApolloConfirmDialog.SearchPlaceHolder": "Search items (AppId, project name)",
"RulesModal.ChooseInstances": "Select from the list of instances",
"RulesModal.InvalidIp": "Illegal IP Address:'{{ip}}'",
"RulesModal.GrayscaleAppIdCanNotBeNull": "Grayscale AppId cannot be empty",
"RulesModal.AppIdExistsRule": "There are already rules for AppId='{{appId}}'",
"RulesModal.IpListCanNotBeNull": "IP list cannot be empty",
"ItemModal.KeyExists": "Key='{{key}}' already exists",
"ItemModal.AddedTips": "Successful addition. Publish if necessary",
"ItemModal.AddFailed": "Failure to add",
"ItemModal.PleaseChooseCluster": "Select Cluster",
"ItemModal.ModifedTips": "Successful update, if necessary, please publish",
"ItemModal.ModifyFailed": "Update failed",
"ItemModal.Tabs": "Tab character",
"ItemModal.NewLine": "Newline character",
"ItemModal.Space": "Blank space",
"ApolloNsPanel.LoadingHistoryError": "Error loading and modifying history",
"ApolloNsPanel.LoadingGrayscaleError": "Error loading and modifying history",
"ApolloNsPanel.Deleted": "Successful deletion",
"ApolloNsPanel.GrayscaleModifed": "Successful updating of gray rules",
"ApolloNsPanel.GrayscaleModifyFailed": "Failure to update gray rules",
"ApolloNsPanel.ModifedTips": "Updates are successful. Publish them to take effect",
"ApolloNsPanel.ModifyFailed": "Update failed",
"ApolloNsPanel.GrammarIsright": "Grammar is correct",
"ReleaseModal.Published": "Publish suceesssful",
"ReleaseModal.PublishFailed": "Publish failed",
"ReleaseModal.GrayscalePublished": "Successful Grayscale Release",
"ReleaseModal.GrayscalePublishFailed": "Grayscale publish failed",
"ReleaseModal.AllPublished": "Full publish successful",
"ReleaseModal.AllPublishFailed": "Full publish failed",
"Rollback.NoRollbackList": "No published history to rollback",
"Rollback.RollbackSuccessfully": "Rollback successful",
"Rollback.RollbackFailed": "Rollback failed"
}
\ No newline at end of file
{
"Common.Title": "Apollo配置中心",
"Common.Ctrip": "携程",
"Common.CtripDepartment": "框架研发部",
"Common.Nav.ShowNavBar": "显示导航栏",
"Common.Nav.HideNavBar": "隐藏导航栏",
"Common.Nav.Help": "帮助",
"Common.Nav.AdminTools": "管理员工具",
"Common.Nav.UserManage": "用户管理",
"Common.Nav.SystemRoleManage": "系统权限管理",
"Common.Nav.OpenMange": "开放平台授权管理",
"Common.Nav.SystemConfig": "系统参数",
"Common.Nav.DeleteApp-Cluster-Namespace": "删除应用、集群、AppNamespace",
"Common.Nav.SystemInfo": "系统信息",
"Common.Nav.Logout": "退出",
"Common.Department": "部门",
"Common.Cluster": "集群",
"Common.Environment": "环境",
"Common.Email": "邮箱",
"Common.AppId": "AppId",
"Common.Namespace": "Namespace",
"Common.AppName": "应用名称",
"Common.AppOwner": "应用负责人",
"Common.AppAdmin": "项目管理员",
"Common.ClusterName": "集群名称",
"Common.Submit": "提交",
"Common.Save": "保存",
"Common.Created": "创建成功",
"Common.CreateFailed": "创建失败",
"Common.Deleted": "删除成功",
"Common.DeleteFailed": "删除失败",
"Common.ReturnToIndex": "返回到项目首页",
"Common.Cancel": "取消",
"Common.Ok": "确定",
"Common.Search": "查询",
"Common.IsRootUser": "当前页面只对Apollo管理员开放",
"Common.PelaseChooseDepartment": "请选择部门",
"Common.PelaseChooseOwner": "请选择应用负责人",
"Common.LoginExprieTips": "您的登录信息已过期,请刷新页面后重试",
"Component.DeleteNamespace.Title": "删除Namespace",
"Component.DeleteNamespace.PublicContent": "删除Namespace将导致实例获取不到此Namespace的配置,确定要删除吗?",
"Component.DeleteNamespace.PrivateContent": "删除私有Namespace将导致实例获取不到此Namespace的配置,且页面会提示缺失Namespace(除非使用管理员工具删除AppNamespace),确定要删除吗?",
"Component.GrayscalePublishRule.Title": "编辑灰度规则",
"Component.GrayscalePublishRule.AppId": "灰度的AppId",
"Component.GrayscalePublishRule.AcceptRule": "灰度应用规则",
"Component.GrayscalePublishRule.AcceptPartInstance": "应用到部分实例",
"Component.GrayscalePublishRule.AcceptAllInstance": "应用到所有的实例",
"Component.GrayscalePublishRule.IP": "灰度的IP",
"Component.GrayscalePublishRule.AppIdFilterTips": "(实例列表会根据输入的AppId自动过滤)",
"Component.GrayscalePublishRule.IpTips": "没找到你想要的IP?可以",
"Component.GrayscalePublishRule.EnterIp": "手动输入IP",
"Component.GrayscalePublishRule.EnterIpTips": "输入IP列表,英文逗号隔开,输入完后点击添加按钮",
"Component.GrayscalePublishRule.Add": "添加",
"Component.ConfigItem.Title": "添加配置项",
"Component.ConfigItem.TitleTips": "(温馨提示: 可以通过文本模式批量添加配置)",
"Component.ConfigItem.AddGrayscaleItem": "添加灰度配置项",
"Component.ConfigItem.ModifyItem": "修改配置项",
"Component.ConfigItem.ItemKey": "Key",
"Component.ConfigItem.ItemValue": "Value",
"Component.ConfigItem.ItemValueTips": "注意: 隐藏字符(空格、换行符、制表符Tab)容易导致配置出错,如果需要检测Value中隐藏字符,请点击",
"Component.ConfigItem.ItemValueShowDetection": "检测隐藏字符",
"Component.ConfigItem.ItemValueNotHiddenChars": "无隐藏字符",
"Component.ConfigItem.ItemComment": "Comment",
"Component.ConfigItem.ChooseCluster": "选择集群",
"Component.MergePublish.Title": "全量发布",
"Component.MergePublish.Tips": "全量发布将会把灰度版本的配置合并到主分支,并发布。",
"Component.MergePublish.NextStep": "全量发布后,您希望",
"Component.MergePublish.DeleteGrayscale": "删除灰度版本",
"Component.MergePublish.ReservedGrayscale": "保留灰度版本",
"Component.Namespace.Branch.IsChanged": "有修改",
"Component.Namespace.Branch.ChangeUser": "当前修改者",
"Component.Namespace.Branch.ContinueGrayscalePublish": "继续灰度发布",
"Component.Namespace.Branch.GrayscalePublish": "灰度发布",
"Component.Namespace.Branch.MergeToMasterAndPublish": "合并到主版本并发布主版本配置",
"Component.Namespace.Branch.AllPublish": "全量发布",
"Component.Namespace.Branch.DiscardGrayscaleVesion": "废弃灰度版本",
"Component.Namespace.Branch.DiscardGrayscale": "放弃灰度",
"Component.Namespace.Branch.NoPermissionTips": "您不是该项目的管理员,也没有该Namespace的编辑或发布权限,无法查看配置信息。",
"Component.Namespace.Branch.Tab.Configuration": "配置",
"Component.Namespace.Branch.Tab.GrayscaleRule": "灰度规则",
"Component.Namespace.Branch.Tab.GrayscaleInstance": "灰度实例列表",
"Component.Namespace.Branch.Tab.ChangeHistory": "更改历史",
"Component.Namespace.Branch.Body.Item": "灰度的配置",
"Component.Namespace.Branch.Body.AddedItem": "新增灰度配置",
"Component.Namespace.Branch.Body.PublishState": "发布状态",
"Component.Namespace.Branch.Body.ItemSort": "排序",
"Component.Namespace.Branch.Body.ItemKey": "Key",
"Component.Namespace.Branch.Body.ItemMasterValue": "主版本的值",
"Component.Namespace.Branch.Body.ItemGrayscaleValue": "灰度的值",
"Component.Namespace.Branch.Body.ItemComment": "备注",
"Component.Namespace.Branch.Body.ItemLastModify": "最后修改人",
"Component.Namespace.Branch.Body.ItemLastModifyTime": "最后修改时间",
"Component.Namespace.Branch.Body.ItemOperator": "操作",
"Component.Namespace.Branch.Body.ClickToSeeItemValue": "点击查看已发布的值",
"Component.Namespace.Branch.Body.ItemNoPublish": "未发布",
"Component.Namespace.Branch.Body.ItemPublished": "已发布",
"Component.Namespace.Branch.Body.ItemEffective": "已生效的配置",
"Component.Namespace.Branch.Body.ClickToSee": "点击查看",
"Component.Namespace.Branch.Body.DeletedItem": "删除的配置",
"Component.Namespace.Branch.Body.Delete": "删",
"Component.Namespace.Branch.Body.ChangedFormMaster": "修改主版本的配置",
"Component.Namespace.Branch.Body.ModifedItem": "修改的配置",
"Component.Namespace.Branch.Body.Modify": "改",
"Component.Namespace.Branch.Body.AddedByGrayscale": "灰度版本特有的配置",
"Component.Namespace.Branch.Body.Added": "新",
"Component.Namespace.Branch.Body.Op.Modify": "修改",
"Component.Namespace.Branch.Body.Op.Delete": "删除",
"Component.Namespace.MasterBranch.Body.Title": "主版本的配置",
"Component.Namespace.MasterBranch.Body.PublishState": "发布状态",
"Component.Namespace.MasterBranch.Body.ItemKey": "Key",
"Component.Namespace.MasterBranch.Body.ItemValue": "Value",
"Component.Namespace.MasterBranch.Body.ItemComment": "备注",
"Component.Namespace.MasterBranch.Body.ItemLastModify": "最后修改人",
"Component.Namespace.MasterBranch.Body.ItemLastModifyTime": "最后修改时间",
"Component.Namespace.MasterBranch.Body.ItemOperator": "操作",
"Component.Namespace.MasterBranch.Body.ClickToSeeItemValue": "点击查看已发布的值",
"Component.Namespace.MasterBranch.Body.ItemNoPublish": "未发布",
"Component.Namespace.MasterBranch.Body.ItemEffective": "已生效的配置",
"Component.Namespace.MasterBranch.Body.ItemPublished": "已发布",
"Component.Namespace.MasterBranch.Body.AddedItem": "新增的配置",
"Component.Namespace.MasterBranch.Body.ModifyItem": "修改此灰度配置",
"Component.Namespace.Branch.GrayScaleRule.NoPermissonTips": "您没有权限编辑灰度规则, 具有namespace修改权或者发布权的人员才可以编辑灰度规则. 如需要编辑灰度规则,请找项目管理员申请权限.",
"Component.Namespace.Branch.GrayScaleRule.AppId": "灰度的AppId",
"Component.Namespace.Branch.GrayScaleRule.IpList": "灰度的IP列表",
"Component.Namespace.Branch.GrayScaleRule.Operator": "操作",
"Component.Namespace.Branch.GrayScaleRule.ApplyToAllInstances": "ALL",
"Component.Namespace.Branch.GrayScaleRule.Modify": "修改",
"Component.Namespace.Branch.GrayScaleRule.Delete": "删除",
"Component.Namespace.Branch.GrayScaleRule.AddNewRule": "新增规则",
"Component.Namespace.Branch.Instance.RefreshList": "刷新列表",
"Component.Namespace.Branch.Instance.ItemToSee": "查看配置",
"Component.Namespace.Branch.Instance.InstanceAppId": "App ID",
"Component.Namespace.Branch.Instance.InstanceClusterName": "Cluster Name",
"Component.Namespace.Branch.Instance.InstanceDataCenter": "Data Center",
"Component.Namespace.Branch.Instance.InstanceIp": "IP",
"Component.Namespace.Branch.Instance.InstanceGetItemTime": "配置获取时间",
"Component.Namespace.Branch.Instance.LoadingMore": "刷新列表",
"Component.Namespace.Branch.Instance.NoInstance": "无实例信息",
"Component.Namespace.Branch.History.ItemType": "Type",
"Component.Namespace.Branch.History.ItemKey": "Key",
"Component.Namespace.Branch.History.ItemOldValue": "Old Value",
"Component.Namespace.Branch.History.ItemNewValue": "New Value",
"Component.Namespace.Branch.History.ItemComment": "Comment",
"Component.Namespace.Branch.History.NewAdded": "新增",
"Component.Namespace.Branch.History.Modifed": "更新",
"Component.Namespace.Branch.History.Deleted": "删除",
"Component.Namespace.Branch.History.LoadingMore": "加载更多",
"Component.Namespace.Branch.History.NoHistory": "无更改历史",
"Component.Namespace.Header.Title.Private": "私有",
"Component.Namespace.Header.Title.PrivateTips": "私有namespace({{namespace.baseInfo.namespaceName}})的配置只能被AppId为{{appId}}的客户端读取到",
"Component.Namespace.Header.Title.Public": "公共",
"Component.Namespace.Header.Title.PublicTips": "namespace({{namespace.baseInfo.namespaceName}})的配置能被任何客户端读取到",
"Component.Namespace.Header.Title.Extend": "关联",
"Component.Namespace.Header.Title.ExtendTips": "namespace({{namespace.baseInfo.namespaceName}})的配置将会覆盖公共namespace的配置, 且合并之后的配置只能被AppId为{{appId}}的客户端读取到",
"Component.Namespace.Header.Title.ExpandAndCollapse": "[展开/收缩]",
"Component.Namespace.Header.Title.Master": "主版本",
"Component.Namespace.Header.Title.Grayscale": "灰度版本",
"Component.Namespace.Master.LoadNamespace": "加载Namespace",
"Component.Namespace.Master.LoadNamespaceTips": "加载Namespace",
"Component.Namespace.Master.Items.Changed": "有修改",
"Component.Namespace.Master.Items.ChangedUser": "当前修改者",
"Component.Namespace.Master.Items.Pubish": "发布",
"Component.Namespace.Master.Items.PubishTips": "发布配置",
"Component.Namespace.Master.Items.Rollback": "回滚",
"Component.Namespace.Master.Items.RollbackTips": "回滚已发布配置",
"Component.Namespace.Master.Items.PubishHistory": "发布历史",
"Component.Namespace.Master.Items.PubishHistoryTips": "查看发布历史",
"Component.Namespace.Master.Items.Grant": "授权",
"Component.Namespace.Master.Items.GrantTips": "配置修改、发布权限",
"Component.Namespace.Master.Items.Grayscale": "灰度",
"Component.Namespace.Master.Items.GrayscaleTips": "创建测试版本",
"Component.Namespace.Master.Items.RequestPermission": "申请配置权限",
"Component.Namespace.Master.Items.RequestPermissionTips": "您没有任何配置权限,请申请",
"Component.Namespace.Master.Items.DeleteNamespace": "删除Namespace",
"Component.Namespace.Master.Items.NoPermissionTips": "您不是该项目的管理员,也没有该Namespace的编辑或发布权限,无法查看配置信息。",
"Component.Namespace.Master.Items.ItemList": "表格",
"Component.Namespace.Master.Items.ItemListByText": "文本",
"Component.Namespace.Master.Items.ItemHistory": "更改历史",
"Component.Namespace.Master.Items.ItemInstance": "实例列表",
"Component.Namespace.Master.Items.CopyText": "复制文本",
"Component.Namespace.Master.Items.GrammarCheck": "语法检查",
"Component.Namespace.Master.Items.CancelChanged": "取消修改",
"Component.Namespace.Master.Items.Change": "修改配置",
"Component.Namespace.Master.Items.SummitChanged": "提交修改",
"Component.Namespace.Master.Items.SortByKey": "按Key过滤配置",
"Component.Namespace.Master.Items.FilterItem": "过滤配置",
"Component.Namespace.Master.Items.SyncItemTips": "同步各环境间配置",
"Component.Namespace.Master.Items.SyncItem": "同步配置",
"Component.Namespace.Master.Items.DiffItemTips": "比较各环境间配置",
"Component.Namespace.Master.Items.DiffItem": "比较配置",
"Component.Namespace.Master.Items.AddItem": "新增配置",
"Component.Namespace.Master.Items.Body.ItemsNoPublishedTips": "Tips: 此namespace从来没有发布过,Apollo客户端将获取不到配置并记录404日志信息,请及时发布。",
"Component.Namespace.Master.Items.Body.FilterByKey": "输入key过滤",
"Component.Namespace.Master.Items.Body.PublishState": "发布状态",
"Component.Namespace.Master.Items.Body.Sort": "排序",
"Component.Namespace.Master.Items.Body.ItemKey": "Key",
"Component.Namespace.Master.Items.Body.ItemValue": "Value",
"Component.Namespace.Master.Items.Body.ItemComment": "备注",
"Component.Namespace.Master.Items.Body.ItemLastModify": "最后修改人",
"Component.Namespace.Master.Items.Body.ItemLastModifyTime": "最后修改时间",
"Component.Namespace.Master.Items.Body.ItemOperator": "操作",
"Component.Namespace.Master.Items.Body.NoPublish": "未发布",
"Component.Namespace.Master.Items.Body.NoPublishTitle": "点击查看已发布的值",
"Component.Namespace.Master.Items.Body.NoPublishTips": "新增的配置,无发布的值",
"Component.Namespace.Master.Items.Body.Published": "已发布",
"Component.Namespace.Master.Items.Body.PublishedTitle": "已生效的配置",
"Component.Namespace.Master.Items.Body.ClickToSee": "点击查看",
"Component.Namespace.Master.Items.Body.Grayscale": "灰",
"Component.Namespace.Master.Items.Body.HaveGrayscale": "该配置有灰度配置,点击查看灰度的值",
"Component.Namespace.Master.Items.Body.NewAdded": "新",
"Component.Namespace.Master.Items.Body.NewAddedTips": "新增的配置",
"Component.Namespace.Master.Items.Body.Modifed": "改",
"Component.Namespace.Master.Items.Body.ModifedTips": "修改的配置",
"Component.Namespace.Master.Items.Body.Deleted": "删",
"Component.Namespace.Master.Items.Body.DeletedTips": "删除的配置",
"Component.Namespace.Master.Items.Body.ModifyTips": "修改",
"Component.Namespace.Master.Items.Body.DeleteTips": "删除",
"Component.Namespace.Master.Items.Body.Link.Title": "覆盖的配置",
"Component.Namespace.Master.Items.Body.Link.NoCoverLinkItem": "无覆盖的配置",
"Component.Namespace.Master.Items.Body.Public.Title": "公共的配置",
"Component.Namespace.Master.Items.Body.Public.Published": "已发布的配置",
"Component.Namespace.Master.Items.Body.Public.NoPublish": "未发布的配置",
"Component.Namespace.Master.Items.Body.Public.NoPublicNamespaceTips1": "当前公共namespace的所有者",
"Component.Namespace.Master.Items.Body.Public.NoPublicNamespaceTips2": "没有关联此namespace,请联系{{namespace.parentAppId}}的所有者在{{namespace.parentAppId}}项目里关联此namespace",
"Component.Namespace.Master.Items.Body.Public.NoPublished": "无发布的配置",
"Component.Namespace.Master.Items.Body.Public.PubishedAndCover": "覆盖此配置",
"Component.Namespace.Master.Items.Body.NoPublished.Title": "无公共的配置",
"Component.Namespace.Master.Items.Body.NoPublished.PublishedValue": "已发布的值",
"Component.Namespace.Master.Items.Body.NoPublished.NoPublishedValue": "未发布的值",
"Component.Namespace.Master.Items.Body.HistoryView.ItemType": "Type",
"Component.Namespace.Master.Items.Body.HistoryView.ItemKey": "Key",
"Component.Namespace.Master.Items.Body.HistoryView.ItemOldValue": "Old Value",
"Component.Namespace.Master.Items.Body.HistoryView.ItemNewValue": " New Value",
"Component.Namespace.Master.Items.Body.HistoryView.ItemComment": "Comment",
"Component.Namespace.Master.Items.Body.HistoryView.NewAdded": "新增",
"Component.Namespace.Master.Items.Body.HistoryView.Updated": "更新",
"Component.Namespace.Master.Items.Body.HistoryView.Deleted": "删除",
"Component.Namespace.Master.Items.Body.HistoryView.LoadingMore": "加载更多",
"Component.Namespace.Master.Items.Body.HistoryView.NoHistory": "无更改历史",
"Component.Namespace.Master.Items.Body.Instance.Tips": "实例说明:只展示最近一天访问过Apollo的实例",
"Component.Namespace.Master.Items.Body.Instance.UsedNewItem": "使用最新配置的实例",
"Component.Namespace.Master.Items.Body.Instance.NoUsedNewItem": "使用非最新配置的实例",
"Component.Namespace.Master.Items.Body.Instance.AllInstance": "所有实例",
"Component.Namespace.Master.Items.Body.Instance.RefreshList": "刷新列表",
"Component.Namespace.Master.Items.Body.Instance.ToSeeItem": "查看配置",
"Component.Namespace.Master.Items.Body.Instance.LoadingMore": "加载更多",
"Component.Namespace.Master.Items.Body.Instance.ItemAppId": "App ID",
"Component.Namespace.Master.Items.Body.Instance.ItemCluster": "Cluster Name",
"Component.Namespace.Master.Items.Body.Instance.ItemDataCenter": "Data Center",
"Component.Namespace.Master.Items.Body.Instance.ItemIp": "IP",
"Component.Namespace.Master.Items.Body.Instance.ItemGetTime": "配置获取时间",
"Component.Namespace.Master.Items.Body.Instance.NoInstanceTips": "无实例信息",
"Component.PublishDeny.Title": "发布受限",
"Component.PublishDeny.Tips1": "您不能发布哟~{{env}}环境配置的编辑和发布必须为不同的人,请找另一个具有当前namespace发布权的人操作发布~",
"Component.PublishDeny.Tips2": "(如果是非工作时间或者特殊情况,您可以通过点击<mark>紧急发布</mark>按钮进行发布)",
"Component.PublishDeny.EmergencyPublish": "紧急发布",
"Component.PublishDeny.Close": "关闭",
"Component.Publish.Title": "发布",
"Component.Publish.Tips": "(只有发布过的配置才会被客户端获取到,此次发布只会作用于当前环境:{{env}})",
"Component.Publish.Grayscale": "灰度发布",
"Component.Publish.GrayscaleTips": "(灰度发布的配置只会作用于在灰度规则中配置的实例)",
"Component.Publish.AllPublish": "全量发布",
"Component.Publish.AllPublishTips": "(全量发布的配置会作用于全部的实例)",
"Component.Publish.ToSeeChange": "查看变更",
"Component.Publish.PublishedValue": "发布的值",
"Component.Publish.Changes": "Changes",
"Component.Publish.Key": "Key",
"Component.Publish.NoPublishedValue": "未发布的值",
"Component.Publish.ModifyUser": "修改人",
"Component.Publish.ModifyTime": "修改时间",
"Component.Publish.NewAdded": "新",
"Component.Publish.NewAddedTips": "新增的配置",
"Component.Publish.Modifed": "改",
"Component.Publish.ModifedTips": "修改的配置",
"Component.Publish.Deleted": "删",
"Component.Publish.DeletedTips": "删除的配置",
"Component.Publish.MasterValue": "主版本值",
"Component.Publish.GrayValue": "灰度版本的值",
"Component.Publish.GrayPublishedValue": "灰度版本发布的值",
"Component.Publish.GrayNoPublishedValue": "灰度版本未发布的值",
"Component.Publish.ItemNoChange": "配置没有变化",
"Component.Publish.GrayItemNoChange": "灰度配置没有变化",
"Component.Publish.NoGrayItems": "没有灰度的配置项",
"Component.Publish.Release": "Release Name",
"Component.Publish.ReleaseComment": "Comment",
"Component.Publish.OpPublish": "发布",
"Component.Rollback.Goto": "回滚到",
"Component.Rollback.Tips": "此操作将会回滚到上一个发布版本,且当前版本作废,但不影响正在修改的配置。可在发布历史页面查看当前生效的版本",
"Component.Rollback.ItemType": "Type",
"Component.Rollback.ItemKey": "Key",
"Component.Rollback.RollbackBeforeValue": "回滚前",
"Component.Rollback.RollbackAfterValue": "回滚后",
"Component.Rollback.Added": "新增",
"Component.Rollback.Modifed": "更新",
"Component.Rollback.Deleted": "删除",
"Component.Rollback.NoChange": "配置没有变化",
"Component.Rollback.OpRollback": "回滚",
"Component.ShowText.Title": "查看",
"Login.Login": "登录",
"Login.UserNameOrPasswordIncorrect": "用户名或密码错误",
"Login.LogoutSuccessfully": "登出成功",
"Index.MyProject": "我的项目",
"Index.CreateProject": "创建项目",
"Index.LoadingMore": "加载更多",
"Index.FavoriteItems": "收藏的项目",
"Index.Topping": "置顶",
"Index.FavoriteTip": "您还没有收藏过任何项目,在项目主页可以收藏项目哟~",
"Index.RecentyViewedItems": "最近浏览的项目",
"Index.GetCreateAppRoleFailed": "获取创建应用权限信息失败",
"Index.Topped": "置顶成功",
"Index.CancelledFavorite": "取消收藏成功",
"Cluster.Tips.1": "通过添加集群,可以使同一份程序在不同的集群(如不同的数据中心)使用不同的配置",
"Cluster.Tips.2": "如果不同集群使用一样的配置,则没有必要创建集群",
"Cluster.Tips.3": "Apollo默认会读取机器上/opt/settings/server.properties(linux)或C:\\opt\\settings\\server.properties(windows)文件中的idc属性作为集群名字, 如SHAJQ(金桥数据中心)、SHAOY(欧阳数据中心)",
"Cluster.Tips.4": "在这里创建的集群名字需要和机器上server.properties中的idc属性一致",
"Cluster.CreaterNameTips": "(部署集群如:SHAJQ,SHAOY 或自定义集群如:SHAJQ-xx,SHAJQ-yy)",
"Cluster.ChooseEnvironment": "选择环境",
"Cluster.LoadingEnvironmentError": "加载环境信息出错",
"Cluster.ClusterCreated": "集群创建成功",
"Cluster.ClusterCreateFailed": "集群创建失败",
"Cluster.PleaseChooseEnvironment": "请选择环境",
"Config.Title": "Apollo配置中心",
"Config.AppIdNotFound": "不存在,",
"Config.ClickByCreate": "点击创建",
"Config.EnvList": "环境列表",
"Config.EnvListTips": "通过切换环境、集群来管理不同环境、集群的配置",
"Config.ProjectInfo": "项目信息",
"Config.ModifyBasicProjectInfo": "修改项目基本信息",
"Config.Favorite": "收藏",
"Config.CancelFavorite": "取消收藏",
"Config.MissEnv": "缺失的环境",
"Config.MissNamespace": "缺失的Namespace",
"Config.ProjectManage": "管理项目",
"Config.CreateAppMissEnv": "补缺环境",
"Config.CreateAppMissNamespace": "补缺Namespace",
"Config.AddCluster": "添加集群",
"Config.AddNamespace": "添加Namespace",
"Config.CurrentlyOperatorEnv": "当前操作环境",
"Config.DoNotRemindAgain": "不再提示",
"Config.Note": "注意",
"Config.ClusterIsDefualtTipContent": "所有不属于 '{{name}}' 集群的实例会使用default集群(当前页面)的配置,属于 '{{name}}' 的实例会使用对应集群的配置!",
"Config.ClusterIsCustomTipContent": "属于 '{{name}}' 集群的实例只会使用 '{{name}}' 集群(当前页面)的配置,只有当对应namespace在当前集群没有发布过配置时,才会使用default集群的配置。",
"Config.HasNotPublishNamespace": "以下环境/集群有未发布的配置,客户端获取不到未发布的配置,请及时发布。",
"Config.DeleteItem.DialogTitle": "删除配置",
"Config.DeleteItem.DialogContent": "您正在删除 Key 为 <b> '{{config.key}}' </b> Value 为 <b> '{{config.value}}' </b> 的配置.<br>确定要删除配置吗?",
"Config.PublishNoPermission.DialogTitle": "发布",
"Config.PublishNoPermission.DialogContent": "您没有发布权限哦~ 请找项目管理员 '{{masterUsers}}' 分配发布权限",
"Config.ModifyNoPermission.DialogTitle": "申请配置权限",
"Config.ModifyNoPermission.DialogContent": "请找项目管理员 '{{masterUsers}}' 分配编辑或发布权限",
"Config.MasterNoPermission.DialogTitle": "申请配置权限",
"Config.MasterNoPermission.DialogContent": "您不是项目管理员, 只有项目管理员才有添加集群、namespace的权限。如需管理员权限,请找项目管理员 '{{masterUsers}}' 分配管理员权限",
"Config.NamespaceLocked.DialogTitle": "编辑受限",
"Config.NamespaceLocked.DialogContent": "当前namespace正在被 '{{lockOwner}}' 编辑,一次发布只能被一个人修改.",
"Config.RollbackAlert.DialogTitle": "回滚",
"Config.RollbackAlert.DialogContent": "确定要回滚吗?",
"Config.EmergencyPublishAlert.DialogTitle": "紧急发布",
"Config.EmergencyPublishAlert.DialogContent": "确定要紧急发布吗?",
"Config.DeleteBranch.DialogTitle": "删除灰度",
"Config.DeleteBranch.DialogContent": "删除灰度会丢失灰度的配置,确定要删除吗?",
"Config.UpdateRuleTips.DialogTitle": "更新灰度规则提示",
"Config.UpdateRuleTips.DialogContent": "灰度规则已生效,但发现灰度版本有未发布的配置,这些配置需要手动灰度发布才会生效",
"Config.MergeAndReleaseDeny.DialogTitle": "全量发布",
"Config.MergeAndReleaseDeny.DialogContent": "namespace主版本有未发布的配置,请先发布主版本配置",
"Config.GrayReleaseWithoutRulesTips.DialogTitle": "缺失灰度规则提示",
"Config.GrayReleaseWithoutRulesTips.DialogContent": "灰度版本还没有配置任何灰度规则,请配置灰度规则",
"Config.DeleteNamespaceDenyForMasterInstance.DialogTitle": "删除Namespace警告信息",
"Config.DeleteNamespaceDenyForMasterInstance.DialogContent": "发现有 <b>'{{deleteNamespaceContext.namespace.instancesCount}}'</b> 个实例正在使用Namespace('{{deleteNamespaceContext.namespace.baseInfo.namespaceName}}'),删除Namespace将导致实例获取不到配置。<br>请到 <ins>“实例列表”</ins> 确认实例信息,如确认相关实例都已经不再使用该Namespace配置,可以联系Apollo相关负责人删除实例信息(InstanceConfig)或等待实例24小时自动过期后再来删除。",
"Config.DeleteNamespaceDenyForBranchInstance.DialogTitle": "删除Namespace警告信息",
"Config.DeleteNamespaceDenyForBranchInstance.DialogContent": "发现有 <b>'{{deleteNamespaceContext.namespace.branch.latestReleaseInstances.total}}'</b> 个实例正在使用Namespace('{{deleteNamespaceContext.namespace.baseInfo.namespaceName}}')灰度版本的配置,删除Namespace将导致实例获取不到配置。<br> 请到 <ins>“灰度版本” => “实例列表”</ins> 确认实例信息,如确认相关实例都已经不再使用该Namespace配置,可以联系Apollo相关负责人删除实例信息(InstanceConfig)或等待实例24小时自动过期后再来删除。",
"Config.DeleteNamespaceDenyForPublicNamespace.DialogTitle": "删除Namespace失败提示",
"Config.DeleteNamespaceDenyForPublicNamespace.DialogContent": "删除Namespace失败提示",
"Config.DeleteNamespaceDenyForPublicNamespace.PleaseEnterAppId": "请输入appId",
"Config.SyntaxCheckFailed.DialogTitle": "语法检查错误",
"Config.SyntaxCheckFailed.DialogContent": "删除Namespace失败提示",
"Config.CreateBranchTips.DialogTitle": "创建灰度须知",
"Config.CreateBranchTips.DialogContent": "通过创建灰度版本,您可以对某些配置做灰度测试<br>灰度流程为:<br>&nbsp;&nbsp;1.创建灰度版本 <br>&nbsp;&nbsp;2.配置灰度配置项<br>&nbsp;&nbsp;3.配置灰度规则.如果是私有的namespace可以按照客户端的IP进行灰度,如果是公共的namespace则可以同时按AppId和客户端的IP进行灰度<br>&nbsp;&nbsp;4.灰度发布<br>灰度版本最终有两种结果:<b>全量发布和放弃灰度</b><br><b>全量发布</b>:灰度的配置合到主版本并发布,所有的客户端都会使用合并后的配置<br><b>放弃灰度</b>:删除灰度版本,所有的客户端都会使用回主版本的配置<br>注意事项:<br>&nbsp;&nbsp;1.如果灰度版本已经有灰度发布过,那么修改灰度规则后,无需再次灰度发布就立即生效",
"Config.ProjectMissEnvInfos": "当前项目有环境缺失,请点击页面左侧『补缺环境』补齐数据",
"Config.ProjectMissNamespaceInfos": "当前环境有Namespace缺失,请点击页面左侧『补缺Namespace』补齐数据",
"Config.SystemError": "系统出错,请重试或联系系统负责人",
"Config.FavoriteSuccessfully": "收藏成功",
"Config.FavoriteFailed": "收藏失败",
"Config.CancelledFavorite": "取消收藏成功",
"Config.CanceFavoriteFailed": "取消收藏失败",
"Config.GetrUserInfoFailed": "获取用户登录信息失败",
"Config.LoadingAllNamespaceError": "加载配置信息出错",
"Config.CanceFavoriteError": "取消收藏失败",
"Config.Deleted": "删除成功",
"Config.DeleteFailed": "删除失败",
"Config.GrayscaleCreated": "创建灰度成功",
"Config.GrayscaleCreateFailed": "创建灰度失败",
"Config.BranchDeleted": "分支删除成功",
"Config.BranchDeleteFailed": "分支删除失败",
"Config.DeleteNamespaceFailedTips": "以下应用已关联此公共Namespace,必须先删除全部已关联的Namespace才能删除公共Namespace",
"Config.DeleteNamespaceNoPermissionFailedTitle": "删除失败",
"Config.DeleteNamespaceNoPermissionFailedTips": "您没有项目管理员权限,只有管理员才能删除Namespace,请找项目管理员 [{{usres}}] 删除Namespace",
"Delete.Title": "删除应用、集群、AppNamespace",
"Delete.DeleteApp": "删除应用",
"Delete.DeleteAppTips": "(由于删除应用影响面较大,所以现在暂时只允许系统管理员删除,请确保没有客户端读取该应用的配置后再做删除动作)",
"Delete.AppIdTips": "(删除前请先查询应用信息)",
"Delete.AppInfo": "应用信息",
"Delete.DeleteCluster": "删除集群",
"Delete.DeleteClusterTips": "(由于删除集群影响面较大,所以现在暂时只允许系统管理员删除,请确保没有客户端读取该集群的配置后再做删除动作)",
"Delete.EnvName": "环境名称",
"Delete.ClusterNameTips": "(删除前请先查询应用集群信息)",
"Delete.ClusterInfo": "集群信息",
"Delete.DeleteNamespace": "删除AppNamespace",
"Delete.DeleteNamespaceTips": "(注意,所有环境的Namespace和AppNamespace都会被删除!如果只是要删除某个环境的Namespace,让用户到项目页面中自行删除!)",
"Delete.DeleteNamespaceTips2": "目前用户可以自行删除关联的Namespace和私有的Namespace,不过无法删除AppNamespace元信息,因为删除AppNamespace影响面较大,所以现在暂时只允许系统管理员删除,对于公共Namespace需要确保没有应用关联了该AppNamespace。",
"Delete.AppNamespaceName": "AppNamespace名称",
"Delete.AppNamespaceNameTips": "(非properties类型的namespace请加上类型后缀,例如apollo.xml)",
"Delete.AppNamespaceInfo": "AppNamespace信息",
"Delete.IsRootUserTips": "当前页面只对Apollo管理员开放",
"Delete.PleaseEnterAppId": "请输入appId",
"Delete.AppIdNotFound": "AppId: '{{appId}}'不存在!",
"Delete.AppInfoContent": "应用名:'{{appName}}' 部门:'{{departmentName}}({{departmentId}})' 负责人:'{{ownerName}}'",
"Delete.ConfirmDeleteAppId": "确认删除AppId:'{{appId}}'?",
"Delete.Deleted": "删除成功",
"Delete.PleaseEnterAppIdAndEnvAndCluster": "请输入appId、环境和集群名称",
"Delete.ClusterInfoContent": "AppId:'{{appId}}' 环境:'{{env}}' 集群名称:'{{clusterName}}'",
"Delete.ConfirmDeleteCluster": "确认删除集群?AppId:'{{appId}}' 环境:'{{env}}' 集群名称:'{{clusterName}}'",
"Delete.PleaseEnterAppIdAndNamespace": "请输入appId和AppNamespace名称",
"Delete.AppNamespaceInfoContent": "AppId:'{{appId}}' AppNamespace名称:'{{namespace}}' isPublic:'{{isPublic}}'",
"Delete.ConfirmDeleteNamespace": "确认删除所有环境的AppNamespace和Namespace?appId: '{{appId}}' 环境:'所有环境' AppNamespace名称:'{{namespace}}'",
"Namespace.Title": "新建Namespace",
"Namespace.UnderstandMore": "(点击了解更多Namespace相关知识)",
"Namespace.Link.Tips1": "应用可以通过关联公共namespace来覆盖公共Namespace的配置",
"Namespace.Link.Tips2": "如果应用不需要覆盖公共Namespace的配置,那么无需关联公共Namespace",
"Namespace.CreatePublic.Tips1": "公共的Namespace的配置能被任何项目读取",
"Namespace.CreatePublic.Tips2": "通过创建公共Namespace可以实现公共组件的配置,或多个应用共享同一份配置的需求",
"Namespace.CreatePublic.Tips3": "如果其它应用需要覆盖公共部分的配置,可以在其它应用那里关联公共Namespace,然后在关联的Namespace里面配置需要覆盖的配置即可",
"Namespace.CreatePublic.Tips4": "如果其它应用不需要覆盖公共部分的配置,那么就不需要在其它应用那里关联公共Namespace",
"Namespace.CreatePrivate.Tips1": "私有Namespace的配置只能被所属的应用获取到",
"Namespace.CreatePrivate.Tips2": "通过创建一个私有的Namespace可以实现分组管理配置",
"Namespace.CreatePrivate.Tips3": "私有Namespace的格式可以是xml、yml、yaml、json、txt. 您可以通过apollo-client中ConfigFile接口来获取非properties格式Namespace的内容",
"Namespace.CreatePrivate.Tips4": "1.3.0及以上版本的apollo-client针对yaml/yml提供了更好的支持,可以通过ConfigService.getConfig(\"someNamespace.yml\")直接获取Config对象,也可以通过@EnableApolloConfig(\"someNamespace.yml\")或apollo.bootstrap.namespaces=someNamespace.yml注入yml配置到Spring/SpringBoot中去",
"Namespace.CreateNamespcae": "创建Namespace",
"Namespace.AssociationPublicNamespcae": "关联公共Namespace",
"Namespace.ChooseCluster": "选择集群",
"Namespace.NamespaceName": "名称",
"Namespace.AutoAddDepartmentPrefix": "自动添加部门前缀",
"Namespace.AutoAddDepartmentPrefixTips": "(公共Namespace的名称需要全局唯一,添加部门前缀有助于保证全局唯一性)",
"Namespace.NamespcaeType": "类型",
"Namespace.NamespcaeType.Public": "public",
"Namespace.NamespcaeType.Private": "private",
"Namespace.Remark": "备注",
"Namespace.Namespace": "namespace",
"Namespace.PleaseChooseNamespace": "请选择Namespace",
"Namespace.LoadingPublicNamespaceError": "加载公共namespace错误",
"Namespace.LoadingAppInfoError": "加载App信息出错",
"Namespace.PleaseChooseCluster": "请选择集群",
"Namespace.ChecknamespaceNameLengthTip": "namespace名称不能大于32个字符. 部门前缀:'{{departmentLength}}'个字符, 名称{{namespaceLength}}个字符",
"SericeConfig.Title": "应用配置",
"SericeConfig.Tips": "(维护ApolloPortalDB.ServerConfig表数据,如果已存在配置项则会覆盖,否则会创建配置项。配置更新后,一分钟后自动生效)",
"SericeConfig.Key": "key",
"SericeConfig.KeyTips": "(修改配置前请先查询该配置信息)",
"SericeConfig.Value": "value",
"SericeConfig.Comment": "comment",
"SericeConfig.Saved": "保存成功",
"SericeConfig.SaveFailed": "保存失败",
"SericeConfig.PleaseEnterKey": "请输入key",
"SericeConfig.KeyNotExistsAndCreateTip": "Key: '{{key}}' 不存在,点击保存后会创建该配置项",
"SericeConfig.KeyExistsAndSaveTip": "Key: '{{key}}' 已存在,点击保存后会覆盖该配置项",
"SystemInfo.Title": "系统信息",
"SystemInfo.SystemVersion": "系统版本",
"SystemInfo.Tips1": "环境列表来自于ApolloPortalDB.ServerConfig中的<strong>apollo.portal.envs</strong>配置,可以到<a href=\"{{serverConfigUrl}}\">系统参数</a>页面配置,更多信息可以参考<a href=\"{{wikiUrl}}\">分布式部署指南</a>中的<strong>apollo.portal.envs - 可支持的环境列表</strong>章节。",
"SystemInfo.Tips2": "Meta server地址展示了该环境配置的meta server信息,更多信息可以参考<a href=\"{{wikiUrl}}\">分布式部署指南</a>中的<strong>配置apollo-portal的meta service信息</strong>章节。",
"SystemInfo.Active": "Active",
"SystemInfo.ActiveTips": "(当前环境状态异常,请结合下方系统信息和AdminService的Check Health结果排查)",
"SystemInfo.MetaServerAddress": "Meta server地址",
"SystemInfo.ConfigServices": "Config Services",
"SystemInfo.ConfigServices.Name": "Name",
"SystemInfo.ConfigServices.InstanceId": "Instance Id",
"SystemInfo.ConfigServices.HomePageUrl": "Home Page Url",
"SystemInfo.ConfigServices.CheckHealth": "Check Health",
"SystemInfo.NoConfigServiceTips": "No config service found!",
"SystemInfo.Check": "check",
"SystemInfo.AdminServices": "Admin Services",
"SystemInfo.AdminServices.Name": "Name",
"SystemInfo.AdminServices.InstanceId": "Instance Id",
"SystemInfo.AdminServices.HomePageUrl": "Home Page Url",
"SystemInfo.AdminServices.CheckHealth": "Check Health",
"SystemInfo.NoAdminServiceTips": "No admin service found!",
"SystemInfo.IsRootUser": "当前页面只对Apollo管理员开放",
"SystemRole.Title": "系统权限管理",
"SystemRole.AddCreateAppRoleToUser": "为用户添加创建应用权限",
"SystemRole.AddCreateAppRoleToUserTips": "(系统参数中设置 role.create-application.enabled=true 会限制只有超级管理员和拥有创建应用权限的帐号可以创建项目)",
"SystemRole.ChooseUser": "用户选择",
"SystemRole.Add": "添加",
"SystemRole.AuthorizedUser": "已拥有权限用户",
"SystemRole.ModifyAppAdminUser": "修改应用管理员分配权限",
"SystemRole.ModifyAppAdminUserTips": "(系统参数中设置 role.manage-app-master.enabled=true 会限制只有超级管理员和拥有管理员分配权限的帐号可以修改项目管理员)",
"SystemRole.AppIdTips": "(请先查询应用信息)",
"SystemRole.AppInfo": "应用信息",
"SystemRole.AllowAppMasterAssignRole": "允许此用户作为管理员时添加Master",
"SystemRole.DeleteAppMasterAssignRole": "禁止此用户作为管理员时添加Master",
"SystemRole.IsRootUser": "当前页面只对Apollo管理员开放",
"SystemRole.PleaseChooseUser": "请选择用户名",
"SystemRole.Added": "添加成功",
"SystemRole.AddFailed": "添加失败",
"SystemRole.Deleted": "删除成功",
"SystemRole.DeleteFailed": "删除失败",
"SystemRole.GetCanCreateProjectUsersError": "获取拥有创建项目的用户列表出错",
"SystemRole.PleaseEnterAppId": "请输入appId",
"SystemRole.AppIdNotFound": "AppId: '{{appId}}' 不存在!",
"SystemRole.AppInfoContent": "应用名:'{{appName}}' 部门:'{{departmentName}}({{departmentId}})' 负责人:'{{ownerName}}",
"SystemRole.DeleteMasterAssignRoleTips": "确认删除AppId: '{{appId}}' 的用户: '{{userId}}' 分配应用管理员的权限?",
"SystemRole.DeletedMasterAssignRoleTips": "删除AppId: '{{appId}}' 的用户: '{{userId}}' 分配应用管理员的权限成功",
"SystemRole.AllowAppMasterAssignRoleTips": "确认添加AppId: '{{appId}}' 的用户: '{{userId}}' 分配应用管理员的权限?",
"SystemRole.AllowedAppMasterAssignRoleTips": "添加AppId: '{{appId}}' 的用户: '{{userId}}' 分配应用管理员的权限成功",
"UserMange.Title": "用户管理",
"UserMange.TitleTips": "(仅对默认的Spring Security简单认证方式有效: -Dapollo_profile=github,auth)",
"UserMange.UserName": "用户名",
"UserMange.UserNameTips": "输入的用户名如果不存在,则新建。若已存在,则更新。",
"UserMange.Pwd": "密码",
"UserMange.Email": "邮箱",
"UserMange.Created": "创建用户成功",
"UserMange.CreateFailed": "创建用户失败",
"Open.Manage.Title": "开放平台",
"Open.Manage.CreateThirdApp": "创建第三方应用",
"Open.Manage.CreateThirdAppTips": "(说明: 第三方应用可以通过Apollo开放平台来对配置进行管理)",
"Open.Manage.ThirdAppId": "第三方应用ID",
"Open.Manage.ThirdAppIdTips": "(创建前请先查询第三方应用是否已经申请过)",
"Open.Manage.ThirdAppName": "第三方应用名称",
"Open.Manage.ThirdAppNameTips": "(建议格式 xx-yy-zz 例:apollo-server)",
"Open.Manage.ProjectOwner": "项目负责人",
"Open.Manage.Create": "创建",
"Open.Manage.GrantPermission": "赋权",
"Open.Manage.GrantPermissionTips": "(Namespace级别权限包括: 修改、发布Namespace。应用级别权限包括: 创建Namespace、修改或发布应用下任何Namespace)",
"Open.Manage.Token": "token",
"Open.Manage.ManagedAppId": "被管理的AppId",
"Open.Manage.ManagedNamespace": "被管理的Namespace",
"Open.Manage.ManagedNamespaceTips": "(非properties类型的namespace请加上类型后缀,例如apollo.xml)",
"Open.Manage.GrantType": "授权类型",
"Open.Manage.GrantType.Namespace": "Namespace",
"Open.Manage.GrantType.App": "App",
"Open.Manage.GrantEnv": "环境",
"Open.Manage.GrantEnvTips": "(不选择则所有环境都有权限,如果提示Namespace's role does not exist,请先打开该Namespace的授权页面触发一下权限的初始化动作)",
"Open.Manage.PleaseEnterAppId": "请输入appId",
"Open.Manage.AppNotCreated": "App('{{appId}}')未创建,请先创建",
"Open.Manage.GrantSuccessfully": "赋权成功",
"Open.Manage.GrantFailed": "赋权失败",
"Namespace.Role.Title": "权限管理",
"Namespace.Role.GrantModifyTo": "修改权",
"Namespace.Role.GrantModifyTo2": "(可以修改配置)",
"Namespace.Role.AllEnv": "所有环境",
"Namespace.Role.GrantPubishTo": "发布权",
"Namespace.Role.GrantPubishTo2": "(可以发布配置)",
"Namespace.Role.Add": "添加",
"Namespace.Role.NoPermisson": "您没有权限哟!",
"Namespace.Role.InitNamespacePermissionError": "初始化授权出错",
"Namespace.Role.GetEnvGrantUserError": "加载 '{{env}}' 授权用户出错",
"Namespace.Role.GetGrantUserError": "加载授权用户出错",
"Namespace.Role.PleaseChooseUser": "请选择用户",
"Namespace.Role.Added": "添加成功",
"Namespace.Role.AddFailed": "添加失败",
"Namespace.Role.Deleted": "删除成功",
"Namespace.Role.DeleteFailed": "删除失败",
"Config.Sync.Title": "同步配置",
"Config.Sync.FistStep": "(第一步:选择同步信息)",
"Config.Sync.SecondStep": "(第二步:检查Diff)",
"Config.Sync.PreviousStep": "上一步",
"Config.Sync.NextStep": "下一步",
"Config.Sync.Sync": "同步",
"Config.Sync.Tips": "Tips",
"Config.Sync.Tips1": "通过同步配置功能,可以使多个环境、集群间的配置保持一致",
"Config.Sync.Tips2": "需要注意的是,同步完之后需要发布后才会对应用生效",
"Config.Sync.SyncNamespace": "同步的Namespace",
"Config.Sync.SyncToCluster": "同步到那个集群",
"Config.Sync.NeedToSyncItem": "需要同步的配置",
"Config.Sync.SortByLastModifyTime": "按最后更新时间过滤",
"Config.Sync.BeginTime": "开始时间",
"Config.Sync.EndTime": "结束时间",
"Config.Sync.Filter": "过滤",
"Config.Sync.Rest": "重置",
"Config.Sync.ItemKey": "Key",
"Config.Sync.ItemValue": "Value",
"Config.Sync.ItemCreateTime": "Create Time",
"Config.Sync.ItemUpdateTime": "Update Time",
"Config.Sync.NoNeedSyncItem": "没有更新的配置",
"Config.Sync.IgnoreSync": "忽略同步",
"Config.Sync.Step2Type": "Type",
"Config.Sync.Step2Key": "Key",
"Config.Sync.Step2SyncBefore": "同步前",
"Config.Sync.Step2SyncAfter": "同步后",
"Config.Sync.Step2Comment": "Comment",
"Config.Sync.Step2Operator": "操作",
"Config.Sync.NewAdd": "新增",
"Config.Sync.NoSyncItem": "不同步该配置",
"Config.Sync.Delete": "删除",
"Config.Sync.Update": "更新",
"Config.Sync.SyncSuccessfully": "同步成功!",
"Config.Sync.SyncFailed": "同步失败!",
"Config.Sync.LoadingItemsError": "加载配置出错",
"Config.Sync.PleaseChooseNeedSyncItems": "请选择需要同步的配置",
"Config.Sync.PleaseChooseCluster": "请选择集群",
"Config.History.Title": "发布历史",
"Config.History.MasterVersionPublish": "主版本发布",
"Config.History.MasterVersionRollback": "主版本回滚",
"Config.History.GrayscaleOperator": "灰度操作",
"Config.History.PublishHistory": "发布历史",
"Config.History.OperationType0": "普通发布",
"Config.History.OperationType1": "回滚",
"Config.History.OperationType2": "灰度发布",
"Config.History.OperationType3": "更新灰度规则",
"Config.History.OperationType4": "灰度全量发布",
"Config.History.OperationType5": "灰度发布(主版本发布)",
"Config.History.OperationType6": "灰度发布(主版本回滚)",
"Config.History.OperationType7": "放弃灰度",
"Config.History.OperationType8": "删除灰度(全量发布)",
"Config.History.UrgentPublish": "紧急发布",
"Config.History.LoadingMore": "加载更多",
"Config.History.ChangedItem": "变更的配置",
"Config.History.AllItem": "全部配置",
"Config.History.ChangeType": "Type",
"Config.History.ChangeKey": "Key",
"Config.History.ChangeValue": "Value",
"Config.History.ChangeOldValue": "Old Value",
"Config.History.ChangeNewValue": "New Value",
"Config.History.ChangeTypeNew": "新增",
"Config.History.ChangeTypeModify": "修改",
"Config.History.ChangeTypeDelete": "删除",
"Config.History.NoChange": "无配置更改",
"Config.History.NoItem": "无配置",
"Config.History.GrayscaleRule": "灰度规则",
"Config.History.GrayscaleAppId": "灰度的AppId",
"Config.History.GrayscaleIp": "灰度的IP",
"Config.History.NoGrayscaleRule": "无灰度规则",
"Config.History.NoPermissonTips": "您不是该项目的管理员,也没有该Namespace的编辑或发布权限,无法查看发布历史",
"Config.History.NoPublishHistory": "无发布历史信息",
"Config.History.LoadingHistoryError": "无发布历史信息",
"Config.Diff.Title": "比较配置",
"Config.Diff.FirstStep": "(第一步:选择比较信息)",
"Config.Diff.SecondStep": "(第二步:查看差异配置)",
"Config.Diff.PreviousStep": "上一步",
"Config.Diff.NextStep": "下一步",
"Config.Diff.TipsTitle": "Tips",
"Config.Diff.Tips": "通过比较配置功能,可以查看多个环境、集群间的配置差异",
"Config.Diff.DiffCluster": "要比较的集群",
"Config.Diff.HasDiffComment": "是否比较注释",
"Config.Diff.PleaseChooseTwoCluster": "请至少选择两个集群",
"App.CreateProject": "创建项目",
"App.AppIdTips": "(应用唯一标识)",
"App.AppNameTips": "(建议格式 xx-yy-zz 例:apollo-server)",
"App.AppOwnerTips": "(开启项目管理员分配权限控制后,应用负责人和项目管理员默认为本账号,不可选择)",
"App.AppAdminTips1": "(应用负责人默认具有项目管理员权限,",
"App.AppAdminTips2": "项目管理员可以创建Namespace和集群、分配用户权限)",
"App.Setting.Title": "项目管理",
"App.Setting.Admin": "管理员",
"App.Setting.AdminTips": "(项目管理员具有以下权限: 1. 创建Namespace 2. 创建集群 3. 管理项目、Namespace权限)",
"App.Setting.Add": "添加",
"App.Setting.BasicInfo": "基本信息",
"App.Setting.ProjectName": "项目名称",
"App.Setting.ProjectNameTips": "(建议格式 xx-yy-zz 例:apollo-server)",
"App.Setting.ProjectOwner": "项目负责人",
"App.Setting.Modify": "修改项目信息",
"App.Setting.Cancel": "取消修改",
"App.Setting.NoPermissonTips": "您没有权限操作,请找 [{{users}}] 开通权限",
"App.Setting.DeleteAdmin": "删除管理员",
"App.Setting.CanNotDeleteAllAdmin": "不能删除所有的管理员",
"App.Setting.PleaseChooseUser": "请选择用户",
"App.Setting.Added": "添加成功",
"App.Setting.AddFailed": "添加失败",
"App.Setting.Deleted": "删除成功",
"App.Setting.DeleteFailed": "删除失败",
"App.Setting.Modifed": "修改成功",
"Valdr.App.AppId.Size": "AppId长度不能多于32个字符",
"Valdr.App.AppId.Required": "AppId不能为空",
"Valdr.App.appName.Size": "应用名称长度不能多于128个字符",
"Valdr.App.appName.Required": "应用名称不能为空",
"Valdr.Cluster.ClusterName.Size": "集群名称长度不能多于32个字符",
"Valdr.Cluster.ClusterName.Required": "集群名称不能为空",
"Valdr.AppNamespace.NamespaceName.Size": "Namespace名称长度不能多于32个字符",
"Valdr.AppNamespace.NamespaceName.Required": "Namespace名称不能为空",
"Valdr.AppNamespace.Comment.Size": "备注长度不能多于64个字符",
"Valdr.Item.Key.Size": "Key长度不能多于128个字符",
"Valdr.Item.Key.Required": "Key不能为空",
"Valdr.Item.Comment.Size": "备注长度不能多于64个字符",
"Valdr.Release.ReleaseName.Size": "Release Name长度不能多于64个字符",
"Valdr.Release.ReleaseName.Required": "Release Name不能为空",
"Valdr.Release.Comment.Size": "备注长度不能多于64个字符",
"ApolloConfirmDialog.DefaultConfirmBtnName": "确认",
"ApolloConfirmDialog.SearchPlaceHolder": "搜索项目(AppId、项目名)",
"RulesModal.ChooseInstances": "从实例列表中选择",
"RulesModal.InvalidIp": "不合法的IP地址: '{{ip}}'",
"RulesModal.GrayscaleAppIdCanNotBeNull": "灰度的AppId不能为空",
"RulesModal.AppIdExistsRule": "已经存在AppId='{{appId}}'的规则",
"RulesModal.IpListCanNotBeNull": "IP列表不能为空",
"ItemModal.KeyExists": "key='{{key}}' 已存在",
"ItemModal.AddedTips": "添加成功,如需生效请发布",
"ItemModal.AddFailed": "添加失败",
"ItemModal.PleaseChooseCluster": "请选择集群",
"ItemModal.ModifedTips": "更新成功, 如需生效请发布",
"ItemModal.ModifyFailed": "更新失败",
"ItemModal.Tabs": "制表符",
"ItemModal.NewLine": "换行符",
"ItemModal.Space": "空格",
"ApolloNsPanel.LoadingHistoryError": "加载修改历史记录出错",
"ApolloNsPanel.LoadingGrayscaleError": "加载修改历史记录出错",
"ApolloNsPanel.Deleted": "删除成功",
"ApolloNsPanel.GrayscaleModifed": "灰度规则更新成功",
"ApolloNsPanel.GrayscaleModifyFailed": "灰度规则更新失败",
"ApolloNsPanel.ModifedTips": "更新成功, 如需生效请发布",
"ApolloNsPanel.ModifyFailed": "更新失败",
"ApolloNsPanel.GrammarIsright": "语法正确!",
"ReleaseModal.Published": "发布成功",
"ReleaseModal.PublishFailed": "发布失败",
"ReleaseModal.GrayscalePublished": "灰度发布成功",
"ReleaseModal.GrayscalePublishFailed": "灰度发布失败",
"ReleaseModal.AllPublished": "全量发布成功",
"ReleaseModal.AllPublishFailed": "全量发布失败",
"Rollback.NoRollbackList": "没有可以回滚的发布历史",
"Rollback.RollbackSuccessfully": "回滚成功",
"Rollback.RollbackFailed": "回滚失败"
}
\ No newline at end of file
<!doctype html> <!doctype html>
<html ng-app="index"> <html ng-app="index">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="icon" href="./img/config.png"> <link rel="icon" href="./img/config.png">
...@@ -11,24 +12,25 @@ ...@@ -11,24 +12,25 @@
<link rel="stylesheet" type="text/css" media='all' href="vendor/font-awesome.min.css"> <link rel="stylesheet" type="text/css" media='all' href="vendor/font-awesome.min.css">
<link rel="stylesheet" type="text/css" href="styles/common-style.css"> <link rel="stylesheet" type="text/css" href="styles/common-style.css">
<title>Apollo配置中心</title> <title>{{'Common.Title' | translate }}</title>
</head> </head>
<body> <body>
<apollonav></apollonav> <apollonav></apollonav>
<div id="app-list" class="hidden" ng-controller="IndexController"> <div id="app-list" class="hidden" ng-controller="IndexController">
<section class="media create-app-list"> <section class="media create-app-list">
<aside class="media-left text-center"> <aside class="media-left text-center">
<h5>我的项目</h5> <h5>{{'Index.MyProject' | translate }}</h5>
</aside> </aside>
<aside class="media-body"> <aside class="media-body">
<div class="app-panel col-md-2 text-center" ng-click="goToCreateAppPage()" ng-if="hasCreateApplicationPermission"> <div class="app-panel col-md-2 text-center" ng-click="goToCreateAppPage()"
ng-if="hasCreateApplicationPermission">
<div href="#" class="thumbnail create-btn hover cursor-pointer"> <div href="#" class="thumbnail create-btn hover cursor-pointer">
<img src="img/plus-white.png"/> <img src="img/plus-white.png" />
<h5>创建项目</h5> <h5>{{'Index.CreateProject' | translate }}</h5>
</div> </div>
</div> </div>
<div class="app-panel col-md-2 text-center" ng-repeat="app in createdApps" <div class="app-panel col-md-2 text-center" ng-repeat="app in createdApps"
...@@ -41,8 +43,8 @@ ...@@ -41,8 +43,8 @@
<div class="app-panel col-md-2 text-center" ng-show="hasMoreCreatedApps" <div class="app-panel col-md-2 text-center" ng-show="hasMoreCreatedApps"
ng-click="getUserCreatedApps()"> ng-click="getUserCreatedApps()">
<div href="#" class="thumbnail hover cursor-pointer"> <div href="#" class="thumbnail hover cursor-pointer">
<img class="more-img" src="img/more.png"/> <img class="more-img" src="img/more.png" />
<h5>加载更多</h5> <h5>{{'Index.LoadingMore' | translate }}</h5>
</div> </div>
</div> </div>
</aside> </aside>
...@@ -50,39 +52,36 @@ ...@@ -50,39 +52,36 @@
<section class="media favorites-app-list"> <section class="media favorites-app-list">
<aside class="media-left text-center"> <aside class="media-left text-center">
<h5>收藏的项目</h5> <h5>{{'Index.FavoriteItems' | translate }}</h5>
</aside> </aside>
<aside class="media-body"> <aside class="media-body">
<div class="app-panel col-md-2 text-center" <div class="app-panel col-md-2 text-center" ng-repeat="app in favorites"
ng-repeat="app in favorites" ng-click="goToAppHomePage(app.appId)" ng-mouseover="toggleOperationBtn(app)"
ng-click="goToAppHomePage(app.appId)"
ng-mouseover="toggleOperationBtn(app)"
ng-mouseout="toggleOperationBtn(app)"> ng-mouseout="toggleOperationBtn(app)">
<div class="thumbnail hover"> <div class="thumbnail hover">
<h4 ng-bind="app.appId"></h4> <h4 ng-bind="app.appId"></h4>
<h5 ng-bind="app.name"></h5> <h5 ng-bind="app.name"></h5>
<p class="operate-panel" ng-show="app.showOperationBtn"> <p class="operate-panel" ng-show="app.showOperationBtn">
<button class="btn btn-default btn-xs" title="置顶" <button class="btn btn-default btn-xs" title="{{'Index.Topping' | translate }}"
ng-click="toTop(app.favoriteId);$event.stopPropagation();"> ng-click="toTop(app.favoriteId);$event.stopPropagation();">
<img src="img/top.png" class="i-15"> <img src="img/top.png" class="i-15">
</button> </button>
<button class="btn btn-default btn-xs" title="取消收藏" <button class="btn btn-default btn-xs" title="{{'Index.FavoriteCancel' | translate }}"
ng-click="deleteFavorite(app.favoriteId);$event.stopPropagation();"> ng-click="deleteFavorite(app.favoriteId);$event.stopPropagation();">
<img src="img/like.png" class="i-15"> <img src="img/like.png" class="i-15">
</button> </button>
</p> </p>
</div> </div>
</div> </div>
<div class="col-md-2 text-center" ng-show="hasMoreFavorites" <div class="col-md-2 text-center" ng-show="hasMoreFavorites" ng-click="getUserFavorites()">
ng-click="getUserFavorites()">
<div href="#" class="thumbnail hover cursor-pointer"> <div href="#" class="thumbnail hover cursor-pointer">
<img class="more-img" src="img/more.png"/> <img class="more-img" src="img/more.png" />
<h5>加载更多</h5> <h5>{{'Index.LoadingMore' | translate }}</h5>
</div> </div>
</div> </div>
<div class="no-favorites text-center" ng-show="!favorites || favorites.length == 0"> <div class="no-favorites text-center" ng-show="!favorites || favorites.length == 0">
<h4>您还没有收藏过任何项目,在项目主页可以收藏项目哟~</h4> <h4>{{'Index.FavoriteTip' | translate }}</h4>
</div> </div>
</aside> </aside>
...@@ -90,11 +89,10 @@ ...@@ -90,11 +89,10 @@
<section class="media visit-app-list" ng-show="visitedApps && visitedApps.length"> <section class="media visit-app-list" ng-show="visitedApps && visitedApps.length">
<aside class="media-left text-center"> <aside class="media-left text-center">
<h5>最近浏览的项目</h5> <h5>{{'Index.RecentyViewedItems' | translate }}</h5>
</aside> </aside>
<aside class="media-body"> <aside class="media-body">
<div class="app-panel col-md-2 text-center" <div class="app-panel col-md-2 text-center" ng-repeat="app in visitedApps"
ng-repeat="app in visitedApps"
ng-click="goToAppHomePage(app.appId)"> ng-click="goToAppHomePage(app.appId)">
<div class="thumbnail hover"> <div class="thumbnail hover">
<h4 ng-bind="app.appId"></h4> <h4 ng-bind="app.appId"></h4>
...@@ -103,35 +101,45 @@ ...@@ -103,35 +101,45 @@
</div> </div>
</aside> </aside>
</section> </section>
</div> </div>
<div ng-include="'views/common/footer.html'"></div>
<div ng-include="'views/common/footer.html'"></div> <!--angular-->
<script src="vendor/angular/angular.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/loading-bar.min.js"></script>
<script src="vendor/angular/angular-cookies.min.js"></script>
<!--angular--> <script src="vendor/angular/angular-translate.2.18.1/angular-translate.min.js"></script>
<script src="vendor/angular/angular.min.js"></script> <script src="vendor/angular/angular-translate.2.18.1/angular-translate-loader-static-files.min.js"></script>
<script src="vendor/angular/angular-resource.min.js"></script> <script src="vendor/angular/angular-translate.2.18.1/angular-translate-storage-cookie.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>
<!-- jquery.js --> <!--<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-translate/2.18.1/angular-translate.min.js"></script>-->
<script src="vendor/jquery.min.js" type="text/javascript"></script> <!--<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-translate/2.18.1/angular-translate-storage-cookie/angular-translate-storage-cookie.min.js"></script>-->
<script src="vendor/select2/select2.min.js" type="text/javascript"></script> <!--<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-translate/2.18.1/angular-translate-loader-static-files/angular-translate-loader-static-files.min.js"></script>-->
<!-- bootstrap.js --> <!-- jquery.js -->
<script src="vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script> <script src="vendor/jquery.min.js" type="text/javascript"></script>
<script src="vendor/select2/select2.min.js" type="text/javascript"></script>
<script type="application/javascript" src="scripts/app.js"></script> <!-- bootstrap.js -->
<script type="application/javascript" src="scripts/services/AppService.js"></script> <script src="vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></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/CommonService.js"></script>
<script type="application/javascript" src="scripts/services/FavoriteService.js"></script>
<script type="application/javascript" src="scripts/services/PermissionService.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/app.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/UserService.js"></script>
<script type="application/javascript" src="scripts/services/CommonService.js"></script>
<script type="application/javascript" src="scripts/services/FavoriteService.js"></script>
<script type="application/javascript" src="scripts/services/PermissionService.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>
</body> </body>
</html> </html>
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<html lang="en" ng-app="login"> <html lang="en" ng-app="login">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Apollo配置中心</title> <title>{{ 'Common.Title' | translate }}</title>
<link rel="icon" href="./img/config.png"> <link rel="icon" href="./img/config.png">
<link rel="stylesheet" type="text/css" href="vendor/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" type="text/css" href="vendor/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="vendor/font-awesome.min.css"> <link rel="stylesheet" href="vendor/font-awesome.min.css">
...@@ -257,7 +257,7 @@ ...@@ -257,7 +257,7 @@
</div> </div>
<div class="col-xs-12 form-group pull-right"> <div class="col-xs-12 form-group pull-right">
<input type="submit" name="login-submit" id="login-submit" tabindex="4" <input type="submit" name="login-submit" id="login-submit" tabindex="4"
class="form-control btn btn-login" value="登录"> class="form-control btn btn-login" value="{{'Login.Login' | translate }}">
</div> </div>
</form> </form>
</div> </div>
...@@ -277,6 +277,11 @@ ...@@ -277,6 +277,11 @@
<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>
<script src="vendor/angular/angular-cookies.min.js"></script>
<script src="vendor/angular/angular-translate.2.18.1/angular-translate.min.js"></script>
<script src="vendor/angular/angular-translate.2.18.1/angular-translate-loader-static-files.min.js"></script>
<script src="vendor/angular/angular-translate.2.18.1/angular-translate-storage-cookie.min.js"></script>
<script type="application/javascript" src="scripts/app.js"></script> <script type="application/javascript" src="scripts/app.js"></script>
<script type="application/javascript" src="scripts/AppUtils.js"></script> <script type="application/javascript" src="scripts/AppUtils.js"></script>
......
<!doctype html> <!doctype html>
<html ng-app="namespace"> <html ng-app="namespace">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="icon" href="./img/config.png"> <link rel="icon" href="./img/config.png">
...@@ -9,28 +10,29 @@ ...@@ -9,28 +10,29 @@
<link rel="stylesheet" type="text/css" href="vendor/select2/select2.min.css"> <link rel="stylesheet" type="text/css" href="vendor/select2/select2.min.css">
<link rel="stylesheet" type="text/css" media='all' href="vendor/angular/loading-bar.min.css"> <link rel="stylesheet" type="text/css" media='all' href="vendor/angular/loading-bar.min.css">
<link rel="stylesheet" type="text/css" href="styles/common-style.css"> <link rel="stylesheet" type="text/css" href="styles/common-style.css">
<title>新建Namespace</title> <title>{{'Namespace.Title' | translate }}</title>
</head> </head>
<body> <body>
<apollonav></apollonav> <apollonav></apollonav>
<div class="container-fluid apollo-container hidden" ng-controller="LinkNamespaceController"> <div class="container-fluid apollo-container hidden" ng-controller="LinkNamespaceController">
<div class="row"> <div class="row">
<div class="col-md-8 col-md-offset-2"> <div class="col-md-8 col-md-offset-2">
<div class="panel"> <div class="panel">
<header class="panel-heading"> <header class="panel-heading">
<div class="row"> <div class="row">
<div class="col-md-6">新建Namespace <div class="col-md-6">{{'Namespace.Title' | translate }}
<small><a target="_blank" href="https://github.com/ctripcorp/apollo/wiki/Apollo%E6%A0%B8%E5%BF%83%E6%A6%82%E5%BF%B5%E4%B9%8B%E2%80%9CNamespace%E2%80%9D"> <small><a target="_blank"
(点击了解更多Namespace相关知识) href="https://github.com/ctripcorp/apollo/wiki/Apollo%E6%A0%B8%E5%BF%83%E6%A6%82%E5%BF%B5%E4%B9%8B%E2%80%9CNamespace%E2%80%9D">
{{'Namespace.UnderstandMore' | translate }}
</a> </small> </a> </small>
</div> </div>
<div class="col-md-6 text-right"> <div class="col-md-6 text-right">
<button type="button" class="btn btn-info" ng-click="back()">返回到项目首页 <button type="button" class="btn btn-info"
</button> ng-click="back()">{{'Common.ReturnToIndex' | translate }} </button>
</div> </div>
</div> </div>
...@@ -41,33 +43,29 @@ ...@@ -41,33 +43,29 @@
<div class="alert alert-info no-radius"> <div class="alert alert-info no-radius">
<strong>Tips:</strong> <strong>Tips:</strong>
<ul ng-show="type == 'link'"> <ul ng-show="type == 'link'">
<li>应用可以通过关联公共namespace来覆盖公共Namespace的配置</li> <li>{{'Namespace.Link.Tips1' | translate }}</li>
<li>如果应用不需要覆盖公共Namespace的配置,那么无需关联公共Namespace</li> <li>{{'Namespace.Link.Tips2' | translate }}</li>
</ul> </ul>
<ul ng-show="type == 'create' && appNamespace.isPublic"> <ul ng-show="type == 'create' && appNamespace.isPublic">
<li>公共的Namespace的配置能被任何项目读取</li> <li>{{'Namespace.CreatePublic.Tips1' | translate }}</li>
<li> <li>{{'Namespace.CreatePublic.Tips2' | translate }}</li>
通过创建公共Namespace可以实现公共组件的配置,或多个应用共享同一份配置的需求 <li>{{'Namespace.CreatePublic.Tips3' | translate }}</li>
</li> <li>{{'Namespace.CreatePublic.Tips4' | translate }}</li>
<li>如果其它应用需要覆盖公共部分的配置,可以在其它应用那里关联公共Namespace,然后在关联的Namespace里面配置需要覆盖的配置即可</li>
<li>如果其它应用不需要覆盖公共部分的配置,那么就不需要在其它应用那里关联公共Namespace</li>
</ul> </ul>
<ul ng-show="type == 'create' && !appNamespace.isPublic"> <ul ng-show="type == 'create' && !appNamespace.isPublic">
<li>私有Namespace的配置只能被所属的应用获取到</li> <li>{{'Namespace.CreatePrivate.Tips1' | translate }}</li>
<li> <li>{{'Namespace.CreatePrivate.Tips2' | translate }}</li>
通过创建一个私有的Namespace可以实现分组管理配置 <li>{{'Namespace.CreatePrivate.Tips3' | translate }}</li>
</li> <li>{{'Namespace.CreatePrivate.Tips4' | translate }}</li>
<li>私有Namespace的格式可以是xml、yml、yaml、json、txt. 您可以通过apollo-client中ConfigFile接口来获取非properties格式Namespace的内容</li>
<li>1.3.0及以上版本的apollo-client针对yaml/yml提供了更好的支持,可以通过ConfigService.getConfig("someNamespace.yml")直接获取Config对象,也可以通过@EnableApolloConfig("someNamespace.yml")或apollo.bootstrap.namespaces=someNamespace.yml注入yml配置到Spring/Spring Boot中去</li>
</ul> </ul>
</div> </div>
<div class="row text-right" style="padding-right: 20px;"> <div class="row text-right" style="padding-right: 20px;">
<div class="btn-group btn-group-sm" role="group" aria-label="..."> <div class="btn-group btn-group-sm" role="group" aria-label="...">
<button type="button" class="btn btn-default" ng-class="{active:type=='link'}" <button type="button" class="btn btn-default" ng-class="{active:type=='link'}"
ng-click="switchType('link')">关联公共Namespace ng-click="switchType('link')">{{'Namespace.AssociationPublicNamespcae' | translate }}
</button> </button>
<button type="button" class="btn btn-default" ng-class="{active:type=='create'}" <button type="button" class="btn btn-default" ng-class="{active:type=='create'}"
ng-click="switchType('create')">创建Namespace ng-click="switchType('create')">{{'Namespace.CreateNamespcae' | translate }}
</button> </button>
</div> </div>
</div> </div>
...@@ -76,7 +74,7 @@ ...@@ -76,7 +74,7 @@
<form class="form-horizontal" name="namespaceForm" valdr-type="AppNamespace" <form class="form-horizontal" name="namespaceForm" valdr-type="AppNamespace"
style="margin-top: 30px;" ng-show="step == 1" ng-submit="createNamespace()"> style="margin-top: 30px;" ng-show="step == 1" ng-submit="createNamespace()">
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">AppId</label> <label class="col-sm-3 control-label">{{'Common.AppId' | translate }}</label>
<div class="col-sm-6" valdr-form-group> <div class="col-sm-6" valdr-form-group>
<label class="form-control-static" ng-bind="appId"></label> <label class="form-control-static" ng-bind="appId"></label>
</div> </div>
...@@ -85,7 +83,8 @@ ...@@ -85,7 +83,8 @@
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label"> <label class="col-sm-3 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
选择集群</label> {{'Namespace.ChooseCluster' | translate }}
</label>
<div class="col-sm-6" valdr-form-group> <div class="col-sm-6" valdr-form-group>
<apolloclusterselector apollo-app-id="appId" apollo-default-all-checked="true" <apolloclusterselector apollo-app-id="appId" apollo-default-all-checked="true"
apollo-select="collectSelectedClusters"></apolloclusterselector> apollo-select="collectSelectedClusters"></apolloclusterselector>
...@@ -95,10 +94,12 @@ ...@@ -95,10 +94,12 @@
<div class="form-group" ng-show="type == 'create'"> <div class="form-group" ng-show="type == 'create'">
<label class="col-sm-3 control-label"> <label class="col-sm-3 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
名称</label> {{'Namespace.NamespaceName' | translate }}
</label>
<div class="col-sm-5" valdr-form-group> <div class="col-sm-5" valdr-form-group>
<div ng-class="{'input-group':appNamespace.isPublic && appendNamespacePrefix}"> <div ng-class="{'input-group':appNamespace.isPublic && appendNamespacePrefix}">
<span class="input-group-addon" ng-show="appNamespace.isPublic && appendNamespacePrefix" <span class="input-group-addon"
ng-show="appNamespace.isPublic && appendNamespacePrefix"
ng-bind="appBaseInfo.namespacePrefix"></span> ng-bind="appBaseInfo.namespacePrefix"></span>
<input type="text" name="namespaceName" class="form-control" <input type="text" name="namespaceName" class="form-control"
ng-model="appNamespace.name"> ng-model="appNamespace.name">
...@@ -118,13 +119,13 @@ ...@@ -118,13 +119,13 @@
</div> </div>
&nbsp;&nbsp; &nbsp;&nbsp;
<span ng-show="appNamespace.isPublic && appendNamespacePrefix" ng-bind="concatNamespace()" <span ng-show="appNamespace.isPublic && appendNamespacePrefix"
style="line-height: 34px;"></span> ng-bind="concatNamespace()" style="line-height: 34px;"></span>
</div> </div>
<div class="form-group" ng-show="type == 'create' && appNamespace.isPublic"> <div class="form-group" ng-show="type == 'create' && appNamespace.isPublic">
<label class="col-sm-3 control-label"> <label class="col-sm-3 control-label">
自动添加部门前缀 {{'Namespace.AutoAddDepartmentPrefix' | translate }}
</label> </label>
<div class="col-sm-6" valdr-form-group> <div class="col-sm-6" valdr-form-group>
<div> <div>
...@@ -133,27 +134,29 @@ ...@@ -133,27 +134,29 @@
{{appBaseInfo.namespacePrefix}} {{appBaseInfo.namespacePrefix}}
</label> </label>
</div> </div>
<small>(公共Namespace的名称需要全局唯一,添加部门前缀有助于保证全局唯一性)</small> <small>{{'Namespace.AutoAddDepartmentPrefixTips' | translate }}</small>
</div> </div>
</div> </div>
<div class="form-group" ng-show="type == 'create' && (pageSetting.canAppAdminCreatePrivateNamespace || hasRootPermission)"> <div class="form-group"
ng-show="type == 'create' && (pageSetting.canAppAdminCreatePrivateNamespace || hasRootPermission)">
<label class="col-sm-3 control-label"> <label class="col-sm-3 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
类型</label> {{'Namespace.NamespcaeType' | translate }}
</label>
<div class="col-sm-4" valdr-form-group> <div class="col-sm-4" valdr-form-group>
<label class="radio-inline"> <label class="radio-inline">
<input type="radio" name="namespaceType" value="true" ng-value="true" <input type="radio" name="namespaceType" value="true" ng-value="true"
ng-model="appNamespace.isPublic"> public ng-model="appNamespace.isPublic"> {{'Namespace.NamespcaeType.Public' | translate }}
</label> </label>
<label class="radio-inline"> <label class="radio-inline">
<input type="radio" name="namespaceType" value="false" ng-value="false" <input type="radio" name="namespaceType" value="false" ng-value="false"
ng-model="appNamespace.isPublic"> private ng-model="appNamespace.isPublic"> {{'Namespace.NamespcaeType.Private' | translate }}
</label> </label>
</div> </div>
</div> </div>
<div class="form-group" ng-show="type == 'create'" valdr-form-group> <div class="form-group" ng-show="type == 'create'" valdr-form-group>
<label class="col-sm-3 control-label">备注</label> <label class="col-sm-3 control-label">{{'Namespace.Remark' | translate }}</label>
<div class="col-sm-7" valdr-form-group> <div class="col-sm-7" valdr-form-group>
<textarea class="form-control" rows="3" name="comment" <textarea class="form-control" rows="3" name="comment"
ng-model="appNamespace.comment"></textarea> ng-model="appNamespace.comment"></textarea>
...@@ -162,7 +165,8 @@ ...@@ -162,7 +165,8 @@
<div class="form-group" ng-show="type == 'link'"> <div class="form-group" ng-show="type == 'link'">
<label class="col-sm-3 control-label"> <label class="col-sm-3 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
namespace</label> {{'Namespace.Namespace' | translate }}
</label>
<div class="col-sm-4" valdr-form-group> <div class="col-sm-4" valdr-form-group>
<select id="namespaces"> <select id="namespaces">
<option></option> <option></option>
...@@ -174,7 +178,7 @@ ...@@ -174,7 +178,7 @@
<div class="col-sm-offset-3 col-sm-10"> <div class="col-sm-offset-3 col-sm-10">
<button type="submit" class="btn btn-primary" <button type="submit" class="btn btn-primary"
ng-disabled="(type == 'create' && namespaceForm.$invalid) || submitBtnDisabled"> ng-disabled="(type == 'create' && namespaceForm.$invalid) || submitBtnDisabled">
提交 {{'Common.Submit' | translate }}
</button> </button>
</div> </div>
</div> </div>
...@@ -182,50 +186,56 @@ ...@@ -182,50 +186,56 @@
<div class="row text-center" ng-show="step == 2"> <div class="row text-center" ng-show="step == 2">
<img src="img/sync-succ.png" style="height: 100px; width: 100px"> <img src="img/sync-succ.png" style="height: 100px; width: 100px">
<h3>创建成功!</h3> <h3>{{'Common.Created' | translate }}</h3>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>
<div ng-include="'views/common/footer.html'"></div> <div ng-include="'views/common/footer.html'"></div>
<!--angular--> <!--angular-->
<script src="vendor/angular/angular.min.js"></script> <script src="vendor/angular/angular.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>
<script src="vendor/angular/angular-cookies.min.js"></script>
<!-- jquery.js --> <script src="vendor/angular/angular-translate.2.18.1/angular-translate.min.js"></script>
<script src="vendor/jquery.min.js" type="text/javascript"></script> <script src="vendor/angular/angular-translate.2.18.1/angular-translate-loader-static-files.min.js"></script>
<script src="vendor/angular/angular-translate.2.18.1/angular-translate-storage-cookie.min.js"></script>
<script src="vendor/select2/select2.min.js" type="text/javascript"></script> <!-- jquery.js -->
<script src="vendor/jquery.min.js" type="text/javascript"></script>
<script src="vendor/select2/select2.min.js" type="text/javascript"></script>
<!-- bootstrap.js -->
<script src="vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
<script src="vendor/valdr/valdr.min.js" type="text/javascript"></script> <!-- bootstrap.js -->
<script src="vendor/valdr/valdr-message.min.js" type="text/javascript"></script> <script src="vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
<script type="application/javascript" src="scripts/app.js"></script> <script src="vendor/valdr/valdr.min.js" type="text/javascript"></script>
<script type="application/javascript" src="scripts/services/AppService.js"></script> <script src="vendor/valdr/valdr-message.min.js" type="text/javascript"></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/CommonService.js"></script>
<script type="application/javascript" src="scripts/services/NamespaceService.js"></script>
<script type="application/javascript" src="scripts/services/PermissionService.js"></script>
<script type="application/javascript" src="scripts/AppUtils.js"></script>
<!--directive--> <script type="application/javascript" src="scripts/app.js"></script>
<script type="application/javascript" src="scripts/directive/directive.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/UserService.js"></script>
<script type="application/javascript" src="scripts/services/CommonService.js"></script>
<script type="application/javascript" src="scripts/services/NamespaceService.js"></script>
<script type="application/javascript" src="scripts/services/PermissionService.js"></script>
<script type="application/javascript" src="scripts/AppUtils.js"></script>
<script type="application/javascript" src="scripts/controller/NamespaceController.js"></script> <!--directive-->
<script type="application/javascript" src="scripts/directive/directive.js"></script>
<script src="scripts/valdr.js" type="text/javascript"></script> <script type="application/javascript" src="scripts/controller/NamespaceController.js"></script>
<script src="scripts/valdr.js" type="text/javascript"></script>
</body> </body>
</html> </html>
\ No newline at end of file
<!doctype html> <!doctype html>
<html ng-app="role"> <html ng-app="role">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="icon" href="../img/config.png"> <link rel="icon" href="../img/config.png">
...@@ -9,24 +10,27 @@ ...@@ -9,24 +10,27 @@
<link rel="stylesheet" type="text/css" media='all' href="../vendor/angular/loading-bar.min.css"> <link rel="stylesheet" type="text/css" media='all' href="../vendor/angular/loading-bar.min.css">
<link rel="stylesheet" type="text/css" href="../styles/common-style.css"> <link rel="stylesheet" type="text/css" href="../styles/common-style.css">
<link rel="stylesheet" type="text/css" href="../vendor/select2/select2.min.css"> <link rel="stylesheet" type="text/css" href="../vendor/select2/select2.min.css">
<title>权限管理</title> <title>{{'Namespace.Role.Title' | translate }}</title>
</head> </head>
<body> <body>
<apollonav></apollonav> <apollonav></apollonav>
<div class="container-fluid apollo-container"> <div class="container-fluid apollo-container">
<section class="panel col-md-offset-1 col-md-10" ng-controller="NamespaceRoleController"> <section class="panel col-md-offset-1 col-md-10" ng-controller="NamespaceRoleController">
<header class="panel-heading"> <header class="panel-heading">
<div class="row"> <div class="row">
<div class="col-md-7"> <div class="col-md-7">
<h4 class="modal-title">权限管理<small>(AppId:<label ng-bind="pageContext.appId"></label> Namespace:<label ng-bind="pageContext.namespaceName"></label>)</small> <h4 class="modal-title">
{{'Namespace.Role.Title' | translate }}<small>({{'Common.AppId' | translate }}:<label
ng-bind="pageContext.appId"></label> {{'Common.Namespace' | translate }}:<label
ng-bind="pageContext.namespaceName"></label>)</small>
</h4> </h4>
</div> </div>
<div class="col-md-5 text-right"> <div class="col-md-5 text-right">
<a type="button" class="btn btn-info" data-dismiss="modal" <a type="button" class="btn btn-info" data-dismiss="modal"
href="/config.html?#appid={{pageContext.appId}}">返回到项目首页 href="/config.html?#appid={{pageContext.appId}}">{{'Common.ReturnToIndex' | translate }}
</a> </a>
</div> </div>
</div> </div>
...@@ -35,35 +39,41 @@ ...@@ -35,35 +39,41 @@
<div class="row"> <div class="row">
<div class="form-horizontal"> <div class="form-horizontal">
<div class="form-group"> <div class="form-group">
<label class="col-sm-2 control-label">修改权<br><small>(可以修改配置)</small></label> <label
class="col-sm-2 control-label">{{'Namespace.Role.GrantModifyTo' | translate }}<br><small>{{'Namespace.Role.GrantModifyT2' | translate }}</small></label>
<div class="col-sm-8"> <div class="col-sm-8">
<form class="form-inline" ng-submit="assignRoleToUser('ModifyNamespace')"> <form class="form-inline" ng-submit="assignRoleToUser('ModifyNamespace')">
<div class="form-group"> <div class="form-group">
<apollouserselector apollo-id="modifyRoleWidgetId"></apollouserselector> <apollouserselector apollo-id="modifyRoleWidgetId"></apollouserselector>
<select class="form-control input-sm" ng-model="modifyRoleSelectedEnv"> <select class="form-control input-sm" ng-model="modifyRoleSelectedEnv">
<option value="">所有环境</option> <option value="">{{'Namespace.Role.AllEnv' | translate }}</option>
<option ng-repeat="env in envs" ng-value="env">{{env}}</option> <option ng-repeat="env in envs" ng-value="env">{{env}}</option>
</select> </select>
</div> </div>
<button type="submit" class="btn btn-default" style="margin-left: 20px;" ng-disabled="modifyRoleSubmitBtnDisabled">添加</button> <button type="submit" class="btn btn-default" style="margin-left: 20px;"
ng-disabled="modifyRoleSubmitBtnDisabled">{{'Namespace.Role.Add' | translate }}</button>
</form> </form>
<!-- Split button --> <!-- Split button -->
<div class="item-container"> <div class="item-container">
<h5>所有环境</h5> <h5>{{'Namespace.Role.AllEnv' | translate }}</h5>
<div class="btn-group item-info" ng-repeat="user in rolesAssignedUsers.modifyRoleUsers"> <div class="btn-group item-info"
ng-repeat="user in rolesAssignedUsers.modifyRoleUsers">
<button type="button" class="btn btn-default" ng-bind="user.userId"></button> <button type="button" class="btn btn-default" ng-bind="user.userId"></button>
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" <button type="button" class="btn btn-default dropdown-toggle"
aria-haspopup="true" aria-expanded="false" ng-click="removeUserRole('ModifyNamespace', user.userId, null)"> data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"
ng-click="removeUserRole('ModifyNamespace', user.userId, null)">
<span class="glyphicon glyphicon-remove"></span> <span class="glyphicon glyphicon-remove"></span>
</button> </button>
</div> </div>
</div> </div>
<div class="item-container" ng-repeat="env in envs"> <div class="item-container" ng-repeat="env in envs">
<h5>{{env}}</h5> <h5>{{env}}</h5>
<div class="btn-group item-info" ng-repeat="user in envRolesAssignedUsers[env].modifyRoleUsers"> <div class="btn-group item-info"
ng-repeat="user in envRolesAssignedUsers[env].modifyRoleUsers">
<button type="button" class="btn btn-default" ng-bind="user.userId"></button> <button type="button" class="btn btn-default" ng-bind="user.userId"></button>
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" <button type="button" class="btn btn-default dropdown-toggle"
aria-haspopup="true" aria-expanded="false" ng-click="removeUserRole('ModifyNamespace', user.userId, env)"> data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"
ng-click="removeUserRole('ModifyNamespace', user.userId, env)">
<span class="glyphicon glyphicon-remove"></span> <span class="glyphicon glyphicon-remove"></span>
</button> </button>
</div> </div>
...@@ -77,26 +87,30 @@ ...@@ -77,26 +87,30 @@
<div class="row" style="margin-top: 10px;"> <div class="row" style="margin-top: 10px;">
<div class="form-horizontal"> <div class="form-horizontal">
<div class="col-sm-2 text-right"> <div class="col-sm-2 text-right">
<label class="control-label">发布权<br><small>(可以发布配置)</small></label> <label
class="control-label">{{'Namespace.Role.GrantPubishTo' | translate }}<br><small>{{'Namespace.Role.GrantPubishTo2' | translate }}</small></label>
</div> </div>
<div class="col-sm-8"> <div class="col-sm-8">
<form class="form-inline" ng-submit="assignRoleToUser('ReleaseNamespace')"> <form class="form-inline" ng-submit="assignRoleToUser('ReleaseNamespace')">
<div class="form-group"> <div class="form-group">
<apollouserselector apollo-id="releaseRoleWidgetId"></apollouserselector> <apollouserselector apollo-id="releaseRoleWidgetId"></apollouserselector>
<select class="form-control input-sm" ng-model="releaseRoleSelectedEnv"> <select class="form-control input-sm" ng-model="releaseRoleSelectedEnv">
<option value="">所有环境</option> <option value="">{{'Namespace.Role.AllEnv' | translate }}</option>
<option ng-repeat="env in envs" ng-value="env">{{env}}</option> <option ng-repeat="env in envs" ng-value="env">{{env}}</option>
</select> </select>
</div> </div>
<button type="submit" class="btn btn-default" style="margin-left: 20px;" ng-disabled="ReleaseRoleSubmitBtnDisabled">添加</button> <button type="submit" class="btn btn-default" style="margin-left: 20px;"
ng-disabled="ReleaseRoleSubmitBtnDisabled">{{'Namespace.Role.Add' | translate }}</button>
</form> </form>
<!-- Split button --> <!-- Split button -->
<div class="item-container"> <div class="item-container">
<h5>所有环境</h5> <h5>{{'Namespace.Role.AllEnv' | translate }}</h5>
<div class="btn-group item-info" ng-repeat="user in rolesAssignedUsers.releaseRoleUsers"> <div class="btn-group item-info"
ng-repeat="user in rolesAssignedUsers.releaseRoleUsers">
<button type="button" class="btn btn-default" ng-bind="user.userId"></button> <button type="button" class="btn btn-default" ng-bind="user.userId"></button>
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" <button type="button" class="btn btn-default dropdown-toggle"
aria-haspopup="true" aria-expanded="false" ng-click="removeUserRole('ReleaseNamespace', user.userId, null)"> data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"
ng-click="removeUserRole('ReleaseNamespace', user.userId, null)">
<span class="glyphicon glyphicon-remove"></span> <span class="glyphicon glyphicon-remove"></span>
</button> </button>
</div> </div>
...@@ -104,10 +118,12 @@ ...@@ -104,10 +118,12 @@
<div class="item-container" ng-repeat="env in envs"> <div class="item-container" ng-repeat="env in envs">
<h5>{{env}}</h5> <h5>{{env}}</h5>
<div class="btn-group item-info" ng-repeat="user in envRolesAssignedUsers[env].releaseRoleUsers"> <div class="btn-group item-info"
ng-repeat="user in envRolesAssignedUsers[env].releaseRoleUsers">
<button type="button" class="btn btn-default" ng-bind="user.userId"></button> <button type="button" class="btn btn-default" ng-bind="user.userId"></button>
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" <button type="button" class="btn btn-default dropdown-toggle"
aria-haspopup="true" aria-expanded="false" ng-click="removeUserRole('ReleaseNamespace', user.userId, env)"> data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"
ng-click="removeUserRole('ReleaseNamespace', user.userId, env)">
<span class="glyphicon glyphicon-remove"></span> <span class="glyphicon glyphicon-remove"></span>
</button> </button>
</div> </div>
...@@ -122,43 +138,48 @@ ...@@ -122,43 +138,48 @@
</div> </div>
<div class="panel-body text-center" ng-show="!hasAssignUserPermission"> <div class="panel-body text-center" ng-show="!hasAssignUserPermission">
<h2>您没有权限哟!</h2> <h2>{{'Namespace.Role.NoPermisson' | translate }}</h2>
</div> </div>
</section> </section>
</div> </div>
<div ng-include="'../views/common/footer.html'"></div> <div ng-include="'../views/common/footer.html'"></div>
<!-- jquery.js --> <!-- jquery.js -->
<script src="../vendor/jquery.min.js" type="text/javascript"></script> <script src="../vendor/jquery.min.js" type="text/javascript"></script>
<!--angular--> <!--angular-->
<script src="../vendor/angular/angular.min.js"></script> <script src="../vendor/angular/angular.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>
<script src="../vendor/angular/angular-cookies.min.js"></script>
<script src="../vendor/angular/angular-translate.2.18.1/angular-translate.min.js"></script>
<script src="../vendor/angular/angular-translate.2.18.1/angular-translate-loader-static-files.min.js"></script>
<script src="../vendor/angular/angular-translate.2.18.1/angular-translate-storage-cookie.min.js"></script>
<!-- bootstrap.js --> <!-- bootstrap.js -->
<script src="../vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script> <script src="../vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
<script src="../vendor/select2/select2.min.js" type="text/javascript"></script> <script src="../vendor/select2/select2.min.js" type="text/javascript"></script>
<!--biz--> <!--biz-->
<!--must import--> <!--must import-->
<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/UserService.js"></script>
<script type="application/javascript" src="../scripts/services/CommonService.js"></script> <script type="application/javascript" src="../scripts/services/CommonService.js"></script>
<script type="application/javascript" src="../scripts/services/PermissionService.js"></script> <script type="application/javascript" src="../scripts/services/PermissionService.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/PageCommon.js"></script> <script type="application/javascript" src="../scripts/PageCommon.js"></script>
<script type="application/javascript" src="../scripts/directive/directive.js"></script> <script type="application/javascript" src="../scripts/directive/directive.js"></script>
<script type="application/javascript" src="../scripts/controller/role/NamespaceRoleController.js"></script> <script type="application/javascript" src="../scripts/controller/role/NamespaceRoleController.js"></script>
</body> </body>
</html> </html>
\ No newline at end of file
<!doctype html> <!doctype html>
<html ng-app="open_manage"> <html ng-app="open_manage">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="icon" href="../img/config.png"> <link rel="icon" href="../img/config.png">
...@@ -9,23 +10,23 @@ ...@@ -9,23 +10,23 @@
<link rel="stylesheet" type="text/css" media='all' href="../vendor/angular/loading-bar.min.css"> <link rel="stylesheet" type="text/css" media='all' href="../vendor/angular/loading-bar.min.css">
<link rel="stylesheet" type="text/css" href="../styles/common-style.css"> <link rel="stylesheet" type="text/css" href="../styles/common-style.css">
<link rel="stylesheet" type="text/css" href="../vendor/select2/select2.min.css"> <link rel="stylesheet" type="text/css" href="../vendor/select2/select2.min.css">
<title>开放平台</title> <title>{{'Open.Manage.Title' | translate }}</title>
</head> </head>
<body> <body>
<apollonav></apollonav> <apollonav></apollonav>
<div class="container-fluid" ng-controller="OpenManageController"> <div class="container-fluid" ng-controller="OpenManageController">
<div class="col-md-10 col-md-offset-1 panel"> <div class="col-md-10 col-md-offset-1 panel">
<section class="panel-body" ng-show="isRootUser"> <section class="panel-body" ng-show="isRootUser">
<!--project admin--> <!--project admin-->
<section class="row"> <section class="row">
<h5>创建第三方应用 <h5>{{'Open.Manage.CreateThirdApp' | translate }}
<small> <small>
(说明: 第三方应用可以通过Apollo开放平台来对配置进行管理) {{'Open.Manage.CreateThirdAppTips' | translate }}
</small> </small>
</h5> </h5>
<hr> <hr>
...@@ -33,24 +34,25 @@ ...@@ -33,24 +34,25 @@
<div class="form-group" valdr-form-group> <div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
第三方应用ID</label> {{'Open.Manage.ThirdAppId' | translate }}
</label>
<div class="col-sm-3"> <div class="col-sm-3">
<input type="text" class="form-control" ng-model="consumer.appId"> <input type="text" class="form-control" ng-model="consumer.appId">
<small>(创建前请先查询第三方应用是否已经申请过)</small> <small>{{'Open.Manage.ThirdAppIdTips' | translate }}</small>
</div> </div>
<div class="col-sm-1"> <div class="col-sm-1">
<button class="btn btn-info" ng-click="getTokenByAppId()">查询</button> <button class="btn btn-info" ng-click="getTokenByAppId()">查询</button>
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<h4 style="color: red" <h4 style="color: red" ng-show="consumerToken"
ng-show="consumerToken"
ng-bind="'Token: ' + consumerToken.token"></h4> ng-bind="'Token: ' + consumerToken.token"></h4>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
部门</label> {{'Common.Department' | translate }}
</label>
<div class="col-sm-3"> <div class="col-sm-3">
<select id="organization"> <select id="organization">
<option></option> <option></option>
...@@ -60,16 +62,18 @@ ...@@ -60,16 +62,18 @@
<div class="form-group" valdr-form-group> <div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
第三方应用名称</label> {{'Open.Manage.ThirdAppName' | translate }}
</label>
<div class="col-sm-3"> <div class="col-sm-3">
<input type="text" class="form-control" ng-model="consumer.name"> <input type="text" class="form-control" ng-model="consumer.name">
<small>(建议格式 xx-yy-zz 例:apollo-server)</small> <small>{{'Open.Manage.ThirdAppNameTips' | translate }}</small>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
项目负责人</label> {{'Open.Manage.ProjectOwner' | translate }}
</label>
<div class="col-sm-6 J_ownerSelectorPanel"> <div class="col-sm-6 J_ownerSelectorPanel">
<apollouserselector apollo-id="'ownerSelector'"></apollouserselector> <apollouserselector apollo-id="'ownerSelector'"></apollouserselector>
</div> </div>
...@@ -77,10 +81,9 @@ ...@@ -77,10 +81,9 @@
<div class="form-group"> <div class="form-group">
<div class="col-sm-offset-2 col-sm-9"> <div class="col-sm-offset-2 col-sm-9">
<button type="submit" class="btn btn-primary" <button type="submit" class="btn btn-primary" ng-disabled="submitBtnDisabled"
ng-disabled="submitBtnDisabled"
ng-click="createConsumer()"> ng-click="createConsumer()">
创建 {{'Open.Manage.Create' | translate }}
</button> </button>
</div> </div>
</div> </div>
...@@ -88,9 +91,9 @@ ...@@ -88,9 +91,9 @@
</section> </section>
<section class="row"> <section class="row">
<h5>赋权 <h5>{{'Open.Manage.GrantPermission' | translate }}
<small> <small>
(Namespace级别权限包括: 修改、发布Namespace。应用级别权限包括: 创建Namespace、修改或发布应用下任何Namespace) {{'Open.Manage.GrantPermissionTips' | translate }}
</small> </small>
</h5> </h5>
<hr> <hr>
...@@ -99,7 +102,8 @@ ...@@ -99,7 +102,8 @@
<div class="form-group" valdr-form-group> <div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
token</label> {{'Open.Manage.Token' | translate }}
</label>
<div class="col-sm-5"> <div class="col-sm-5">
<input type="text" class="form-control" ng-model="consumerRole.token" required> <input type="text" class="form-control" ng-model="consumerRole.token" required>
</div> </div>
...@@ -107,37 +111,40 @@ ...@@ -107,37 +111,40 @@
<div class="form-group" valdr-form-group> <div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
被管理的AppId</label> {{'Open.Manage.ManagedAppId' | translate }}
</label>
<div class="col-sm-3"> <div class="col-sm-3">
<input type="text" class="form-control" ng-model="consumerRole.appId" required> <input type="text" class="form-control" ng-model="consumerRole.appId" required>
</div> </div>
</div> </div>
<div class="form-group" valdr-form-group> <div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
被管理的Namespace</label> {{'Open.Manage.ManagedNamespace' | translate }}</label>
<div class="col-sm-3"> <div class="col-sm-3">
<input type="text" class="form-control" ng-model="consumerRole.namespaceName"> <input type="text" class="form-control" ng-model="consumerRole.namespaceName">
<small>(非properties类型的namespace请加上类型后缀,例如apollo.xml)</small> <small>{{'Open.Manage.ManagedNamespaceTips' | translate }}</small>
</div> </div>
</div> </div>
<div class="form-group" valdr-form-group> <div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
授权类型 {{'Open.Manage.GrantType' | translate }}
</label> </label>
<div class="col-sm-3"> <div class="col-sm-3">
<label class="radio-inline"> <label class="radio-inline">
<input type="radio" name="inlineRadioOptions" ng-value="'NamespaceRole'" ng-model="consumerRole.type"> <input type="radio" name="inlineRadioOptions" ng-value="'NamespaceRole'"
Namespace ng-model="consumerRole.type">
{{'Open.Manage.GrantType.Namespace' | translate }}
</label> </label>
<label class="radio-inline"> <label class="radio-inline">
<input type="radio" name="inlineRadioOptions" ng-value="'AppRole'" ng-model="consumerRole.type"> <input type="radio" name="inlineRadioOptions" ng-value="'AppRole'"
App ng-model="consumerRole.type">
{{'Open.Manage.GrantType.App' | translate }}
</label> </label>
</div> </div>
</div> </div>
<div class="form-group" valdr-form-group ng-show="consumerRole.type=='NamespaceRole'"> <div class="form-group" valdr-form-group ng-show="consumerRole.type=='NamespaceRole'">
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
环境 {{'Open.Manage.GrantEnv' | translate }}
</label> </label>
<div class="col-sm-10"> <div class="col-sm-10">
<div> <div>
...@@ -146,14 +153,13 @@ ...@@ -146,14 +153,13 @@
{{env.env}} {{env.env}}
</label> </label>
</div> </div>
<small>(不选择则所有环境都有权限,如果提示Namespace's role does not exist,请先打开该Namespace的授权页面触发一下权限的初始化动作)</small> <small>{{'Open.Manage.GrantEnvTips' | translate }}</small>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="col-sm-offset-2 col-sm-9"> <div class="col-sm-offset-2 col-sm-9">
<button type="submit" class="btn btn-primary" <button type="submit" class="btn btn-primary" ng-disabled="submitBtnDisabled">
ng-disabled="submitBtnDisabled"> {{'Common.Submit' | translate }}
提交
</button> </button>
</div> </div>
</div> </div>
...@@ -164,51 +170,56 @@ ...@@ -164,51 +170,56 @@
</section> </section>
<section class="panel-body text-center" ng-if="!isRootUser"> <section class="panel-body text-center" ng-if="!isRootUser">
<h4>当前页面只对Apollo管理员开放</h4> <h4>{{'Common.IsRootUser' | translate }}</h4>
</section> </section>
</div> </div>
</div> </div>
<div ng-include="'../views/common/footer.html'"></div> <div ng-include="'../views/common/footer.html'"></div>
<!-- jquery.js --> <!-- jquery.js -->
<script src="../vendor/jquery.min.js" type="text/javascript"></script> <script src="../vendor/jquery.min.js" type="text/javascript"></script>
<!--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-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>
<script src="../vendor/angular/angular-cookies.min.js"></script>
<!--valdr--> <script src="../vendor/angular/angular-translate.2.18.1/angular-translate.min.js"></script>
<script src="../vendor/valdr/valdr.min.js" type="text/javascript"></script> <script src="../vendor/angular/angular-translate.2.18.1/angular-translate-loader-static-files.min.js"></script>
<script src="../vendor/valdr/valdr-message.min.js" type="text/javascript"></script> <script src="../vendor/angular/angular-translate.2.18.1/angular-translate-storage-cookie.min.js"></script>
<!--valdr-->
<script src="../vendor/valdr/valdr.min.js" type="text/javascript"></script>
<script src="../vendor/valdr/valdr-message.min.js" type="text/javascript"></script>
<!-- bootstrap.js --> <!-- bootstrap.js -->
<script src="../vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script> <script src="../vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
<script src="../vendor/lodash.min.js"></script> <script src="../vendor/lodash.min.js"></script>
<script src="../vendor/select2/select2.min.js" type="text/javascript"></script> <script src="../vendor/select2/select2.min.js" type="text/javascript"></script>
<!--biz--> <!--biz-->
<!--must import--> <!--must import-->
<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/UserService.js"></script>
<script type="application/javascript" src="../scripts/services/CommonService.js"></script> <script type="application/javascript" src="../scripts/services/CommonService.js"></script>
<script type="application/javascript" src="../scripts/services/PermissionService.js"></script> <script type="application/javascript" src="../scripts/services/PermissionService.js"></script>
<script type="application/javascript" src="../scripts/services/OrganizationService.js"></script> <script type="application/javascript" src="../scripts/services/OrganizationService.js"></script>
<script type="application/javascript" src="../scripts/services/ConsumerService.js"></script> <script type="application/javascript" src="../scripts/services/ConsumerService.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/PageCommon.js"></script> <script type="application/javascript" src="../scripts/PageCommon.js"></script>
<script type="application/javascript" src="../scripts/directive/directive.js"></script> <script type="application/javascript" src="../scripts/directive/directive.js"></script>
<script type="application/javascript" src="../scripts/valdr.js"></script> <script type="application/javascript" src="../scripts/valdr.js"></script>
<script type="application/javascript" src="../scripts/controller/open/OpenManageController.js"></script> <script type="application/javascript" src="../scripts/controller/open/OpenManageController.js"></script>
</body> </body>
</html> </html>
\ No newline at end of file
appUtil.service('AppUtil', ['toastr', '$window', '$q', function (toastr, $window, $q) { appUtil.service('AppUtil', ['toastr', '$window', '$q', '$translate', function (toastr, $window, $q, $translate) {
function parseErrorMsg(response) { function parseErrorMsg(response) {
if (response.status == -1) { if (response.status == -1) {
return "您的登录信息已过期,请刷新页面后重试"; return $translate.instant('Common.LoginExprieTips');
} }
var msg = "Code:" + response.status; var msg = "Code:" + response.status;
if (response.data.message != null) { if (response.data.message != null) {
...@@ -13,7 +13,7 @@ appUtil.service('AppUtil', ['toastr', '$window', '$q', function (toastr, $window ...@@ -13,7 +13,7 @@ appUtil.service('AppUtil', ['toastr', '$window', '$q', function (toastr, $window
function parsePureErrorMsg(response) { function parsePureErrorMsg(response) {
if (response.status == -1) { if (response.status == -1) {
return "您的登录信息已过期,请刷新页面后重试"; return $translate.instant('Common.LoginExprieTips');
} }
if (response.data.message != null) { if (response.data.message != null) {
return response.data.message; return response.data.message;
...@@ -92,7 +92,7 @@ appUtil.service('AppUtil', ['toastr', '$window', '$q', function (toastr, $window ...@@ -92,7 +92,7 @@ appUtil.service('AppUtil', ['toastr', '$window', '$q', function (toastr, $window
hideModal: function (modal) { hideModal: function (modal) {
$(modal).modal("hide"); $(modal).modal("hide");
}, },
checkIPV4:function (ip) { checkIPV4: function (ip) {
return /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$|^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/.test(ip); return /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$|^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/.test(ip);
} }
} }
......
/**utils*/ /**utils*/
var appUtil = angular.module('app.util', ['toastr']); var appUtil = angular.module('app.util', ['toastr', 'ngCookies', 'pascalprecht.translate'])
.config(['$translateProvider', function ($translateProvider) {
// $translateProvider.useMissingTranslationHandlerLog();
$translateProvider.useCookieStorage();
$translateProvider.useStaticFilesLoader({
prefix: '/i18n/',
suffix: '.json'
});
$translateProvider.preferredLanguage('en');
$translateProvider.fallbackLanguage('zh-cn');
}]);
/**service module 定义*/ /**service module 定义*/
var appService = angular.module('app.service', ['ngResource']); var appService = angular.module('app.service', ['ngResource', 'app.util'])
/** directive */ /** directive */
var directive_module = angular.module('apollo.directive', ['app.service', 'app.util', 'toastr']); var directive_module = angular.module('apollo.directive', ['app.service', 'app.util', 'toastr', 'pascalprecht.translate']);
/** page module 定义*/ /** page module 定义*/
// 首页 // 首页
var index_module = angular.module('index', ['toastr', 'app.service', 'apollo.directive', 'app.util', 'angular-loading-bar']); var index_module = angular.module('index', ['toastr', 'app.service', 'apollo.directive', 'app.util', 'angular-loading-bar', 'pascalprecht.translate']);
//项目主页 //项目主页
var application_module = angular.module('application', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar', 'valdr', 'ui.ace']); var application_module = angular.module('application', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar', 'valdr', 'ui.ace', 'ngSanitize']);
//创建项目页面 //创建项目页面
var app_module = angular.module('create_app', ['apollo.directive', 'toastr', 'app.service', 'app.util', 'angular-loading-bar', 'valdr']); var app_module = angular.module('create_app', ['apollo.directive', 'toastr', 'app.service', 'app.util', 'angular-loading-bar', 'valdr','pascalprecht.translate']);
//配置同步页面 //配置同步页面
var sync_item_module = angular.module('sync_item', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar']); var sync_item_module = angular.module('sync_item', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar']);
// 比较页面 // 比较页面
...@@ -27,7 +39,7 @@ var setting_module = angular.module('setting', ['app.service', 'apollo.directive ...@@ -27,7 +39,7 @@ var setting_module = angular.module('setting', ['app.service', 'apollo.directive
//role //role
var role_module = angular.module('role', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar']); var role_module = angular.module('role', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar']);
//cluster //cluster
var cluster_module = angular.module('cluster', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar' , 'valdr']); var cluster_module = angular.module('cluster', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar', 'valdr']);
//release history //release history
var release_history_module = angular.module('release_history', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar']); var release_history_module = angular.module('release_history', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar']);
//open manage //open manage
...@@ -35,7 +47,7 @@ var open_manage_module = angular.module('open_manage', ['app.service', 'apollo.d ...@@ -35,7 +47,7 @@ var open_manage_module = angular.module('open_manage', ['app.service', 'apollo.d
//user //user
var user_module = angular.module('user', ['apollo.directive', 'toastr', 'app.service', 'app.util', 'angular-loading-bar', 'valdr']); var user_module = angular.module('user', ['apollo.directive', 'toastr', 'app.service', 'app.util', 'angular-loading-bar', 'valdr']);
//login //login
var login_module = angular.module('login', ['toastr', 'app.util']); var login_module = angular.module('login', ['app.service', 'toastr', 'app.util', 'pascalprecht.translate']);
//delete app cluster namespace //delete app cluster namespace
var delete_app_cluster_namespace_module = angular.module('delete_app_cluster_namespace', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar']); var delete_app_cluster_namespace_module = angular.module('delete_app_cluster_namespace', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar']);
//system info //system info
......
app_module.controller('CreateAppController', app_module.controller('CreateAppController',
['$scope', '$window', 'toastr', 'AppService', 'AppUtil', 'OrganizationService','SystemRoleService','UserService', ['$scope', '$window', '$translate', 'toastr', 'AppService', 'AppUtil', 'OrganizationService', 'SystemRoleService', 'UserService',
createAppController]); createAppController]);
function createAppController($scope, $window, toastr, AppService, AppUtil, OrganizationService, SystemRoleService, UserService) { function createAppController($scope, $window, $translate, toastr, AppService, AppUtil, OrganizationService, SystemRoleService, UserService) {
$scope.app = {}; $scope.app = {};
$scope.submitBtnDisabled = false; $scope.submitBtnDisabled = false;
...@@ -27,7 +27,7 @@ function createAppController($scope, $window, toastr, AppService, AppUtil, Organ ...@@ -27,7 +27,7 @@ function createAppController($scope, $window, toastr, AppService, AppUtil, Organ
organizations.push(org); organizations.push(org);
}); });
$('#organization').select2({ $('#organization').select2({
placeholder: '请选择部门', placeholder: $translate.instant('Common.PelaseChooseDepartment'),
width: '100%', width: '100%',
data: organizations data: organizations
}); });
...@@ -60,7 +60,7 @@ function createAppController($scope, $window, toastr, AppService, AppUtil, Organ ...@@ -60,7 +60,7 @@ function createAppController($scope, $window, toastr, AppService, AppUtil, Organ
var selectedOrg = $('#organization').select2('data')[0]; var selectedOrg = $('#organization').select2('data')[0];
if (!selectedOrg.id) { if (!selectedOrg.id) {
toastr.warning("请选择部门"); toastr.warning($translate.instant('Common.PelaseChooseDepartment'));
$scope.submitBtnDisabled = false; $scope.submitBtnDisabled = false;
return; return;
} }
...@@ -71,10 +71,10 @@ function createAppController($scope, $window, toastr, AppService, AppUtil, Organ ...@@ -71,10 +71,10 @@ function createAppController($scope, $window, toastr, AppService, AppUtil, Organ
// owner // owner
var owner = $('.ownerSelector').select2('data')[0]; var owner = $('.ownerSelector').select2('data')[0];
if ($scope.isOpenManageAppMasterRoleLimit) { if ($scope.isOpenManageAppMasterRoleLimit) {
owner = {id: $scope.currentUser.userId}; owner = { id: $scope.currentUser.userId };
} }
if (!owner) { if (!owner) {
toastr.warning("请选择应用负责人"); toastr.warning($translate.instant('Common.PelaseChooseOwner'));
$scope.submitBtnDisabled = false; $scope.submitBtnDisabled = false;
return; return;
} }
...@@ -84,7 +84,7 @@ function createAppController($scope, $window, toastr, AppService, AppUtil, Organ ...@@ -84,7 +84,7 @@ function createAppController($scope, $window, toastr, AppService, AppUtil, Organ
$scope.app.admins = []; $scope.app.admins = [];
var admins = $(".adminSelector").select2('data'); var admins = $(".adminSelector").select2('data');
if ($scope.isOpenManageAppMasterRoleLimit) { if ($scope.isOpenManageAppMasterRoleLimit) {
admins = [{id: $scope.currentUser.userId}]; admins = [{ id: $scope.currentUser.userId }];
} }
if (admins) { if (admins) {
admins.forEach(function (admin) { admins.forEach(function (admin) {
...@@ -93,14 +93,14 @@ function createAppController($scope, $window, toastr, AppService, AppUtil, Organ ...@@ -93,14 +93,14 @@ function createAppController($scope, $window, toastr, AppService, AppUtil, Organ
} }
AppService.create($scope.app).then(function (result) { AppService.create($scope.app).then(function (result) {
toastr.success('创建成功!'); toastr.success($translate.instant('Common.Created'));
setInterval(function () { setInterval(function () {
$scope.submitBtnDisabled = false; $scope.submitBtnDisabled = false;
$window.location.href = '/config.html?#appid=' + result.appId; $window.location.href = '/config.html?#appid=' + result.appId;
}, 1000); }, 1000);
}, function (result) { }, function (result) {
$scope.submitBtnDisabled = false; $scope.submitBtnDisabled = false;
toastr.error(AppUtil.errorMsg(result), '创建失败!'); toastr.error(AppUtil.errorMsg(result), $translate.instant('Common.CreateFailed'));
}); });
} }
......
cluster_module.controller('ClusterController', cluster_module.controller('ClusterController',
['$scope', '$location', '$window', 'toastr', 'AppService', 'EnvService', 'ClusterService', ['$scope', '$location', '$window', '$translate', 'toastr', 'AppService', 'EnvService', 'ClusterService',
'AppUtil', 'AppUtil',
function ($scope, $location, $window, toastr, AppService, EnvService, ClusterService, function ($scope, $location, $window, $translate, toastr, AppService, EnvService, ClusterService,
AppUtil) { AppUtil) {
var params = AppUtil.parseParams($location.$$url); var params = AppUtil.parseParams($location.$$url);
...@@ -14,12 +14,12 @@ cluster_module.controller('ClusterController', ...@@ -14,12 +14,12 @@ cluster_module.controller('ClusterController',
EnvService.find_all_envs().then(function (result) { EnvService.find_all_envs().then(function (result) {
$scope.envs = []; $scope.envs = [];
result.forEach(function (env) { result.forEach(function (env) {
$scope.envs.push({name: env, checked: false}); $scope.envs.push({ name: env, checked: false });
}); });
$(".apollo-container").removeClass("hidden"); $(".apollo-container").removeClass("hidden");
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "加载环境信息出错"); toastr.error(AppUtil.errorMsg(result), $translate.instant('Cluster.LoadingEnvironmentError'));
}); });
$scope.clusterName = ''; $scope.clusterName = '';
...@@ -45,18 +45,18 @@ cluster_module.controller('ClusterController', ...@@ -45,18 +45,18 @@ cluster_module.controller('ClusterController',
name: $scope.clusterName, name: $scope.clusterName,
appId: $scope.appId appId: $scope.appId
}).then(function (result) { }).then(function (result) {
toastr.success(env.name, "集群创建成功"); toastr.success(env.name, $translate.instant('Cluster.ClusterCreated'));
$scope.step = 2; $scope.step = 2;
$scope.submitBtnDisabled = false; $scope.submitBtnDisabled = false;
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "集群创建失败"); toastr.error(AppUtil.errorMsg(result), $translate.instant('Cluster.ClusterCreateFailed'));
$scope.submitBtnDisabled = false; $scope.submitBtnDisabled = false;
}) })
} }
}); });
if (noEnvChecked){ if (noEnvChecked) {
toastr.warning("请选择环境"); toastr.warning($translate.instant('Cluster.PleaseChooseEnvironment'));
} }
}; };
......
delete_app_cluster_namespace_module.controller('DeleteAppClusterNamespaceController', delete_app_cluster_namespace_module.controller('DeleteAppClusterNamespaceController',
['$scope', 'toastr', 'AppUtil', 'AppService', 'ClusterService', 'NamespaceService', 'PermissionService', ['$scope', '$translate', 'toastr', 'AppUtil', 'AppService', 'ClusterService', 'NamespaceService', 'PermissionService',
DeleteAppClusterNamespaceController]); DeleteAppClusterNamespaceController]);
function DeleteAppClusterNamespaceController($scope, toastr, AppUtil, AppService, ClusterService, NamespaceService, PermissionService) { function DeleteAppClusterNamespaceController($scope, $translate, toastr, AppUtil, AppService, ClusterService, NamespaceService, PermissionService) {
$scope.app = {}; $scope.app = {};
$scope.deleteAppBtnDisabled = true; $scope.deleteAppBtnDisabled = true;
...@@ -30,7 +30,7 @@ function DeleteAppClusterNamespaceController($scope, toastr, AppUtil, AppService ...@@ -30,7 +30,7 @@ function DeleteAppClusterNamespaceController($scope, toastr, AppUtil, AppService
function getAppInfo() { function getAppInfo() {
if (!$scope.app.appId) { if (!$scope.app.appId) {
toastr.warning("请输入appId"); toastr.warning($translate.instant('Delete.PleaseEnterAppId'));
return; return;
} }
...@@ -38,12 +38,18 @@ function DeleteAppClusterNamespaceController($scope, toastr, AppUtil, AppService ...@@ -38,12 +38,18 @@ function DeleteAppClusterNamespaceController($scope, toastr, AppUtil, AppService
AppService.load($scope.app.appId).then(function (result) { AppService.load($scope.app.appId).then(function (result) {
if (!result.appId) { if (!result.appId) {
toastr.warning("AppId: " + $scope.app.appId + " 不存在!"); toastr.warning($translate.instant('Delete.AppIdNotFound', { appId: $scope.app.appId }));
$scope.deleteAppBtnDisabled = true; $scope.deleteAppBtnDisabled = true;
return; return;
} }
$scope.app.info = "应用名:" + result.name + " 部门:" + result.orgName + '(' + result.orgId + ')' + " 负责人:" + result.ownerName; $scope.app.info = $translate.instant('Delete.AppInfoContent', {
appName: result.name,
departmentName: result.orgName,
departmentId: result.orgId,
ownerName: result.ownerName
});
$scope.deleteAppBtnDisabled = false; $scope.deleteAppBtnDisabled = false;
}, function (result) { }, function (result) {
...@@ -53,12 +59,12 @@ function DeleteAppClusterNamespaceController($scope, toastr, AppUtil, AppService ...@@ -53,12 +59,12 @@ function DeleteAppClusterNamespaceController($scope, toastr, AppUtil, AppService
function deleteApp() { function deleteApp() {
if (!$scope.app.appId) { if (!$scope.app.appId) {
toastr.warning("请输入appId"); toastr.warning($translate.instant('Delete.PleaseEnterAppId'));
return; return;
} }
if (confirm("确认删除AppId: " + $scope.app.appId + "")) { if (confirm($translate.instant('Delete.PleaseEnterAppId', { appId: $scope.app.appId }))) {
AppService.delete_app($scope.app.appId).then(function (result) { AppService.delete_app($scope.app.appId).then(function (result) {
toastr.success("删除成功"); toastr.success($translate.instant('Delete.Deleted'));
$scope.deleteAppBtnDisabled = true; $scope.deleteAppBtnDisabled = true;
}, function (result) { }, function (result) {
AppUtil.showErrorMsg(result); AppUtil.showErrorMsg(result);
...@@ -68,14 +74,18 @@ function DeleteAppClusterNamespaceController($scope, toastr, AppUtil, AppService ...@@ -68,14 +74,18 @@ function DeleteAppClusterNamespaceController($scope, toastr, AppUtil, AppService
function getClusterInfo() { function getClusterInfo() {
if (!$scope.cluster.appId || !$scope.cluster.env || !$scope.cluster.name) { if (!$scope.cluster.appId || !$scope.cluster.env || !$scope.cluster.name) {
toastr.warning("请输入appId、环境和集群名称"); toastr.warning($translate.instant('Delete.PleaseEnterAppIdAndEnvAndCluster'));
return; return;
} }
$scope.cluster.info = ""; $scope.cluster.info = "";
ClusterService.load_cluster($scope.cluster.appId, $scope.cluster.env, $scope.cluster.name).then(function (result) { ClusterService.load_cluster($scope.cluster.appId, $scope.cluster.env, $scope.cluster.name).then(function (result) {
$scope.cluster.info = "AppId:" + result.appId+ " 环境:" + $scope.cluster.env + " 集群名称:" + result.name; $scope.cluster.info = $translate.instant('Delete.ClusterInfoContent', {
appId: result.appId,
env: $scope.cluster.env,
clusterName: result.name
});
$scope.deleteClusterBtnDisabled = false; $scope.deleteClusterBtnDisabled = false;
}, function (result) { }, function (result) {
...@@ -85,12 +95,18 @@ function DeleteAppClusterNamespaceController($scope, toastr, AppUtil, AppService ...@@ -85,12 +95,18 @@ function DeleteAppClusterNamespaceController($scope, toastr, AppUtil, AppService
function deleteCluster() { function deleteCluster() {
if (!$scope.cluster.appId || !$scope.cluster.env || !$scope.cluster.name) { if (!$scope.cluster.appId || !$scope.cluster.env || !$scope.cluster.name) {
toastr.warning("请输入appId、环境和集群名称"); toastr.warning($translate.instant('Delete.PleaseEnterAppIdAndEnvAndCluster'));
return; return;
} }
if (confirm("确认删除集群?appId: " + $scope.cluster.appId + " 环境:" + $scope.cluster.env + " 集群名称:" + $scope.cluster.name)) { var confirmTip = $translate.instant('Delete.ConfirmDeleteCluster', {
appId: result.appId,
env: $scope.cluster.env,
clusterName: result.name
});
if (confirm(confirmTip)) {
ClusterService.delete_cluster($scope.cluster.appId, $scope.cluster.env, $scope.cluster.name).then(function (result) { ClusterService.delete_cluster($scope.cluster.appId, $scope.cluster.env, $scope.cluster.name).then(function (result) {
toastr.success("删除成功"); toastr.success($translate.instant('Delete.Deleted'));
$scope.deleteClusterBtnDisabled = true; $scope.deleteClusterBtnDisabled = true;
}, function (result) { }, function (result) {
AppUtil.showErrorMsg(result); AppUtil.showErrorMsg(result);
...@@ -100,14 +116,18 @@ function DeleteAppClusterNamespaceController($scope, toastr, AppUtil, AppService ...@@ -100,14 +116,18 @@ function DeleteAppClusterNamespaceController($scope, toastr, AppUtil, AppService
function getAppNamespaceInfo() { function getAppNamespaceInfo() {
if (!$scope.appNamespace.appId || !$scope.appNamespace.name) { if (!$scope.appNamespace.appId || !$scope.appNamespace.name) {
toastr.warning("请输入appId和AppNamespace名称"); toastr.warning($translate.instant('Delete.PleaseEnterAppIdAndNamespace'));
return; return;
} }
$scope.appNamespace.info = ""; $scope.appNamespace.info = "";
NamespaceService.loadAppNamespace($scope.appNamespace.appId, $scope.appNamespace.name).then(function (result) { NamespaceService.loadAppNamespace($scope.appNamespace.appId, $scope.appNamespace.name).then(function (result) {
$scope.appNamespace.info = "AppId:" + result.appId+ " AppNamespace名称:" + result.name + " isPublic:" + result.isPublic; $scope.appNamespace.info = $translate.instant('Delete.AppNamespaceInfoContent', {
appId: result.appId,
namespace: result.name,
isPublic: result.isPublic
});
$scope.deleteAppNamespaceBtnDisabled = false; $scope.deleteAppNamespaceBtnDisabled = false;
}, function (result) { }, function (result) {
...@@ -117,12 +137,16 @@ function DeleteAppClusterNamespaceController($scope, toastr, AppUtil, AppService ...@@ -117,12 +137,16 @@ function DeleteAppClusterNamespaceController($scope, toastr, AppUtil, AppService
function deleteAppNamespace() { function deleteAppNamespace() {
if (!$scope.appNamespace.appId || !$scope.appNamespace.name) { if (!$scope.appNamespace.appId || !$scope.appNamespace.name) {
toastr.warning("请输入appId和AppNamespace名称"); toastr.warning($translate.instant('Delete.PleaseEnterAppIdAndNamespace'));
return; return;
} }
if (confirm("确认删除所有环境的AppNamespace和Namespace?appId: " + $scope.appNamespace.appId + " 环境:所有环境" + " AppNamespace名称:" + $scope.appNamespace.name)) { var confirmTip = $translate.instant('Delete.ConfirmDeleteNamespace', {
appId: $scope.appNamespace.appId,
namespace: $scope.appNamespace.name
});
if (confirm(confirmTip)) {
NamespaceService.deleteAppNamespace($scope.appNamespace.appId, $scope.appNamespace.name).then(function (result) { NamespaceService.deleteAppNamespace($scope.appNamespace.appId, $scope.appNamespace.name).then(function (result) {
toastr.success("删除成功"); toastr.success($translate.instant('Delete.Deleted'));
$scope.deleteAppNamespaceBtnDisabled = true; $scope.deleteAppNamespaceBtnDisabled = true;
}, function (result) { }, function (result) {
AppUtil.showErrorMsg(result); AppUtil.showErrorMsg(result);
......
index_module.controller('IndexController', ['$scope', '$window', 'toastr', 'AppUtil', 'AppService', index_module.controller('IndexController', ['$scope', '$window', '$translate', 'toastr', 'AppUtil', 'AppService',
'UserService', 'FavoriteService', 'UserService', 'FavoriteService',
IndexController]); IndexController]);
function IndexController($scope, $window, toastr, AppUtil, AppService, UserService, FavoriteService) { function IndexController($scope, $window, $translate, toastr, AppUtil, AppService, UserService, FavoriteService) {
$scope.userId = ''; $scope.userId = '';
...@@ -21,7 +21,7 @@ function IndexController($scope, $window, toastr, AppUtil, AppService, UserServi ...@@ -21,7 +21,7 @@ function IndexController($scope, $window, toastr, AppUtil, AppService, UserServi
$scope.hasCreateApplicationPermission = value.hasCreateApplicationPermission; $scope.hasCreateApplicationPermission = value.hasCreateApplicationPermission;
}, },
function (reason) { function (reason) {
toastr.warning(AppUtil.errorMsg(reason), "获取创建应用权限信息失败"); toastr.warning(AppUtil.errorMsg(reason), $translate.instant('Index.GetCreateAppRoleFailed'));
} }
) )
} }
...@@ -70,7 +70,7 @@ function IndexController($scope, $window, toastr, AppUtil, AppService, UserServi ...@@ -70,7 +70,7 @@ function IndexController($scope, $window, toastr, AppUtil, AppService, UserServi
$scope.favoritesPage += 1; $scope.favoritesPage += 1;
$scope.hasMoreFavorites = result.length == size; $scope.hasMoreFavorites = result.length == size;
if ($scope.favoritesPage == 1){ if ($scope.favoritesPage == 1) {
$("#app-list").removeClass("hidden"); $("#app-list").removeClass("hidden");
} }
...@@ -92,7 +92,7 @@ function IndexController($scope, $window, toastr, AppUtil, AppService, UserServi ...@@ -92,7 +92,7 @@ function IndexController($scope, $window, toastr, AppUtil, AppService, UserServi
}); });
result.forEach(function (favorite) { result.forEach(function (favorite) {
var app = appIdMapApp[favorite.appId]; var app = appIdMapApp[favorite.appId];
if (!app){ if (!app) {
return; return;
} }
app.favoriteId = favorite.id; app.favoriteId = favorite.id;
...@@ -122,7 +122,7 @@ function IndexController($scope, $window, toastr, AppUtil, AppService, UserServi ...@@ -122,7 +122,7 @@ function IndexController($scope, $window, toastr, AppUtil, AppService, UserServi
userVisitedApps.forEach(function (appId) { userVisitedApps.forEach(function (appId) {
var app = appIdMapApp[appId]; var app = appIdMapApp[appId];
if (app){ if (app) {
$scope.visitedApps.push(app); $scope.visitedApps.push(app);
} }
}); });
...@@ -145,7 +145,7 @@ function IndexController($scope, $window, toastr, AppUtil, AppService, UserServi ...@@ -145,7 +145,7 @@ function IndexController($scope, $window, toastr, AppUtil, AppService, UserServi
function toTop(favoriteId) { function toTop(favoriteId) {
FavoriteService.toTop(favoriteId).then(function () { FavoriteService.toTop(favoriteId).then(function () {
toastr.success("置顶成功"); toastr.success($translate.instant('Index.Topped'));
refreshFavorites(); refreshFavorites();
}) })
...@@ -153,7 +153,7 @@ function IndexController($scope, $window, toastr, AppUtil, AppService, UserServi ...@@ -153,7 +153,7 @@ function IndexController($scope, $window, toastr, AppUtil, AppService, UserServi
function deleteFavorite(favoriteId) { function deleteFavorite(favoriteId) {
FavoriteService.deleteFavorite(favoriteId).then(function () { FavoriteService.deleteFavorite(favoriteId).then(function () {
toastr.success("取消收藏成功"); toastr.success($translate.instant('Index.CancelledFavorite'));
refreshFavorites(); refreshFavorites();
}) })
} }
......
login_module.controller('LoginController', login_module.controller('LoginController',
['$scope', '$window', '$location', 'toastr', 'AppUtil', ['$scope', '$window', '$location', '$translate', 'toastr', 'AppUtil',
LoginController]); LoginController]);
function LoginController($scope, $window, $location, toastr, AppUtil) { function LoginController($scope, $window, $location, $translate, toastr, AppUtil) {
if ($location.$$url) { if ($location.$$url) {
var params = AppUtil.parseParams($location.$$url); var params = AppUtil.parseParams($location.$$url);
if (params.error) { if (params.error) {
$scope.info = "用户名或密码错误"; $translate('Login.UserNameOrPasswordIncorrect').then(function(result) {
$scope.info = result;
})
} }
if (params.logout) { if (params.logout) {
$scope.info = "登出成功"; $scope.info = $translate.instant('Login.LogoutSuccessfully');
} }
} }
......
namespace_module.controller("LinkNamespaceController", namespace_module.controller("LinkNamespaceController",
['$scope', '$location', '$window', 'toastr', 'AppService', 'AppUtil', 'NamespaceService', ['$scope', '$location', '$window', '$translate', 'toastr', 'AppService', 'AppUtil', 'NamespaceService',
'PermissionService', 'CommonService', 'PermissionService', 'CommonService',
function ($scope, $location, $window, toastr, AppService, AppUtil, NamespaceService, function ($scope, $location, $window, $translate, toastr, AppService, AppUtil, NamespaceService,
PermissionService, CommonService) { PermissionService, CommonService) {
var params = AppUtil.parseParams($location.$$url); var params = AppUtil.parseParams($location.$$url);
...@@ -30,20 +30,20 @@ namespace_module.controller("LinkNamespaceController", ...@@ -30,20 +30,20 @@ namespace_module.controller("LinkNamespaceController",
publicNamespaces.push(namespace); publicNamespaces.push(namespace);
}); });
$('#namespaces').select2({ $('#namespaces').select2({
placeholder: '请选择Namespace', placeholder: $translate.instant('Namespace.PleaseChooseNamespace'),
width: '100%', width: '100%',
data: publicNamespaces data: publicNamespaces
}); });
$(".apollo-container").removeClass("hidden"); $(".apollo-container").removeClass("hidden");
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "load public namespace error"); toastr.error(AppUtil.errorMsg(result), $translate.instant('Namespace.LoadingPublicNamespaceError'));
}); });
AppService.load($scope.appId).then(function (result) { AppService.load($scope.appId).then(function (result) {
$scope.appBaseInfo = result; $scope.appBaseInfo = result;
$scope.appBaseInfo.namespacePrefix = result.orgId + '.'; $scope.appBaseInfo.namespacePrefix = result.orgId + '.';
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "加载App信息出错"); toastr.error(AppUtil.errorMsg(result), $translate.instant('Namespace.LoadingAppInfoError'));
}); });
$scope.appNamespace = { $scope.appNamespace = {
...@@ -73,14 +73,14 @@ namespace_module.controller("LinkNamespaceController", ...@@ -73,14 +73,14 @@ namespace_module.controller("LinkNamespaceController",
$scope.createNamespace = function () { $scope.createNamespace = function () {
if ($scope.type == 'link') { if ($scope.type == 'link') {
if (selectedClusters.length == 0) { if (selectedClusters.length == 0) {
toastr.warning("请选择集群"); toastr.warning($translate.instant('Namespace.PleaseChooseCluster'));
return; return;
} }
if ($scope.namespaceType == 1) { if ($scope.namespaceType == 1) {
var selectedNamespaceName = $('#namespaces').select2('data')[0].id; var selectedNamespaceName = $('#namespaces').select2('data')[0].id;
if (!selectedNamespaceName) { if (!selectedNamespaceName) {
toastr.warning("请选择Namespace"); toastr.warning($translate.instant('Namespace.PleaseChooseNamespace'));
return; return;
} }
...@@ -102,7 +102,7 @@ namespace_module.controller("LinkNamespaceController", ...@@ -102,7 +102,7 @@ namespace_module.controller("LinkNamespaceController",
$scope.submitBtnDisabled = true; $scope.submitBtnDisabled = true;
NamespaceService.createNamespace($scope.appId, namespaceCreationModels) NamespaceService.createNamespace($scope.appId, namespaceCreationModels)
.then(function (result) { .then(function (result) {
toastr.success("创建成功"); toastr.success($translate.instant('Common.Created'));
$scope.step = 2; $scope.step = 2;
setInterval(function () { setInterval(function () {
$scope.submitBtnDisabled = false; $scope.submitBtnDisabled = false;
...@@ -118,10 +118,11 @@ namespace_module.controller("LinkNamespaceController", ...@@ -118,10 +118,11 @@ namespace_module.controller("LinkNamespaceController",
var namespaceNameLength = $scope.concatNamespace().length; var namespaceNameLength = $scope.concatNamespace().length;
if (namespaceNameLength > 32) { if (namespaceNameLength > 32) {
toastr.error("namespace名称不能大于32个字符. 部门前缀" var errorTip = $translate.instant('Namespace.ChecknamespaceNameLengthTip', {
+ (namespaceNameLength - $scope.appNamespace.name.length) departmentLength: namespaceNameLength - $scope.appNamespace.name.length,
+ "个字符, 名称" + $scope.appNamespace.name.length + "个字符" namespaceLength: $scope.appNamespace.name.length
); });
toastr.error(errorTip);
return; return;
} }
...@@ -139,7 +140,7 @@ namespace_module.controller("LinkNamespaceController", ...@@ -139,7 +140,7 @@ namespace_module.controller("LinkNamespaceController",
}, 1000); }, 1000);
}, function (result) { }, function (result) {
$scope.submitBtnDisabled = false; $scope.submitBtnDisabled = false;
toastr.error(AppUtil.errorMsg(result), "创建失败"); toastr.error(AppUtil.errorMsg(result), $translate.instant('Common.CreateFailed'));
}); });
} }
......
server_config_module.controller('ServerConfigController', server_config_module.controller('ServerConfigController',
['$scope', '$window', 'toastr', 'ServerConfigService', 'AppUtil', ['$scope', '$window', '$translate', 'toastr', 'ServerConfigService', 'AppUtil',
function ($scope, $window, toastr, ServerConfigService, AppUtil) { function ($scope, $window, $translate, toastr, ServerConfigService, AppUtil) {
$scope.serverConfig = {}; $scope.serverConfig = {};
$scope.saveBtnDisabled = true; $scope.saveBtnDisabled = true;
$scope.create = function () { $scope.create = function () {
ServerConfigService.create($scope.serverConfig).then(function (result) { ServerConfigService.create($scope.serverConfig).then(function (result) {
toastr.success("保存成功"); toastr.success($translate.instant('SericeConfig.Saved'));
$scope.saveBtnDisabled = true; $scope.saveBtnDisabled = true;
$scope.serverConfig = result; $scope.serverConfig = result;
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "保存失败"); toastr.error(AppUtil.errorMsg(result), $translate.instant('SericeConfig.SaveFailed'));
}); });
}; };
$scope.getServerConfigInfo = function () { $scope.getServerConfigInfo = function () {
if (!$scope.serverConfig.key) { if (!$scope.serverConfig.key) {
toastr.warning("请输入key"); toastr.warning($translate.instant('SericeConfig.PleaseEnterKey'));
return; return;
} }
...@@ -25,11 +25,11 @@ server_config_module.controller('ServerConfigController', ...@@ -25,11 +25,11 @@ server_config_module.controller('ServerConfigController',
$scope.saveBtnDisabled = false; $scope.saveBtnDisabled = false;
if (!result.key) { if (!result.key) {
toastr.info("Key: " + $scope.serverConfig.key + " 不存在,点击保存后会创建该配置项"); toastr.info($translate.instant('SericeConfig.KeyNotExistsAndCreateTip', { key: $scope.serverConfig.key }));
return; return;
} }
toastr.info("Key: " + $scope.serverConfig.key + " 已存在,点击保存后会覆盖该配置项"); toastr.info($translate.instant('SericeConfig.KeyExistsAndSaveTip', { key: $scope.serverConfig.key }));
$scope.serverConfig = result; $scope.serverConfig = result;
}, function (result) { }, function (result) {
AppUtil.showErrorMsg(result); AppUtil.showErrorMsg(result);
......
setting_module.controller('SettingController', setting_module.controller('SettingController',
['$scope', '$location', 'toastr', ['$scope', '$location', '$translate', 'toastr',
'AppService', 'AppUtil', 'PermissionService', 'AppService', 'AppUtil', 'PermissionService',
'OrganizationService', 'OrganizationService',
SettingController]); SettingController]);
function SettingController($scope, $location, toastr, function SettingController($scope, $location, $translate, toastr,
AppService, AppUtil, PermissionService, AppService, AppUtil, PermissionService,
OrganizationService) { OrganizationService) {
...@@ -49,7 +49,7 @@ function SettingController($scope, $location, toastr, ...@@ -49,7 +49,7 @@ function SettingController($scope, $location, toastr,
organizations.push(org); organizations.push(org);
}); });
$orgWidget.select2({ $orgWidget.select2({
placeholder: '请选择部门', placeholder: $translate.instant('Common.PelaseChooseDepartment'),
width: '100%', width: '100%',
data: organizations data: organizations
}); });
...@@ -115,7 +115,7 @@ function SettingController($scope, $location, toastr, ...@@ -115,7 +115,7 @@ function SettingController($scope, $location, toastr,
function assignMasterRoleToUser() { function assignMasterRoleToUser() {
var user = $('.' + $scope.userSelectWidgetId).select2('data')[0]; var user = $('.' + $scope.userSelectWidgetId).select2('data')[0];
if (!user) { if (!user) {
toastr.warning("请选择用户"); toastr.warning($translate.instant('App.Setting.PleaseChooseUser'));
return; return;
} }
var toAssignMasterRoleUser = user.id; var toAssignMasterRoleUser = user.id;
...@@ -124,12 +124,12 @@ function SettingController($scope, $location, toastr, ...@@ -124,12 +124,12 @@ function SettingController($scope, $location, toastr,
toAssignMasterRoleUser) toAssignMasterRoleUser)
.then(function (result) { .then(function (result) {
$scope.submitBtnDisabled = false; $scope.submitBtnDisabled = false;
toastr.success("添加成功"); toastr.success($translate.instant('App.Setting.Added'));
$scope.appRoleUsers.masterUsers.push({userId: toAssignMasterRoleUser}); $scope.appRoleUsers.masterUsers.push({ userId: toAssignMasterRoleUser });
$('.' + $scope.userSelectWidgetId).select2("val", ""); $('.' + $scope.userSelectWidgetId).select2("val", "");
}, function (result) { }, function (result) {
$scope.submitBtnDisabled = false; $scope.submitBtnDisabled = false;
toastr.error(AppUtil.errorMsg(result), "添加失败"); toastr.error(AppUtil.errorMsg(result), $translate.instant('App.Setting.AddFailed'));
}); });
} }
...@@ -140,10 +140,10 @@ function SettingController($scope, $location, toastr, ...@@ -140,10 +140,10 @@ function SettingController($scope, $location, toastr,
} }
PermissionService.remove_master_role($scope.pageContext.appId, user) PermissionService.remove_master_role($scope.pageContext.appId, user)
.then(function (result) { .then(function (result) {
toastr.success("删除成功"); toastr.success($translate.instant('App.Setting.Deleted'));
removeUserFromList($scope.appRoleUsers.masterUsers, user); removeUserFromList($scope.appRoleUsers.masterUsers, user);
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "删除失败"); toastr.error(AppUtil.errorMsg(result), $translate.instant('App.Setting.DeleteFailed'));
}); });
} }
...@@ -177,7 +177,7 @@ function SettingController($scope, $location, toastr, ...@@ -177,7 +177,7 @@ function SettingController($scope, $location, toastr,
var selectedOrg = $orgWidget.select2('data')[0]; var selectedOrg = $orgWidget.select2('data')[0];
if (!selectedOrg.id) { if (!selectedOrg.id) {
toastr.warning("请选择部门"); toastr.warning($translate.instant('Common.PelaseChooseDepartment'));
return; return;
} }
...@@ -187,13 +187,13 @@ function SettingController($scope, $location, toastr, ...@@ -187,13 +187,13 @@ function SettingController($scope, $location, toastr,
// owner // owner
var owner = $('.ownerSelector').select2('data')[0]; var owner = $('.ownerSelector').select2('data')[0];
if (!owner) { if (!owner) {
toastr.warning("请选择应用负责人"); toastr.warning($translate.instant('Common.PelaseChooseOwner'));
return; return;
} }
app.ownerName = owner.id; app.ownerName = owner.id;
AppService.update(app).then(function (app) { AppService.update(app).then(function (app) {
toastr.success("修改成功"); toastr.success($translate.instant('Common.Modifed'));
initApplication(); initApplication();
$scope.display.app.edit = false; $scope.display.app.edit = false;
$scope.submitBtnDisabled = false; $scope.submitBtnDisabled = false;
......
user_module.controller('UserController', user_module.controller('UserController',
['$scope', '$window', 'toastr', 'AppUtil', 'UserService', ['$scope', '$window', '$translate', 'toastr', 'AppUtil', 'UserService',
UserController]); UserController]);
function UserController($scope, $window, toastr, AppUtil, UserService) { function UserController($scope, $window, $translate, toastr, AppUtil, UserService) {
$scope.user = {}; $scope.user = {};
$scope.createOrUpdateUser = function () { $scope.createOrUpdateUser = function () {
UserService.createOrUpdateUser($scope.user).then(function (result) { UserService.createOrUpdateUser($scope.user).then(function (result) {
toastr.success("创建用户成功"); toastr.success($translate.instant('UserMange.Created'));
}, function (result) { }, function (result) {
AppUtil.showErrorMsg(result, "创建用户失败"); AppUtil.showErrorMsg(result, $translate.instant('UserMange.CreateFailed'));
}) })
} }
......
application_module.controller("ConfigBaseInfoController", application_module.controller("ConfigBaseInfoController",
['$rootScope', '$scope', '$window', '$location', 'toastr', 'EventManager', 'UserService', ['$rootScope', '$scope', '$window', '$location', '$translate', 'toastr', 'EventManager', 'UserService',
'AppService', 'AppService',
'FavoriteService', 'FavoriteService',
'PermissionService', 'PermissionService',
'AppUtil', ConfigBaseInfoController]); 'AppUtil', ConfigBaseInfoController]);
function ConfigBaseInfoController($rootScope, $scope, $window, $location, toastr, EventManager, UserService, AppService, function ConfigBaseInfoController($rootScope, $scope, $window, $location, $translate, toastr, EventManager, UserService, AppService,
FavoriteService, FavoriteService,
PermissionService, PermissionService,
AppUtil) { AppUtil) {
...@@ -45,7 +45,7 @@ function ConfigBaseInfoController($rootScope, $scope, $window, $location, toastr ...@@ -45,7 +45,7 @@ function ConfigBaseInfoController($rootScope, $scope, $window, $location, toastr
loadAppInfo(); loadAppInfo();
handleFavorite(); handleFavorite();
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "获取用户登录信息失败"); toastr.error(AppUtil.errorMsg(result), $translate.instant('Config.GetrUserInfoFailed'));
}); });
handlePermission(); handlePermission();
...@@ -74,13 +74,13 @@ function ConfigBaseInfoController($rootScope, $scope, $window, $location, toastr ...@@ -74,13 +74,13 @@ function ConfigBaseInfoController($rootScope, $scope, $window, $location, toastr
var count = 0; var count = 0;
$scope.missEnvs.forEach(function (env) { $scope.missEnvs.forEach(function (env) {
AppService.create_remote(env, $scope.appBaseInfo).then(function (result) { AppService.create_remote(env, $scope.appBaseInfo).then(function (result) {
toastr.success(env, '创建成功'); toastr.success(env, $translate.instant('Common.Created'));
count++; count++;
if (count == $scope.missEnvs.length) { if (count == $scope.missEnvs.length) {
location.reload(true); location.reload(true);
} }
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), '创建失败:' + env); toastr.error(AppUtil.errorMsg(result), `${$translate.instant('Common.CreateFailed')}:${env}`);
count++; count++;
if (count == $scope.missEnvs.length) { if (count == $scope.missEnvs.length) {
location.reload(true); location.reload(true);
...@@ -92,10 +92,10 @@ function ConfigBaseInfoController($rootScope, $scope, $window, $location, toastr ...@@ -92,10 +92,10 @@ function ConfigBaseInfoController($rootScope, $scope, $window, $location, toastr
$scope.createMissingNamespaces = function () { $scope.createMissingNamespaces = function () {
AppService.create_missing_namespaces($rootScope.pageContext.appId, $rootScope.pageContext.env, AppService.create_missing_namespaces($rootScope.pageContext.appId, $rootScope.pageContext.env,
$rootScope.pageContext.clusterName).then(function (result) { $rootScope.pageContext.clusterName).then(function (result) {
toastr.success("创建成功"); toastr.success($translate.instant('Common.Created'));
location.reload(true); location.reload(true);
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "创建失败"); toastr.error(AppUtil.errorMsg(result), $translate.instant('Common.CreateFailed'));
} }
); );
}; };
...@@ -106,7 +106,7 @@ function ConfigBaseInfoController($rootScope, $scope, $window, $location, toastr ...@@ -106,7 +106,7 @@ function ConfigBaseInfoController($rootScope, $scope, $window, $location, toastr
$scope.missEnvs = AppUtil.collectData(result); $scope.missEnvs = AppUtil.collectData(result);
if ($scope.missEnvs.length > 0) { if ($scope.missEnvs.length > 0) {
toastr.warning("当前项目有环境缺失,请点击页面左侧『补缺环境』补齐数据"); toastr.warning($translate.instant('Config.ProjectMissEnvInfos'));
} }
$scope.findMissingNamespaces(); $scope.findMissingNamespaces();
...@@ -125,7 +125,7 @@ function ConfigBaseInfoController($rootScope, $scope, $window, $location, toastr ...@@ -125,7 +125,7 @@ function ConfigBaseInfoController($rootScope, $scope, $window, $location, toastr
$rootScope.pageContext.clusterName).then(function (result) { $rootScope.pageContext.clusterName).then(function (result) {
$scope.missingNamespaces = AppUtil.collectData(result); $scope.missingNamespaces = AppUtil.collectData(result);
if ($scope.missingNamespaces.length > 0) { if ($scope.missingNamespaces.length > 0) {
toastr.warning("当前环境有Namespace缺失,请点击页面左侧『补缺Namespace』补齐数据"); toastr.warning($translate.instant('Config.ProjectMissNamespaceInfos'));
} }
}); });
} }
...@@ -176,7 +176,7 @@ function ConfigBaseInfoController($rootScope, $scope, $window, $location, toastr ...@@ -176,7 +176,7 @@ function ConfigBaseInfoController($rootScope, $scope, $window, $location, toastr
var nodes = AppUtil.collectData(result); var nodes = AppUtil.collectData(result);
if (!nodes || nodes.length == 0) { if (!nodes || nodes.length == 0) {
toastr.error("系统出错,请重试或联系系统负责人"); toastr.error($translate.instant('Config.SystemError'));
return; return;
} }
//default first env if session storage is empty //default first env if session storage is empty
...@@ -220,7 +220,7 @@ function ConfigBaseInfoController($rootScope, $scope, $window, $location, toastr ...@@ -220,7 +220,7 @@ function ConfigBaseInfoController($rootScope, $scope, $window, $location, toastr
clusterNode.text = cluster.name; clusterNode.text = cluster.name;
parentNode.push(node.text); parentNode.push(node.text);
clusterNode.tags = ['集群']; clusterNode.tags = [$translate.instant('Common.Cluster')];
clusterNode.parentNode = parentNode; clusterNode.parentNode = parentNode;
clusterNodes.push(clusterNode); clusterNodes.push(clusterNode);
...@@ -289,7 +289,7 @@ function ConfigBaseInfoController($rootScope, $scope, $window, $location, toastr ...@@ -289,7 +289,7 @@ function ConfigBaseInfoController($rootScope, $scope, $window, $location, toastr
$rootScope.envMapClusters = envMapClusters; $rootScope.envMapClusters = envMapClusters;
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "系统出错,请重试或联系系统负责人"); toastr.error(AppUtil.errorMsg(result), $translate.instant('Config.SystemError'));
}); });
} }
...@@ -314,9 +314,9 @@ function ConfigBaseInfoController($rootScope, $scope, $window, $location, toastr ...@@ -314,9 +314,9 @@ function ConfigBaseInfoController($rootScope, $scope, $window, $location, toastr
FavoriteService.addFavorite(favorite) FavoriteService.addFavorite(favorite)
.then(function (result) { .then(function (result) {
$scope.favoriteId = result.id; $scope.favoriteId = result.id;
toastr.success("收藏成功"); toastr.success($translate.instant('Config.FavoriteSuccessfully'));
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "收藏失败"); toastr.error(AppUtil.errorMsg(result), $translate.instant('Config.FavoriteFailed'));
}) })
}; };
...@@ -324,9 +324,9 @@ function ConfigBaseInfoController($rootScope, $scope, $window, $location, toastr ...@@ -324,9 +324,9 @@ function ConfigBaseInfoController($rootScope, $scope, $window, $location, toastr
FavoriteService.deleteFavorite($scope.favoriteId) FavoriteService.deleteFavorite($scope.favoriteId)
.then(function (result) { .then(function (result) {
$scope.favoriteId = 0; $scope.favoriteId = 0;
toastr.success("取消收藏成功"); toastr.success($translate.instant('Config.CancelledFavorite'));
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "取消收藏失败"); toastr.error(AppUtil.errorMsg(result), $translate.instant('Config.CanceFavoriteFailed'));
}) })
}; };
} }
......
application_module.controller("ConfigNamespaceController", application_module.controller("ConfigNamespaceController",
['$rootScope', '$scope', 'toastr', 'AppUtil', 'EventManager', 'ConfigService', ['$rootScope', '$scope', '$translate', 'toastr', 'AppUtil', 'EventManager', 'ConfigService',
'PermissionService', 'UserService', 'NamespaceBranchService', 'NamespaceService', 'PermissionService', 'UserService', 'NamespaceBranchService', 'NamespaceService',
controller]); controller]);
function controller($rootScope, $scope, toastr, AppUtil, EventManager, ConfigService, function controller($rootScope, $scope, $translate, toastr, AppUtil, EventManager, ConfigService,
PermissionService, UserService, NamespaceBranchService, NamespaceService) { PermissionService, UserService, NamespaceBranchService, NamespaceService) {
$scope.rollback = rollback; $scope.rollback = rollback;
...@@ -24,12 +24,10 @@ function controller($rootScope, $scope, toastr, AppUtil, EventManager, ConfigSer ...@@ -24,12 +24,10 @@ function controller($rootScope, $scope, toastr, AppUtil, EventManager, ConfigSer
init(); init();
function init() { function init() {
initRole(); initRole();
initUser(); initUser();
initPublishInfo(); initPublishInfo();
} }
function initRole() { function initRole() {
PermissionService.get_app_role_users($rootScope.pageContext.appId) PermissionService.get_app_role_users($rootScope.pageContext.appId)
.then(function (result) { .then(function (result) {
...@@ -111,7 +109,7 @@ function controller($rootScope, $scope, toastr, AppUtil, EventManager, ConfigSer ...@@ -111,7 +109,7 @@ function controller($rootScope, $scope, toastr, AppUtil, EventManager, ConfigSer
initPublishInfo(); initPublishInfo();
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "加载配置信息出错"); toastr.error(AppUtil.errorMsg(result), $translate.instant('Config.LoadingAllNamespaceError'));
}); });
} }
...@@ -138,7 +136,7 @@ function controller($rootScope, $scope, toastr, AppUtil, EventManager, ConfigSer ...@@ -138,7 +136,7 @@ function controller($rootScope, $scope, toastr, AppUtil, EventManager, ConfigSer
initPublishInfo(); initPublishInfo();
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "加载配置信息出错"); toastr.error(AppUtil.errorMsg(result), $translate.instant('Config.LoadingAllNamespaceError'));
}); });
} }
...@@ -170,13 +168,13 @@ function controller($rootScope, $scope, toastr, AppUtil, EventManager, ConfigSer ...@@ -170,13 +168,13 @@ function controller($rootScope, $scope, toastr, AppUtil, EventManager, ConfigSer
$scope.toOperationNamespace.baseInfo.namespaceName, $scope.toOperationNamespace.baseInfo.namespaceName,
toDeleteItemId).then( toDeleteItemId).then(
function (result) { function (result) {
toastr.success("删除成功!"); toastr.success($translate.instant('Config.Deleted'));
EventManager.emit(EventManager.EventType.REFRESH_NAMESPACE, EventManager.emit(EventManager.EventType.REFRESH_NAMESPACE,
{ {
namespace: $scope.toOperationNamespace namespace: $scope.toOperationNamespace
}); });
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "删除失败"); toastr.error(AppUtil.errorMsg(result), $translate.instant('Config.DeleteFailed'));
}); });
} }
...@@ -280,13 +278,13 @@ function controller($rootScope, $scope, toastr, AppUtil, EventManager, ConfigSer ...@@ -280,13 +278,13 @@ function controller($rootScope, $scope, toastr, AppUtil, EventManager, ConfigSer
$rootScope.pageContext.clusterName, $rootScope.pageContext.clusterName,
toCreateBranchNamespace.baseInfo.namespaceName) toCreateBranchNamespace.baseInfo.namespaceName)
.then(function (result) { .then(function (result) {
toastr.success("创建灰度成功"); toastr.success($translate.instant('Config.GrayscaleCreated'));
EventManager.emit(EventManager.EventType.REFRESH_NAMESPACE, EventManager.emit(EventManager.EventType.REFRESH_NAMESPACE,
{ {
namespace: toCreateBranchNamespace namespace: toCreateBranchNamespace
}); });
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "创建灰度失败"); toastr.error(AppUtil.errorMsg(result), $translate.instant('Config.GrayscaleCreateFailed'));
}) })
} }
...@@ -306,13 +304,13 @@ function controller($rootScope, $scope, toastr, AppUtil, EventManager, ConfigSer ...@@ -306,13 +304,13 @@ function controller($rootScope, $scope, toastr, AppUtil, EventManager, ConfigSer
$scope.toDeleteBranch.baseInfo.clusterName $scope.toDeleteBranch.baseInfo.clusterName
) )
.then(function (result) { .then(function (result) {
toastr.success("删除成功"); toastr.success($translate.instant('Config.BranchDeleted'));
EventManager.emit(EventManager.EventType.REFRESH_NAMESPACE, EventManager.emit(EventManager.EventType.REFRESH_NAMESPACE,
{ {
namespace: $scope.toDeleteBranch.parentNamespace namespace: $scope.toDeleteBranch.parentNamespace
}); });
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "删除分支失败"); toastr.error(AppUtil.errorMsg(result), $translate.instant('Config.BranchDeleteFailed'));
}) })
} }
...@@ -357,13 +355,11 @@ function controller($rootScope, $scope, toastr, AppUtil, EventManager, ConfigSer ...@@ -357,13 +355,11 @@ function controller($rootScope, $scope, toastr, AppUtil, EventManager, ConfigSer
var url = '/config.html?#/appid=' + appId + '&env=' + $scope.pageContext.env + '&cluster=' var url = '/config.html?#/appid=' + appId + '&env=' + $scope.pageContext.env + '&cluster='
+ clusterName; + clusterName;
namespaceTips.push("<a target='_blank' href=\'" + url + "\'>AppId = " + appId + ", 集群 = " + clusterName namespaceTips.push("<a target='_blank' href=\'" + url + "\'>AppId = " + appId + ", Cluster = " + clusterName
+ ", Namespace = " + namespace.namespaceName + "</a>"); + ", Namespace = " + namespace.namespaceName + "</a>");
}); });
$scope.deleteNamespaceContext.detailReason = $scope.deleteNamespaceContext.detailReason = $translate.instant('Config.DeleteNamespaceFailedTips') + "<br>" + namespaceTips.join("<br>");
"以下应用已关联此公共Namespace,必须先删除全部已关联的Namespace才能删除公共Namespace。<br>"
+ namespaceTips.join("<br>");
AppUtil.showModal('#deleteNamespaceDenyForPublicNamespaceDialog'); AppUtil.showModal('#deleteNamespaceDenyForPublicNamespaceDialog');
} }
......
diff_item_module.controller("DiffItemController", diff_item_module.controller("DiffItemController",
['$scope', '$location', '$window', 'toastr', 'AppService', 'AppUtil', 'ConfigService', ['$scope', '$location', '$window', '$translate', 'toastr', 'AppService', 'AppUtil', 'ConfigService',
function ($scope, $location, $window, toastr, AppService, AppUtil, ConfigService) { function ($scope, $location, $window, $translate, toastr, AppService, AppUtil, ConfigService) {
var params = AppUtil.parseParams($location.$$url); var params = AppUtil.parseParams($location.$$url);
$scope.pageContext = { $scope.pageContext = {
...@@ -33,7 +33,7 @@ diff_item_module.controller("DiffItemController", ...@@ -33,7 +33,7 @@ diff_item_module.controller("DiffItemController",
function diff() { function diff() {
$scope.syncData = parseSyncSourceData(); $scope.syncData = parseSyncSourceData();
if ($scope.syncData.syncToNamespaces.length < 2) { if ($scope.syncData.syncToNamespaces.length < 2) {
toastr.warning("请至少选择两个集群"); toastr.warning($translate.instant('Config.Diff.PleaseChooseTwoCluster'));
return; return;
} }
$scope.syncData.syncToNamespaces.forEach(function (namespace) { $scope.syncData.syncToNamespaces.forEach(function (namespace) {
...@@ -93,4 +93,4 @@ diff_item_module.controller("DiffItemController", ...@@ -93,4 +93,4 @@ diff_item_module.controller("DiffItemController",
$scope.text = text; $scope.text = text;
AppUtil.showModal('#showTextModal'); AppUtil.showModal('#showTextModal');
} }
}]); }]);
release_history_module.controller("ReleaseHistoryController", release_history_module.controller("ReleaseHistoryController",
['$scope', '$location', 'AppUtil', ['$scope', '$location', '$translate', 'AppUtil',
'ReleaseService', 'ConfigService', 'ReleaseHistoryService', releaseHistoryController 'ReleaseService', 'ConfigService', 'ReleaseHistoryService', releaseHistoryController
]); ]);
function releaseHistoryController($scope, $location, AppUtil, function releaseHistoryController($scope, $location, $translate, AppUtil,
ReleaseService, ConfigService, ReleaseHistoryService) { ReleaseService, ConfigService, ReleaseHistoryService) {
var params = AppUtil.parseParams($location.$$url); var params = AppUtil.parseParams($location.$$url);
...@@ -87,7 +87,7 @@ function releaseHistoryController($scope, $location, AppUtil, ...@@ -87,7 +87,7 @@ function releaseHistoryController($scope, $location, AppUtil,
$scope.page = $scope.page + 1; $scope.page = $scope.page + 1;
}, function (result) { }, function (result) {
AppUtil.showErrorMsg(result, "加载发布历史信息出错"); AppUtil.showErrorMsg(result, $translate.instant('Config.History.LoadingHistoryError'));
}); });
} }
......
sync_item_module.controller("SyncItemController", sync_item_module.controller("SyncItemController",
['$scope', '$location', '$window', 'toastr', 'AppService', 'AppUtil', 'ConfigService', ['$scope', '$location', '$window', '$translate', 'toastr', 'AppService', 'AppUtil', 'ConfigService',
function ($scope, $location, $window, toastr, AppService, AppUtil, ConfigService) { function ($scope, $location, $window, $translate, toastr, AppService, AppUtil, ConfigService) {
var params = AppUtil.parseParams($location.$$url); var params = AppUtil.parseParams($location.$$url);
$scope.pageContext = { $scope.pageContext = {
...@@ -50,7 +50,7 @@ sync_item_module.controller("SyncItemController", ...@@ -50,7 +50,7 @@ sync_item_module.controller("SyncItemController",
$scope.viewItems = sourceItems; $scope.viewItems = sourceItems;
$(".apollo-container").removeClass("hidden"); $(".apollo-container").removeClass("hidden");
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "加载配置出错"); toastr.error(AppUtil.errorMsg(result), $translate.instant('Config.Sync.LoadingItemsError'));
}); });
} }
...@@ -71,11 +71,11 @@ sync_item_module.controller("SyncItemController", ...@@ -71,11 +71,11 @@ sync_item_module.controller("SyncItemController",
function diff() { function diff() {
parseSyncSourceData(); parseSyncSourceData();
if (syncData.syncItems.length == 0) { if (syncData.syncItems.length == 0) {
toastr.warning("请选择需要同步的配置"); toastr.warning($translate.instant('Config.Sync.PleaseChooseNeedSyncItems'));
return; return;
} }
if (syncData.syncToNamespaces.length == 0) { if (syncData.syncToNamespaces.length == 0) {
toastr.warning("请选择集群"); toastr.warning($translate.instant('Config.Sync.PleaseChooseCluster'));
return; return;
} }
$scope.hasDiff = false; $scope.hasDiff = false;
......
open_manage_module.controller('OpenManageController', open_manage_module.controller('OpenManageController',
['$scope', 'toastr', 'AppUtil', 'OrganizationService', 'ConsumerService', 'PermissionService','EnvService', ['$scope', '$translate', 'toastr', 'AppUtil', 'OrganizationService', 'ConsumerService', 'PermissionService', 'EnvService',
OpenManageController]); OpenManageController]);
function OpenManageController($scope, toastr, AppUtil, OrganizationService, ConsumerService, PermissionService, EnvService) { function OpenManageController($scope, $translate, toastr, AppUtil, OrganizationService, ConsumerService, PermissionService, EnvService) {
var $orgWidget = $('#organization'); var $orgWidget = $('#organization');
...@@ -35,7 +35,7 @@ function OpenManageController($scope, toastr, AppUtil, OrganizationService, Cons ...@@ -35,7 +35,7 @@ function OpenManageController($scope, toastr, AppUtil, OrganizationService, Cons
organizations.push(org); organizations.push(org);
}); });
$orgWidget.select2({ $orgWidget.select2({
placeholder: '请选择部门', placeholder: $translate.instant('Common.PelaseChooseDepartment'),
width: '100%', width: '100%',
data: organizations data: organizations
}); });
...@@ -53,10 +53,10 @@ function OpenManageController($scope, toastr, AppUtil, OrganizationService, Cons ...@@ -53,10 +53,10 @@ function OpenManageController($scope, toastr, AppUtil, OrganizationService, Cons
function initEnv() { function initEnv() {
EnvService.find_all_envs() EnvService.find_all_envs()
.then(function (result){ .then(function (result) {
$scope.envs = new Array(); $scope.envs = new Array();
for (var iLoop = 0; iLoop < result.length; iLoop++) { for (var iLoop = 0; iLoop < result.length; iLoop++) {
$scope.envs.push({ checked : false, env : result[iLoop] }); $scope.envs.push({ checked: false, env: result[iLoop] });
$scope.envsChecked = new Array(); $scope.envsChecked = new Array();
} }
...@@ -75,7 +75,7 @@ function OpenManageController($scope, toastr, AppUtil, OrganizationService, Cons ...@@ -75,7 +75,7 @@ function OpenManageController($scope, toastr, AppUtil, OrganizationService, Cons
function getTokenByAppId() { function getTokenByAppId() {
if (!$scope.consumer.appId) { if (!$scope.consumer.appId) {
toastr.warning("请输入appId"); toastr.warning($translate.instant('Open.Manage.PleaseEnterAppId'));
return; return;
} }
...@@ -86,7 +86,9 @@ function OpenManageController($scope, toastr, AppUtil, OrganizationService, Cons ...@@ -86,7 +86,9 @@ function OpenManageController($scope, toastr, AppUtil, OrganizationService, Cons
$scope.consumerToken = consumerToken; $scope.consumerToken = consumerToken;
$scope.consumerRole.token = consumerToken.token; $scope.consumerRole.token = consumerToken.token;
} else { } else {
$scope.consumerToken = {token: 'App(' + $scope.consumer.appId + ')未创建,请先创建'}; $scope.consumerToken = {
token: $translate.instant('Open.Manage.AppNotCreated', { appId: $scope.consumer.appId })
};
} }
}); });
} }
...@@ -95,13 +97,13 @@ function OpenManageController($scope, toastr, AppUtil, OrganizationService, Cons ...@@ -95,13 +97,13 @@ function OpenManageController($scope, toastr, AppUtil, OrganizationService, Cons
$scope.submitBtnDisabled = true; $scope.submitBtnDisabled = true;
if (!$scope.consumer.appId) { if (!$scope.consumer.appId) {
toastr.warning("请输入appId"); toastr.warning($translate.instant('Open.Manage.PleaseEnterAppId'));
return; return;
} }
var selectedOrg = $orgWidget.select2('data')[0]; var selectedOrg = $orgWidget.select2('data')[0];
if (!selectedOrg.id) { if (!selectedOrg.id) {
toastr.warning("请选择部门"); toastr.warning($translate.instant('Common.PelaseChooseDepartment'));
return; return;
} }
...@@ -111,20 +113,20 @@ function OpenManageController($scope, toastr, AppUtil, OrganizationService, Cons ...@@ -111,20 +113,20 @@ function OpenManageController($scope, toastr, AppUtil, OrganizationService, Cons
// owner // owner
var owner = $('.ownerSelector').select2('data')[0]; var owner = $('.ownerSelector').select2('data')[0];
if (!owner) { if (!owner) {
toastr.warning("请选择应用负责人"); toastr.warning($translate.instant('Common.PelaseChooseOwner'));
return; return;
} }
$scope.consumer.ownerName = owner.id; $scope.consumer.ownerName = owner.id;
ConsumerService.createConsumer($scope.consumer) ConsumerService.createConsumer($scope.consumer)
.then(function (consumerToken) { .then(function (consumerToken) {
toastr.success("创建成功"); toastr.success($translate.instant('Common.Created'));
$scope.consumerToken = consumerToken; $scope.consumerToken = consumerToken;
$scope.consumerRole.token = consumerToken.token; $scope.consumerRole.token = consumerToken.token;
$scope.submitBtnDisabled = false; $scope.submitBtnDisabled = false;
$scope.consumer = {}; $scope.consumer = {};
}, function (response) { }, function (response) {
AppUtil.showErrorMsg(response, "创建失败"); AppUtil.showErrorMsg(response, $translate.instant('Common.CreateFailed'));
$scope.submitBtnDisabled = false; $scope.submitBtnDisabled = false;
}) })
...@@ -137,9 +139,9 @@ function OpenManageController($scope, toastr, AppUtil, OrganizationService, Cons ...@@ -137,9 +139,9 @@ function OpenManageController($scope, toastr, AppUtil, OrganizationService, Cons
$scope.consumerRole.namespaceName, $scope.consumerRole.namespaceName,
$scope.envsChecked) $scope.envsChecked)
.then(function (consumerRoles) { .then(function (consumerRoles) {
toastr.success("赋权成功"); toastr.success($translate.instant('Open.Manage.GrantSuccessfully'));
}, function (response) { }, function (response) {
AppUtil.showErrorMsg(response, "赋权失败"); AppUtil.showErrorMsg(response, $translate.instant('Open.Manage.GrantFailed'));
}) })
} }
......
role_module.controller('NamespaceRoleController', role_module.controller('NamespaceRoleController',
['$scope', '$location', '$window', 'toastr', 'AppService', 'UserService', 'AppUtil', 'EnvService', ['$scope', '$location', '$window', '$translate', 'toastr', 'AppService', 'UserService', 'AppUtil', 'EnvService',
'PermissionService', 'PermissionService',
function ($scope, $location, $window, toastr, AppService, UserService, AppUtil, EnvService, function ($scope, $location, $window, $translate, toastr, AppService, UserService, AppUtil, EnvService,
PermissionService) { PermissionService) {
var params = AppUtil.parseParams($location.$$url); var params = AppUtil.parseParams($location.$$url);
...@@ -22,8 +22,8 @@ role_module.controller('NamespaceRoleController', ...@@ -22,8 +22,8 @@ role_module.controller('NamespaceRoleController',
PermissionService.init_app_namespace_permission($scope.pageContext.appId, $scope.pageContext.namespaceName) PermissionService.init_app_namespace_permission($scope.pageContext.appId, $scope.pageContext.namespaceName)
.then(function (result) { .then(function (result) {
}, function(result) { }, function (result) {
toastr.warn(AppUtil.errorMsg(result), "初始化授权出错"); toastr.warn(AppUtil.errorMsg(result), $translate.instant('Namespace.Role.InitNamespacePermissionError'));
}); });
PermissionService.has_assign_user_permission($scope.pageContext.appId) PermissionService.has_assign_user_permission($scope.pageContext.appId)
...@@ -34,7 +34,7 @@ role_module.controller('NamespaceRoleController', ...@@ -34,7 +34,7 @@ role_module.controller('NamespaceRoleController',
}); });
EnvService.find_all_envs() EnvService.find_all_envs()
.then(function (result){ .then(function (result) {
$scope.envs = result; $scope.envs = result;
$scope.envRolesAssignedUsers = {}; $scope.envRolesAssignedUsers = {};
for (var iLoop = 0; iLoop < result.length; iLoop++) { for (var iLoop = 0; iLoop < result.length; iLoop++) {
...@@ -42,8 +42,8 @@ role_module.controller('NamespaceRoleController', ...@@ -42,8 +42,8 @@ role_module.controller('NamespaceRoleController',
PermissionService.get_namespace_env_role_users($scope.pageContext.appId, env, $scope.pageContext.namespaceName) PermissionService.get_namespace_env_role_users($scope.pageContext.appId, env, $scope.pageContext.namespaceName)
.then(function (result) { .then(function (result) {
$scope.envRolesAssignedUsers[result.env] = result; $scope.envRolesAssignedUsers[result.env] = result;
}, function(result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "加载" + env + "授权用户出错"); toastr.error(AppUtil.errorMsg(result), $translate.instant('Namespace.Role.GetEnvGrantUserError', { env }));
}); });
} }
}); });
...@@ -53,14 +53,14 @@ role_module.controller('NamespaceRoleController', ...@@ -53,14 +53,14 @@ role_module.controller('NamespaceRoleController',
.then(function (result) { .then(function (result) {
$scope.rolesAssignedUsers = result; $scope.rolesAssignedUsers = result;
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "加载授权用户出错"); toastr.error(AppUtil.errorMsg(result), $translate.instant('Namespace.Role.GetGrantUserError'));
}); });
$scope.assignRoleToUser = function (roleType) { $scope.assignRoleToUser = function (roleType) {
if ("ReleaseNamespace" === roleType) { if ("ReleaseNamespace" === roleType) {
var user = $('.' + $scope.releaseRoleWidgetId).select2('data')[0]; var user = $('.' + $scope.releaseRoleWidgetId).select2('data')[0];
if (!user) { if (!user) {
toastr.warning("请选择用户"); toastr.warning($translate.instant('Namespace.Role.PleaseChooseUser'));
return; return;
} }
$scope.ReleaseRoleSubmitBtnDisabled = true; $scope.ReleaseRoleSubmitBtnDisabled = true;
...@@ -76,26 +76,26 @@ role_module.controller('NamespaceRoleController', ...@@ -76,26 +76,26 @@ role_module.controller('NamespaceRoleController',
$scope.pageContext.namespaceName, $scope.pageContext.namespaceName,
toAssignReleaseNamespaceRoleUser) toAssignReleaseNamespaceRoleUser)
.then(function (result) { .then(function (result) {
toastr.success("添加成功"); toastr.success($translate.instant('Namespace.Role.Added'));
$scope.ReleaseRoleSubmitBtnDisabled = false; $scope.ReleaseRoleSubmitBtnDisabled = false;
if ($scope.releaseRoleSelectedEnv === "") { if ($scope.releaseRoleSelectedEnv === "") {
$scope.rolesAssignedUsers.releaseRoleUsers.push( $scope.rolesAssignedUsers.releaseRoleUsers.push(
{userId: toAssignReleaseNamespaceRoleUser}); { userId: toAssignReleaseNamespaceRoleUser });
} else { } else {
$scope.envRolesAssignedUsers[$scope.releaseRoleSelectedEnv].releaseRoleUsers.push( $scope.envRolesAssignedUsers[$scope.releaseRoleSelectedEnv].releaseRoleUsers.push(
{userId: toAssignReleaseNamespaceRoleUser}); { userId: toAssignReleaseNamespaceRoleUser });
} }
$('.' + $scope.releaseRoleWidgetId).select2("val", ""); $('.' + $scope.releaseRoleWidgetId).select2("val", "");
$scope.releaseRoleSelectedEnv = ""; $scope.releaseRoleSelectedEnv = "";
}, function (result) { }, function (result) {
$scope.ReleaseRoleSubmitBtnDisabled = false; $scope.ReleaseRoleSubmitBtnDisabled = false;
toastr.error(AppUtil.errorMsg(result), "添加失败"); toastr.error(AppUtil.errorMsg(result), $translate.instant('Namespace.Role.AddFailed'));
}); });
} else { } else {
var user = $('.' + $scope.modifyRoleWidgetId).select2('data')[0]; var user = $('.' + $scope.modifyRoleWidgetId).select2('data')[0];
if (!user) { if (!user) {
toastr.warning("请选择用户"); toastr.warning($translate.instant('Namespace.Role.PleaseChooseUser'));
return; return;
} }
$scope.modifyRoleSubmitBtnDisabled = true; $scope.modifyRoleSubmitBtnDisabled = true;
...@@ -111,20 +111,20 @@ role_module.controller('NamespaceRoleController', ...@@ -111,20 +111,20 @@ role_module.controller('NamespaceRoleController',
$scope.pageContext.namespaceName, $scope.pageContext.namespaceName,
toAssignModifyNamespaceRoleUser) toAssignModifyNamespaceRoleUser)
.then(function (result) { .then(function (result) {
toastr.success("添加成功"); toastr.success($translate.instant('Namespace.Role.Added'));
$scope.modifyRoleSubmitBtnDisabled = false; $scope.modifyRoleSubmitBtnDisabled = false;
if ($scope.modifyRoleSelectedEnv === "") { if ($scope.modifyRoleSelectedEnv === "") {
$scope.rolesAssignedUsers.modifyRoleUsers.push( $scope.rolesAssignedUsers.modifyRoleUsers.push(
{userId: toAssignModifyNamespaceRoleUser}); { userId: toAssignModifyNamespaceRoleUser });
} else { } else {
$scope.envRolesAssignedUsers[$scope.modifyRoleSelectedEnv].modifyRoleUsers.push( $scope.envRolesAssignedUsers[$scope.modifyRoleSelectedEnv].modifyRoleUsers.push(
{userId: toAssignModifyNamespaceRoleUser}); { userId: toAssignModifyNamespaceRoleUser });
} }
$('.' + $scope.modifyRoleWidgetId).select2("val", ""); $('.' + $scope.modifyRoleWidgetId).select2("val", "");
$scope.modifyRoleSelectedEnv = ""; $scope.modifyRoleSelectedEnv = "";
}, function (result) { }, function (result) {
$scope.modifyRoleSubmitBtnDisabled = false; $scope.modifyRoleSubmitBtnDisabled = false;
toastr.error(AppUtil.errorMsg(result), "添加失败"); toastr.error(AppUtil.errorMsg(result), $translate.instant('Namespace.Role.AddFailed'));
}); });
} }
}; };
...@@ -141,14 +141,14 @@ role_module.controller('NamespaceRoleController', ...@@ -141,14 +141,14 @@ role_module.controller('NamespaceRoleController',
$scope.pageContext.namespaceName, $scope.pageContext.namespaceName,
user) user)
.then(function (result) { .then(function (result) {
toastr.success("删除成功"); toastr.success($translate.instant('Namespace.Role.Deleted'));
if (!env) { if (!env) {
removeUserFromList($scope.rolesAssignedUsers.releaseRoleUsers, user); removeUserFromList($scope.rolesAssignedUsers.releaseRoleUsers, user);
} else { } else {
removeUserFromList($scope.envRolesAssignedUsers[env].releaseRoleUsers, user); removeUserFromList($scope.envRolesAssignedUsers[env].releaseRoleUsers, user);
} }
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "删除失败"); toastr.error(AppUtil.errorMsg(result), $translate.instant('Namespace.Role.DeleteFailed'));
}); });
} else { } else {
var removeModifyNamespaceRoleFunc = !env ? var removeModifyNamespaceRoleFunc = !env ?
...@@ -161,14 +161,14 @@ role_module.controller('NamespaceRoleController', ...@@ -161,14 +161,14 @@ role_module.controller('NamespaceRoleController',
$scope.pageContext.namespaceName, $scope.pageContext.namespaceName,
user) user)
.then(function (result) { .then(function (result) {
toastr.success("删除成功"); toastr.success($translate.instant('Namespace.Role.Deleted'));
if (!env) { if (!env) {
removeUserFromList($scope.rolesAssignedUsers.modifyRoleUsers, user); removeUserFromList($scope.rolesAssignedUsers.modifyRoleUsers, user);
} else { } else {
removeUserFromList($scope.envRolesAssignedUsers[env].modifyRoleUsers, user); removeUserFromList($scope.envRolesAssignedUsers[env].modifyRoleUsers, user);
} }
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "删除失败"); toastr.error(AppUtil.errorMsg(result), $translate.instant('Namespace.Role.DeleteFailed'));
}); });
} }
}; };
......
angular.module('systemRole', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar']) angular.module('systemRole', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar'])
.controller('SystemRoleController', .controller('SystemRoleController',
['$scope', '$location', '$window', 'toastr', 'AppService', 'UserService', 'AppUtil', 'EnvService', ['$scope', '$location', '$window', '$translate', 'toastr', 'AppService', 'UserService', 'AppUtil', 'EnvService',
'PermissionService', 'SystemRoleService', function SystemRoleController($scope, $location, $window, toastr, AppService, UserService, AppUtil, EnvService, 'PermissionService', 'SystemRoleService', function SystemRoleController($scope, $location, $window, $translate, toastr, AppService, UserService, AppUtil, EnvService,
PermissionService, SystemRoleService) { PermissionService, SystemRoleService) {
$scope.addCreateApplicationBtnDisabled = false; $scope.addCreateApplicationBtnDisabled = false;
...@@ -21,33 +21,33 @@ angular.module('systemRole', ['app.service', 'apollo.directive', 'app.util', 'to ...@@ -21,33 +21,33 @@ angular.module('systemRole', ['app.service', 'apollo.directive', 'app.util', 'to
initPermission(); initPermission();
$scope.addCreateApplicationRoleToUser = function() { $scope.addCreateApplicationRoleToUser = function () {
var user = $('.' + $scope.modifySystemRoleWidgetId).select2('data')[0]; var user = $('.' + $scope.modifySystemRoleWidgetId).select2('data')[0];
if (!user) { if (!user) {
toastr.warning("请选择用户名"); toastr.warning($translate.instant('SystemRole.PleaseChooseUser'));
return; return;
} }
SystemRoleService.add_create_application_role(user.id) SystemRoleService.add_create_application_role(user.id)
.then( .then(
function (value) { function (value) {
toastr.info("添加成功"); toastr.info($translate.instant('SystemRole.Added'));
getCreateApplicationRoleUsers(); getCreateApplicationRoleUsers();
}, },
function (reason) { function (reason) {
toastr.warning(AppUtil.errorMsg(reason), "添加失败"); toastr.warning(AppUtil.errorMsg(reason), $translate.instant('SystemRole.AddFailed'));
} }
); );
}; };
$scope.deleteCreateApplicationRoleFromUser = function(userId) { $scope.deleteCreateApplicationRoleFromUser = function (userId) {
SystemRoleService.delete_create_application_role(userId) SystemRoleService.delete_create_application_role(userId)
.then( .then(
function (value) { function (value) {
toastr.info("删除成功"); toastr.info($translate.instant('SystemRole.Deleted'));
getCreateApplicationRoleUsers(); getCreateApplicationRoleUsers();
}, },
function (reason) { function (reason) {
toastr.warn(AppUtil.errorMsg(reason), "删除失败"); toastr.warn(AppUtil.errorMsg(reason), $translate.instant('SystemRole.DeleteFailed'));
} }
); );
}; };
...@@ -60,7 +60,7 @@ angular.module('systemRole', ['app.service', 'apollo.directive', 'app.util', 'to ...@@ -60,7 +60,7 @@ angular.module('systemRole', ['app.service', 'apollo.directive', 'app.util', 'to
$scope.hasCreateApplicationPermissionUserList = result; $scope.hasCreateApplicationPermissionUserList = result;
}, },
function (reason) { function (reason) {
toastr.warning(AppUtil.errorMsg(reason), "获取拥有创建项目的用户列表出错"); toastr.warning(AppUtil.errorMsg(reason), $translate.instant('SystemRole.GetCanCreateProjectUsersError'));
} }
) )
} }
...@@ -73,9 +73,9 @@ angular.module('systemRole', ['app.service', 'apollo.directive', 'app.util', 'to ...@@ -73,9 +73,9 @@ angular.module('systemRole', ['app.service', 'apollo.directive', 'app.util', 'to
getCreateApplicationRoleUsers(); getCreateApplicationRoleUsers();
} }
$scope.getAppInfo = function() { $scope.getAppInfo = function () {
if (!$scope.app.appId) { if (!$scope.app.appId) {
toastr.warning("请输入appId"); toastr.warning($translate.instant('SystemRole.PleaseEnterAppId'));
$scope.operateManageAppMasterRoleBtn = true; $scope.operateManageAppMasterRoleBtn = true;
return; return;
} }
...@@ -84,12 +84,17 @@ angular.module('systemRole', ['app.service', 'apollo.directive', 'app.util', 'to ...@@ -84,12 +84,17 @@ angular.module('systemRole', ['app.service', 'apollo.directive', 'app.util', 'to
AppService.load($scope.app.appId).then(function (result) { AppService.load($scope.app.appId).then(function (result) {
if (!result.appId) { if (!result.appId) {
toastr.warning("AppId: " + $scope.app.appId + " 不存在!"); toastr.warning($translate.instant('SystemRole.AppIdNotFound', { appId: $scope.app.appId }));
$scope.operateManageAppMasterRoleBtn = true; $scope.operateManageAppMasterRoleBtn = true;
return; return;
} }
$scope.app.info = "应用名:" + result.name + " 部门:" + result.orgName + '(' + result.orgId + ')' + " 负责人:" + result.ownerName; $scope.app.info = $translate.instant('SystemRole.AppInfoContent', {
appName: result.name,
departmentName: result.orgName,
departmentId: result.orgId,
ownerName: result.ownerName
});
$scope.operateManageAppMasterRoleBtn = false; $scope.operateManageAppMasterRoleBtn = false;
}, function (result) { }, function (result) {
...@@ -98,19 +103,27 @@ angular.module('systemRole', ['app.service', 'apollo.directive', 'app.util', 'to ...@@ -98,19 +103,27 @@ angular.module('systemRole', ['app.service', 'apollo.directive', 'app.util', 'to
}); });
}; };
$scope.deleteAppMasterAssignRole = function() { $scope.deleteAppMasterAssignRole = function () {
if (!$scope.app.appId) { if (!$scope.app.appId) {
toastr.warning("请输入appId"); toastr.warning($translate.instant('SystemRole.PleaseEnterAppId'));
return; return;
} }
var user = $('.' + $scope.modifyManageAppMasterRoleWidgetId).select2('data')[0]; var user = $('.' + $scope.modifyManageAppMasterRoleWidgetId).select2('data')[0];
if (!user) { if (!user) {
toastr.warning("请选择用户名"); toastr.warning($translate.instant('SystemRole.PleaseChooseUser'));
return; return;
} }
if (confirm("确认删除AppId: " + $scope.app.appId + "的用户: " + user.id + " 分配应用管理员的权限?")) { var confirmTips = $translate.instant('SystemRole.DeleteMasterAssignRoleTips', {
appId: $scope.app.appId,
userId: user.id
});
if (confirm(confirmTips)) {
AppService.delete_app_master_assign_role($scope.app.appId, user.id).then(function (result) { AppService.delete_app_master_assign_role($scope.app.appId, user.id).then(function (result) {
toastr.success("删除AppId: " + $scope.app.appId + "的用户: " + user.id + " 分配应用管理员的权限成功"); var deletedTips = $translate.instant('SystemRole.DeletedMasterAssignRoleTips', {
appId: $scope.app.appId,
userId: user.id
});
toastr.success(deletedTips);
$scope.operateManageAppMasterRoleBtn = true; $scope.operateManageAppMasterRoleBtn = true;
}, function (result) { }, function (result) {
AppUtil.showErrorMsg(result); AppUtil.showErrorMsg(result);
...@@ -120,21 +133,30 @@ angular.module('systemRole', ['app.service', 'apollo.directive', 'app.util', 'to ...@@ -120,21 +133,30 @@ angular.module('systemRole', ['app.service', 'apollo.directive', 'app.util', 'to
$scope.allowAppMasterAssignRole = function () { $scope.allowAppMasterAssignRole = function () {
if (!$scope.app.appId) { if (!$scope.app.appId) {
toastr.warning("请输入appId"); toastr.warning($translate.instant('SystemRole.PleaseEnterAppId'));
return; return;
} }
var user = $('.' + $scope.modifyManageAppMasterRoleWidgetId).select2('data')[0]; var user = $('.' + $scope.modifyManageAppMasterRoleWidgetId).select2('data')[0];
if (!user) { if (!user) {
toastr.warning("请选择用户名"); toastr.warning($translate.instant('SystemRole.PleaseChooseUser'));
return; return;
} }
if (confirm("确认添加AppId: " + $scope.app.appId + "的用户: " + user.id + " 分配应用管理员的权限?")) { var confirmTips = $translate.instant('SystemRole.AllowAppMasterAssignRoleTips', {
appId: $scope.app.appId,
userId: user.id
});
if (confirm(confirmTips)) {
AppService.allow_app_master_assign_role($scope.app.appId, user.id).then(function (result) { AppService.allow_app_master_assign_role($scope.app.appId, user.id).then(function (result) {
toastr.success("添加AppId: " + $scope.app.appId + "的用户: " + user.id + " 分配应用管理员的权限成功");
var allowedTips = $translate.instant('SystemRole.AllowedAppMasterAssignRoleTips', {
appId: $scope.app.appId,
userId: user.id
});
toastr.success(allowedTips);
$scope.operateManageAppMasterRoleBtn = true; $scope.operateManageAppMasterRoleBtn = true;
}, function (result) { }, function (result) {
AppUtil.showErrorMsg(result); AppUtil.showErrorMsg(result);
}) })
} }
}; };
}]); }]);
directive_module.directive('deletenamespacemodal', deleteNamespaceModalDirective); directive_module.directive('deletenamespacemodal', deleteNamespaceModalDirective);
function deleteNamespaceModalDirective($window, $q, toastr, AppUtil, EventManager, function deleteNamespaceModalDirective($window, $q, $translate, toastr, AppUtil, EventManager,
PermissionService, UserService, NamespaceService) { PermissionService, UserService, NamespaceService) {
return { return {
restrict: 'E', restrict: 'E',
...@@ -12,6 +12,8 @@ function deleteNamespaceModalDirective($window, $q, toastr, AppUtil, EventManage ...@@ -12,6 +12,8 @@ function deleteNamespaceModalDirective($window, $q, toastr, AppUtil, EventManage
}, },
link: function (scope) { link: function (scope) {
scope.doDeleteNamespace = doDeleteNamespace; scope.doDeleteNamespace = doDeleteNamespace;
EventManager.subscribe(EventManager.EventType.PRE_DELETE_NAMESPACE, function (context) { EventManager.subscribe(EventManager.EventType.PRE_DELETE_NAMESPACE, function (context) {
...@@ -67,8 +69,9 @@ function deleteNamespaceModalDirective($window, $q, toastr, AppUtil, EventManage ...@@ -67,8 +69,9 @@ function deleteNamespaceModalDirective($window, $q, toastr, AppUtil, EventManage
scope.isAppMasterUser = isAppMasterUser; scope.isAppMasterUser = isAppMasterUser;
if (!isAppMasterUser) { if (!isAppMasterUser) {
toastr.error("您没有项目管理员权限,只有管理员才能删除Namespace,请找项目管理员 [" + scope.masterUsers.join("") toastr.error($translate.instant('Config.DeleteNamespaceNoPermissionFailedTitle', {
+ "] 删除Namespace", "删除失败"); usres: scope.masterUsers.join(", ")
}), $translate.instant('Config.DeleteNamespaceNoPermissionFailedTitle'));
d.reject(); d.reject();
} else { } else {
d.resolve(); d.resolve();
...@@ -147,14 +150,14 @@ function deleteNamespaceModalDirective($window, $q, toastr, AppUtil, EventManage ...@@ -147,14 +150,14 @@ function deleteNamespaceModalDirective($window, $q, toastr, AppUtil, EventManage
toDeleteNamespace.baseInfo.clusterName, toDeleteNamespace.baseInfo.clusterName,
toDeleteNamespace.baseInfo.namespaceName) toDeleteNamespace.baseInfo.namespaceName)
.then(function () { .then(function () {
toastr.success("删除成功"); toastr.success($translate.instant('Common.Deleted'));
setTimeout(function () { setTimeout(function () {
$window.location.reload(); $window.location.reload();
}, 1000); }, 1000);
}, function (result) { }, function (result) {
AppUtil.showErrorMsg(result, "删除失败"); AppUtil.showErrorMsg(result, $translate.instant('Common.DeleteFailed'));
}) })
} }
......
...@@ -19,7 +19,7 @@ directive_module.directive('apollodiff', ...@@ -19,7 +19,7 @@ directive_module.directive('apollodiff',
function makeDiff() { function makeDiff() {
var displayArea = document.getElementById(scope.apolloId); var displayArea = document.getElementById(scope.apolloId);
if (!displayArea){ if (!displayArea) {
return; return;
} }
//clear //clear
......
/** navbar */ /** navbar */
directive_module.directive('apollonav', directive_module.directive('apollonav',
function ($compile, $window, toastr, AppUtil, AppService, EnvService, function ($compile, $window, $translate, toastr, AppUtil, AppService, EnvService,
UserService, CommonService, PermissionService) { UserService, CommonService, PermissionService) {
return { return {
restrict: 'E', restrict: 'E',
...@@ -19,7 +19,7 @@ directive_module.directive('apollonav', ...@@ -19,7 +19,7 @@ directive_module.directive('apollonav',
}); });
$('#app-search-list').select2({ $('#app-search-list').select2({
placeholder: '搜索项目(AppId、项目名)', placeholder: $translate.instant('ApolloConfirmDialog.SearchPlaceHolder'),
ajax: { ajax: {
url: "/apps/search", url: "/apps/search",
dataType: 'json', dataType: 'json',
...@@ -83,9 +83,13 @@ directive_module.directive('apollonav', ...@@ -83,9 +83,13 @@ directive_module.directive('apollonav',
}); });
PermissionService.has_root_permission().then(function(result) { PermissionService.has_root_permission().then(function (result) {
scope.hasRootPermission = result.hasPermission; scope.hasRootPermission = result.hasPermission;
}) })
scope.changeLanguage = function (lang) {
$translate.use(lang)
}
} }
} }
...@@ -186,7 +190,7 @@ directive_module.directive('apollorequiredfield', function ($compile, $window) { ...@@ -186,7 +190,7 @@ directive_module.directive('apollorequiredfield', function ($compile, $window) {
}); });
/** 确认框 */ /** 确认框 */
directive_module.directive('apolloconfirmdialog', function ($compile, $window, $sce) { directive_module.directive('apolloconfirmdialog', function ($compile, $window, $sce,$translate) {
return { return {
restrict: 'E', restrict: 'E',
templateUrl: '../../views/component/confirm-dialog.html', templateUrl: '../../views/component/confirm-dialog.html',
...@@ -209,7 +213,7 @@ directive_module.directive('apolloconfirmdialog', function ($compile, $window, $ ...@@ -209,7 +213,7 @@ directive_module.directive('apolloconfirmdialog', function ($compile, $window, $
}); });
if (!scope.confirmBtnText) { if (!scope.confirmBtnText) {
scope.confirmBtnText = '确认'; scope.confirmBtnText = $translate.instant('ApolloConfirmDialog.DefaultConfirmBtnName');
} }
scope.confirm = function () { scope.confirm = function () {
......
directive_module.directive('rulesmodal', rulesModalDirective); directive_module.directive('rulesmodal', rulesModalDirective);
function rulesModalDirective(toastr, AppUtil, EventManager, InstanceService) { function rulesModalDirective($translate, toastr, AppUtil, EventManager, InstanceService) {
return { return {
restrict: 'E', restrict: 'E',
templateUrl: '../../views/component/gray-release-rules-modal.html', templateUrl: '../../views/component/gray-release-rules-modal.html',
...@@ -27,15 +27,15 @@ function rulesModalDirective(toastr, AppUtil, EventManager, InstanceService) { ...@@ -27,15 +27,15 @@ function rulesModalDirective(toastr, AppUtil, EventManager, InstanceService) {
var branch = context.branch; var branch = context.branch;
scope.branch = branch; scope.branch = branch;
if (branch.editingRuleItem.clientIpList && branch.editingRuleItem.clientIpList[0] == '*'){ if (branch.editingRuleItem.clientIpList && branch.editingRuleItem.clientIpList[0] == '*') {
branch.editingRuleItem.ApplyToAllInstances = true; branch.editingRuleItem.ApplyToAllInstances = true;
}else { } else {
branch.editingRuleItem.ApplyToAllInstances = false; branch.editingRuleItem.ApplyToAllInstances = false;
} }
$('.rules-ip-selector').select2({ $('.rules-ip-selector').select2({
placeholder: "从实例列表中选择", placeholder: $translate.instant('RulesModal.ChooseInstances'),
allowClear: true allowClear: true
}); });
...@@ -73,7 +73,7 @@ function rulesModalDirective(toastr, AppUtil, EventManager, InstanceService) { ...@@ -73,7 +73,7 @@ function rulesModalDirective(toastr, AppUtil, EventManager, InstanceService) {
if (newIps && newIps.length > 0) { if (newIps && newIps.length > 0) {
newIps.forEach(function (IP) { newIps.forEach(function (IP) {
if (!AppUtil.checkIPV4(IP)) { if (!AppUtil.checkIPV4(IP)) {
toastr.error("不合法的IP地址:" + IP); toastr.error($translate.instant('RulesModal.ChooseInstances', { ip: IP }));
} else if (oldIPs.indexOf(IP) < 0) { } else if (oldIPs.indexOf(IP) < 0) {
oldIPs.push(IP); oldIPs.push(IP);
} }
...@@ -102,7 +102,7 @@ function rulesModalDirective(toastr, AppUtil, EventManager, InstanceService) { ...@@ -102,7 +102,7 @@ function rulesModalDirective(toastr, AppUtil, EventManager, InstanceService) {
scope.completeEditBtnDisable = true; scope.completeEditBtnDisable = true;
if (!branch.editingRuleItem.clientAppId) { if (!branch.editingRuleItem.clientAppId) {
toastr.error("灰度的AppId不能为空"); toastr.error($translate.instant('RulesModal.GrayscaleAppIdCanNotBeNull'));
scope.completeEditBtnDisable = false; scope.completeEditBtnDisable = false;
return; return;
} }
...@@ -111,7 +111,7 @@ function rulesModalDirective(toastr, AppUtil, EventManager, InstanceService) { ...@@ -111,7 +111,7 @@ function rulesModalDirective(toastr, AppUtil, EventManager, InstanceService) {
var errorRuleItem = false; var errorRuleItem = false;
branch.rules.ruleItems.forEach(function (ruleItem) { branch.rules.ruleItems.forEach(function (ruleItem) {
if (ruleItem.clientAppId == branch.editingRuleItem.clientAppId) { if (ruleItem.clientAppId == branch.editingRuleItem.clientAppId) {
toastr.error("已经存在AppId=" + branch.editingRuleItem.clientAppId + "的规则"); toastr.error($translate.instant('RulesModal.AppIdExistsRule', { appId: branch.editingRuleItem.clientAppId }));
errorRuleItem = true; errorRuleItem = true;
} }
}); });
...@@ -123,7 +123,7 @@ function rulesModalDirective(toastr, AppUtil, EventManager, InstanceService) { ...@@ -123,7 +123,7 @@ function rulesModalDirective(toastr, AppUtil, EventManager, InstanceService) {
if (!branch.editingRuleItem.ApplyToAllInstances) { if (!branch.editingRuleItem.ApplyToAllInstances) {
if (branch.editingRuleItem.draftIpList.length == 0) { if (branch.editingRuleItem.draftIpList.length == 0) {
toastr.error("IP列表不能为空"); toastr.error($translate.instant('RulesModal.IpListCanNotBeNull'));
scope.completeEditBtnDisable = false; scope.completeEditBtnDisable = false;
return; return;
} else { } else {
......
directive_module.directive('itemmodal', itemModalDirective); directive_module.directive('itemmodal', itemModalDirective);
function itemModalDirective(toastr, $sce, AppUtil, EventManager, ConfigService) { function itemModalDirective($translate, toastr, $sce, AppUtil, EventManager, ConfigService) {
return { return {
restrict: 'E', restrict: 'E',
templateUrl: '../../views/component/item-modal.html', templateUrl: '../../views/component/item-modal.html',
...@@ -44,7 +44,7 @@ function itemModalDirective(toastr, $sce, AppUtil, EventManager, ConfigService) ...@@ -44,7 +44,7 @@ function itemModalDirective(toastr, $sce, AppUtil, EventManager, ConfigService)
var hasRepeatKey = false; var hasRepeatKey = false;
scope.toOperationNamespace.items.forEach(function (item) { scope.toOperationNamespace.items.forEach(function (item) {
if (!item.isDeleted && scope.item.key == item.item.key) { if (!item.isDeleted && scope.item.key == item.item.key) {
toastr.error("key=" + scope.item.key + " 已存在"); toastr.error($translate.instant('ItemModal.KeyExists', { key: scope.item.key }));
hasRepeatKey = true; hasRepeatKey = true;
} }
}); });
...@@ -61,7 +61,7 @@ function itemModalDirective(toastr, $sce, AppUtil, EventManager, ConfigService) ...@@ -61,7 +61,7 @@ function itemModalDirective(toastr, $sce, AppUtil, EventManager, ConfigService)
scope.toOperationNamespace.baseInfo.namespaceName, scope.toOperationNamespace.baseInfo.namespaceName,
scope.item).then( scope.item).then(
function (result) { function (result) {
toastr.success("添加成功,如需生效请发布"); toastr.success($translate.instant('ItemModal.AddedTips'));
scope.item.addItemBtnDisabled = false; scope.item.addItemBtnDisabled = false;
AppUtil.hideModal('#itemModal'); AppUtil.hideModal('#itemModal');
EventManager.emit(EventManager.EventType.REFRESH_NAMESPACE, EventManager.emit(EventManager.EventType.REFRESH_NAMESPACE,
...@@ -70,12 +70,12 @@ function itemModalDirective(toastr, $sce, AppUtil, EventManager, ConfigService) ...@@ -70,12 +70,12 @@ function itemModalDirective(toastr, $sce, AppUtil, EventManager, ConfigService)
}); });
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "添加失败"); toastr.error(AppUtil.errorMsg(result), $translate.instant('ItemModal.AddFailed'));
scope.item.addItemBtnDisabled = false; scope.item.addItemBtnDisabled = false;
}); });
} else { } else {
if (selectedClusters.length == 0) { if (selectedClusters.length == 0) {
toastr.error("请选择集群"); toastr.error($translate.instant('ItemModal.PleaseChooseCluster'));
scope.item.addItemBtnDisabled = false; scope.item.addItemBtnDisabled = false;
return; return;
} }
...@@ -89,7 +89,7 @@ function itemModalDirective(toastr, $sce, AppUtil, EventManager, ConfigService) ...@@ -89,7 +89,7 @@ function itemModalDirective(toastr, $sce, AppUtil, EventManager, ConfigService)
function (result) { function (result) {
scope.item.addItemBtnDisabled = false; scope.item.addItemBtnDisabled = false;
AppUtil.hideModal('#itemModal'); AppUtil.hideModal('#itemModal');
toastr.success(cluster.env + " , " + scope.item.key, "添加成功,如需生效请发布"); toastr.success(cluster.env + " , " + scope.item.key, $translate.instant('ItemModal.AddedTips'));
if (cluster.env == scope.env && if (cluster.env == scope.env &&
cluster.name == scope.cluster) { cluster.name == scope.cluster) {
...@@ -99,7 +99,7 @@ function itemModalDirective(toastr, $sce, AppUtil, EventManager, ConfigService) ...@@ -99,7 +99,7 @@ function itemModalDirective(toastr, $sce, AppUtil, EventManager, ConfigService)
}); });
} }
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "添加失败"); toastr.error(AppUtil.errorMsg(result), $translate.instant('ItemModal.AddFailed'));
scope.item.addItemBtnDisabled = false; scope.item.addItemBtnDisabled = false;
}); });
}); });
...@@ -124,9 +124,9 @@ function itemModalDirective(toastr, $sce, AppUtil, EventManager, ConfigService) ...@@ -124,9 +124,9 @@ function itemModalDirective(toastr, $sce, AppUtil, EventManager, ConfigService)
AppUtil.hideModal('#itemModal'); AppUtil.hideModal('#itemModal');
toastr.success("更新成功, 如需生效请发布"); toastr.success($translate.instant('ItemModal.ModifedTips'));
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "更新失败"); toastr.error(AppUtil.errorMsg(result), $translate.instant('ItemModal.ModifyFailed'));
}); });
} }
...@@ -167,11 +167,11 @@ function itemModalDirective(toastr, $sce, AppUtil, EventManager, ConfigService) ...@@ -167,11 +167,11 @@ function itemModalDirective(toastr, $sce, AppUtil, EventManager, ConfigService)
function viewHiddenChar(c) { function viewHiddenChar(c) {
if (c == '\t') { if (c == '\t') {
return '<mark>#制表符#</mark>'; return '<mark>#' + $translate.instant('ItemModal.Tabs') + '#</mark>';
} else if (c == '\n') { } else if (c == '\n') {
return '<mark>#换行符#</mark>'; return '<mark>#' + $translate.instant('ItemModal.NewLine') + '#</mark>';
} else if (c == ' ') { } else if (c == ' ') {
return '<mark>#空格#</mark>'; return '<mark>#' + $translate.instant('ItemModal.Space') + '#</mark>';
} }
} }
......
directive_module.directive('apollonspanel', directive); directive_module.directive('apollonspanel', directive);
function directive($window, toastr, AppUtil, EventManager, PermissionService, NamespaceLockService, function directive($window, $translate, toastr, AppUtil, EventManager, PermissionService, NamespaceLockService,
UserService, CommitService, ReleaseService, InstanceService, NamespaceBranchService, ConfigService) { UserService, CommitService, ReleaseService, InstanceService, NamespaceBranchService, ConfigService) {
return { return {
restrict: 'E', restrict: 'E',
...@@ -103,7 +103,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na ...@@ -103,7 +103,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
function refreshNamespace() { function refreshNamespace() {
EventManager.emit(EventManager.EventType.REFRESH_NAMESPACE, EventManager.emit(EventManager.EventType.REFRESH_NAMESPACE,
{namespace: scope.namespace}); { namespace: scope.namespace });
} }
function initNamespace(namespace, viewType) { function initNamespace(namespace, viewType) {
...@@ -463,7 +463,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na ...@@ -463,7 +463,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
} }
namespace.commitPage += 1; namespace.commitPage += 1;
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "加载修改历史记录出错"); toastr.error(AppUtil.errorMsg(result), $translate.instant('ApolloNsPanel.LoadingHistoryError'));
}); });
} }
...@@ -609,7 +609,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na ...@@ -609,7 +609,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
} }
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "加载灰度规则出错"); toastr.error(AppUtil.errorMsg(result), $translate.instant('ApolloNsPanel.LoadingGrayscaleError'));
}); });
} }
...@@ -643,7 +643,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na ...@@ -643,7 +643,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
branch.rules.ruleItems.forEach(function (item, index) { branch.rules.ruleItems.forEach(function (item, index) {
if (item.clientAppId == ruleItem.clientAppId) { if (item.clientAppId == ruleItem.clientAppId) {
branch.rules.ruleItems.splice(index, 1); branch.rules.ruleItems.splice(index, 1);
toastr.success("删除成功"); toastr.success($translate.instant('ApolloNsPanel.Deleted'));
} }
}); });
...@@ -659,7 +659,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na ...@@ -659,7 +659,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
branch.rules branch.rules
) )
.then(function (result) { .then(function (result) {
toastr.success('灰度规则更新成功'); toastr.success($translate.instant('ApolloNsPanel.GrayscaleModifed'));
//show tips if branch has not release configs //show tips if branch has not release configs
if (branch.itemModifiedCnt) { if (branch.itemModifiedCnt) {
...@@ -671,7 +671,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na ...@@ -671,7 +671,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
}, 1500); }, 1500);
}, function (result) { }, function (result) {
AppUtil.showErrorMsg(result, "灰度规则更新失败"); AppUtil.showErrorMsg(result, $translate.instant('ApolloNsPanel.GrayscaleModifyFailed'));
}) })
} }
...@@ -729,7 +729,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na ...@@ -729,7 +729,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
namespace.baseInfo.namespaceName, namespace.baseInfo.namespaceName,
model).then( model).then(
function (result) { function (result) {
toastr.success("更新成功, 如需生效请发布"); toastr.success($translate.instant('ApolloNsPanel.ModifedTips'));
//refresh all namespace items //refresh all namespace items
EventManager.emit(EventManager.EventType.REFRESH_NAMESPACE, EventManager.emit(EventManager.EventType.REFRESH_NAMESPACE,
{ {
...@@ -738,7 +738,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na ...@@ -738,7 +738,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
return true; return true;
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "更新失败"); toastr.error(AppUtil.errorMsg(result), $translate.instant('ApolloNsPanel.ModifyFailed'));
namespace.commitChangeBtnDisabled = false; namespace.commitChangeBtnDisabled = false;
return false; return false;
} }
...@@ -759,7 +759,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na ...@@ -759,7 +759,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
namespace.baseInfo.namespaceName, namespace.baseInfo.namespaceName,
model).then( model).then(
function (result) { function (result) {
toastr.success("语法正确!"); toastr.success($translate.instant('ApolloNsPanel.GrammarIsright'));
}, function (result) { }, function (result) {
EventManager.emit(EventManager.EventType.SYNTAX_CHECK_TEXT_FAILED, { EventManager.emit(EventManager.EventType.SYNTAX_CHECK_TEXT_FAILED, {
...@@ -874,16 +874,16 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na ...@@ -874,16 +874,16 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
mergeAndPublish: true mergeAndPublish: true
}); });
} else { } else {
EventManager.emit(EventManager.EventType.MERGE_AND_PUBLISH_NAMESPACE, {branch: branch}); EventManager.emit(EventManager.EventType.MERGE_AND_PUBLISH_NAMESPACE, { branch: branch });
} }
} }
function rollback(namespace) { function rollback(namespace) {
EventManager.emit(EventManager.EventType.PRE_ROLLBACK_NAMESPACE, {namespace: namespace}); EventManager.emit(EventManager.EventType.PRE_ROLLBACK_NAMESPACE, { namespace: namespace });
} }
function deleteNamespace(namespace) { function deleteNamespace(namespace) {
EventManager.emit(EventManager.EventType.PRE_DELETE_NAMESPACE, {namespace: namespace}); EventManager.emit(EventManager.EventType.PRE_DELETE_NAMESPACE, { namespace: namespace });
} }
//theme: https://github.com/ajaxorg/ace-builds/tree/ba3b91e04a5aa559d56ac70964f9054baa0f4caf/src-min //theme: https://github.com/ajaxorg/ace-builds/tree/ba3b91e04a5aa559d56ac70964f9054baa0f4caf/src-min
......
directive_module.directive('releasemodal', releaseModalDirective); directive_module.directive('releasemodal', releaseModalDirective);
function releaseModalDirective(toastr, AppUtil, EventManager, ReleaseService, NamespaceBranchService) { function releaseModalDirective($translate, toastr, AppUtil, EventManager, ReleaseService, NamespaceBranchService) {
return { return {
restrict: 'E', restrict: 'E',
templateUrl: '../../views/component/release-modal.html', templateUrl: '../../views/component/release-modal.html',
...@@ -61,7 +61,7 @@ function releaseModalDirective(toastr, AppUtil, EventManager, ReleaseService, Na ...@@ -61,7 +61,7 @@ function releaseModalDirective(toastr, AppUtil, EventManager, ReleaseService, Na
scope.isEmergencyPublish).then( scope.isEmergencyPublish).then(
function (result) { function (result) {
AppUtil.hideModal('#releaseModal'); AppUtil.hideModal('#releaseModal');
toastr.success("发布成功"); toastr.success($translate.instant('ReleaseModal.Published'));
scope.releaseBtnDisabled = false; scope.releaseBtnDisabled = false;
...@@ -72,7 +72,7 @@ function releaseModalDirective(toastr, AppUtil, EventManager, ReleaseService, Na ...@@ -72,7 +72,7 @@ function releaseModalDirective(toastr, AppUtil, EventManager, ReleaseService, Na
}, function (result) { }, function (result) {
scope.releaseBtnDisabled = false; scope.releaseBtnDisabled = false;
toastr.error(AppUtil.errorMsg(result), "发布失败"); toastr.error(AppUtil.errorMsg(result), $translate.instant('ReleaseModal.PublishFailed'));
} }
); );
...@@ -90,7 +90,7 @@ function releaseModalDirective(toastr, AppUtil, EventManager, ReleaseService, Na ...@@ -90,7 +90,7 @@ function releaseModalDirective(toastr, AppUtil, EventManager, ReleaseService, Na
scope.isEmergencyPublish).then( scope.isEmergencyPublish).then(
function (result) { function (result) {
AppUtil.hideModal('#releaseModal'); AppUtil.hideModal('#releaseModal');
toastr.success("灰度发布成功"); toastr.success($translate.instant('ReleaseModal.GrayscalePublished'));
scope.releaseBtnDisabled = false; scope.releaseBtnDisabled = false;
...@@ -117,7 +117,7 @@ function releaseModalDirective(toastr, AppUtil, EventManager, ReleaseService, Na ...@@ -117,7 +117,7 @@ function releaseModalDirective(toastr, AppUtil, EventManager, ReleaseService, Na
}, function (result) { }, function (result) {
scope.releaseBtnDisabled = false; scope.releaseBtnDisabled = false;
toastr.error(AppUtil.errorMsg(result), "灰度发布失败"); toastr.error(AppUtil.errorMsg(result), $translate.instant('ReleaseModal.GrayscalePublishFailed'));
}); });
} }
...@@ -135,7 +135,7 @@ function releaseModalDirective(toastr, AppUtil, EventManager, ReleaseService, Na ...@@ -135,7 +135,7 @@ function releaseModalDirective(toastr, AppUtil, EventManager, ReleaseService, Na
scope.toReleaseNamespace.mergeAfterDeleteBranch) scope.toReleaseNamespace.mergeAfterDeleteBranch)
.then(function (result) { .then(function (result) {
toastr.success("全量发布成功"); toastr.success($translate.instant('ReleaseModal.AllPublished'));
EventManager.emit(EventManager.EventType.REFRESH_NAMESPACE, EventManager.emit(EventManager.EventType.REFRESH_NAMESPACE,
{ {
...@@ -143,7 +143,7 @@ function releaseModalDirective(toastr, AppUtil, EventManager, ReleaseService, Na ...@@ -143,7 +143,7 @@ function releaseModalDirective(toastr, AppUtil, EventManager, ReleaseService, Na
}) })
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "全量发布失败"); toastr.error(AppUtil.errorMsg(result), $translate.instant('ReleaseModal.AllPublishFailed'));
}); });
AppUtil.hideModal('#releaseModal'); AppUtil.hideModal('#releaseModal');
......
directive_module.directive('rollbackmodal', rollbackModalDirective); directive_module.directive('rollbackmodal', rollbackModalDirective);
function rollbackModalDirective(AppUtil, EventManager, ReleaseService, toastr) { function rollbackModalDirective($translate, AppUtil, EventManager, ReleaseService, toastr) {
return { return {
restrict: 'E', restrict: 'E',
templateUrl: '../../views/component/rollback-modal.html', templateUrl: '../../views/component/rollback-modal.html',
...@@ -35,7 +35,7 @@ function rollbackModalDirective(AppUtil, EventManager, ReleaseService, toastr) { ...@@ -35,7 +35,7 @@ function rollbackModalDirective(AppUtil, EventManager, ReleaseService, toastr) {
0, 2) 0, 2)
.then(function (result) { .then(function (result) {
if (result.length <= 1) { if (result.length <= 1) {
toastr.error("没有可以回滚的发布历史"); toastr.error($translate.instant('Rollback.NoRollbackList'));
return; return;
} }
scope.toRollbackNamespace.firstRelease = result[0]; scope.toRollbackNamespace.firstRelease = result[0];
...@@ -57,16 +57,16 @@ function rollbackModalDirective(AppUtil, EventManager, ReleaseService, toastr) { ...@@ -57,16 +57,16 @@ function rollbackModalDirective(AppUtil, EventManager, ReleaseService, toastr) {
ReleaseService.rollback(scope.env, ReleaseService.rollback(scope.env,
scope.toRollbackNamespace.firstRelease.id) scope.toRollbackNamespace.firstRelease.id)
.then(function (result) { .then(function (result) {
toastr.success("回滚成功"); toastr.success($translate.instant('Rollback.RollbackSuccessfully'));
scope.toRollbackNamespace.rollbackBtnDisabled = false; scope.toRollbackNamespace.rollbackBtnDisabled = false;
AppUtil.hideModal('#rollbackModal'); AppUtil.hideModal('#rollbackModal');
EventManager.emit(EventManager.EventType.REFRESH_NAMESPACE, EventManager.emit(EventManager.EventType.REFRESH_NAMESPACE,
{ {
namespace:scope.toRollbackNamespace namespace: scope.toRollbackNamespace
}); });
}, function (result) { }, function (result) {
scope.toRollbackNamespace.rollbackBtnDisabled = false; scope.toRollbackNamespace.rollbackBtnDisabled = false;
AppUtil.showErrorMsg(result, "回滚失败"); AppUtil.showErrorMsg(result, $translate.instant('Rollback.RollbackFailed'));
}) })
} }
......
...@@ -7,19 +7,19 @@ function appValdr(valdrProvider) { ...@@ -7,19 +7,19 @@ function appValdr(valdrProvider) {
'appId': { 'appId': {
'size': { 'size': {
'max': 32, 'max': 32,
'message': 'AppId长度不能多于32个字符' 'message': 'Valdr.App.AppId.Size'
}, },
'required': { 'required': {
'message': 'AppId不能为空' 'message': 'Valdr.App.AppId.Required'
} }
}, },
'appName': { 'appName': {
'size': { 'size': {
'max': 128, 'max': 128,
'message': '应用名称长度不能多于128个字符' 'message': 'Valdr.App.appName.Size'
}, },
'required': { 'required': {
'message': '应用名称不能为空' 'message': 'Valdr.App.appName.Required'
} }
} }
} }
...@@ -32,10 +32,10 @@ cluster_module.config(function (valdrProvider) { ...@@ -32,10 +32,10 @@ cluster_module.config(function (valdrProvider) {
'clusterName': { 'clusterName': {
'size': { 'size': {
'max': 32, 'max': 32,
'message': '集群名称长度不能多于32个字符' 'message': 'Valdr.Cluster.ClusterName.Size'
}, },
'required': { 'required': {
'message': '集群名称不能为空' 'message': 'Valdr.Cluster.ClusterName.Required'
} }
} }
} }
...@@ -48,16 +48,16 @@ namespace_module.config(function (valdrProvider) { ...@@ -48,16 +48,16 @@ namespace_module.config(function (valdrProvider) {
'namespaceName': { 'namespaceName': {
'size': { 'size': {
'max': 32, 'max': 32,
'message': 'Namespace名称长度不能多于32个字符' 'message': 'Valdr.AppNamespace.NamespaceName.Size'
}, },
'required': { 'required': {
'message': 'Namespace名称不能为空' 'message': 'Valdr.AppNamespace.NamespaceName.Required'
} }
}, },
'comment': { 'comment': {
'size': { 'size': {
'max': 64, 'max': 64,
'message': '备注长度不能多于64个字符' 'message': 'Valdr.AppNamespace.Comment.Size'
} }
} }
} }
...@@ -70,16 +70,16 @@ application_module.config(function (valdrProvider) { ...@@ -70,16 +70,16 @@ application_module.config(function (valdrProvider) {
'key': { 'key': {
'size': { 'size': {
'max': 128, 'max': 128,
'message': 'Key长度不能多于128个字符' 'message': 'Valdr.Item.Key.Size'
}, },
'required': { 'required': {
'message': 'Key不能为空' 'message': 'Valdr.Item.Key.Required'
} }
}, },
'comment': { 'comment': {
'size': { 'size': {
'max': 64, 'max': 64,
'message': '备注长度不能多于64个字符' 'message': 'Valdr.Item.Comment.Size'
} }
} }
}, },
...@@ -87,16 +87,16 @@ application_module.config(function (valdrProvider) { ...@@ -87,16 +87,16 @@ application_module.config(function (valdrProvider) {
'releaseName': { 'releaseName': {
'size': { 'size': {
'max': 64, 'max': 64,
'message': 'Release Name长度不能多于64个字符' 'message': 'Valdr.Release.ReleaseName.Size'
}, },
'required': { 'required': {
'message': 'Release Name不能为空' 'message': 'Valdr.Release.ReleaseName.Size'
} }
}, },
'comment': { 'comment': {
'size': { 'size': {
'max': 64, 'max': 64,
'message': '备注长度不能多于64个字符' 'message': 'Valdr.Release.Comment.Size'
} }
} }
} }
......
<!doctype html> <!doctype html>
<html ng-app="server_config"> <html ng-app="server_config">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="icon" href="./img/config.png"> <link rel="icon" href="./img/config.png">
...@@ -9,20 +10,20 @@ ...@@ -9,20 +10,20 @@
<link rel="stylesheet" type="text/css" href="vendor/select2/select2.min.css"> <link rel="stylesheet" type="text/css" href="vendor/select2/select2.min.css">
<link rel="stylesheet" type="text/css" media='all' href="vendor/angular/loading-bar.min.css"> <link rel="stylesheet" type="text/css" media='all' href="vendor/angular/loading-bar.min.css">
<link rel="stylesheet" type="text/css" href="styles/common-style.css"> <link rel="stylesheet" type="text/css" href="styles/common-style.css">
<title>应用配置</title> <title>{{'SericeConfig.Title' | translate }}</title>
</head> </head>
<body> <body>
<apollonav></apollonav> <apollonav></apollonav>
<div class="container-fluid apollo-container"> <div class="container-fluid apollo-container">
<div class="row"> <div class="row">
<div class="col-md-8 col-md-offset-2"> <div class="col-md-8 col-md-offset-2">
<div class="panel"> <div class="panel">
<header class="panel-heading"> <header class="panel-heading">
应用配置 {{'SericeConfig.Title' | translate }}
<small>(维护ApolloPortalDB.ServerConfig表数据,如果已存在配置项则会覆盖,否则会创建配置项。配置更新后,一分钟后自动生效)</small> <small>{{'SericeConfig.Tips' | translate }}</small>
</header> </header>
<div class="panel-body"> <div class="panel-body">
...@@ -30,38 +31,42 @@ ...@@ -30,38 +31,42 @@
<div class="form-group"> <div class="form-group">
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
key</label> {{'SericeConfig.Key' | translate }}
</label>
<div class="col-sm-8"> <div class="col-sm-8">
<input type="text" class="form-control" name="key" ng-model="serverConfig.key" <input type="text" class="form-control" name="key" ng-model="serverConfig.key"
required> required>
<small>(修改配置前请先查询该配置信息)</small> <small>{{'SericeConfig.KeyTips' | translate }}</small>
</div> </div>
<div class="col-sm-1"> <div class="col-sm-1">
<button class="btn btn-info" ng-click="getServerConfigInfo()">查询</button> <button class="btn btn-info"
ng-click="getServerConfigInfo()">{{'Common.Search' | translate }}</button>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
value</label> {{'SericeConfig.Value' | translate }}
</label>
<div class="col-sm-9"> <div class="col-sm-9">
<textarea class="form-control" rows="4" name="value" ng-model="serverConfig.value"></textarea> <textarea class="form-control" rows="4" name="value"
ng-model="serverConfig.value"></textarea>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
comment</label> {{'SericeConfig.Comment' | translate }}</label>
<div class="col-sm-9"> <div class="col-sm-9">
<textarea class="form-control" rows="4" name="comment" ng-model="serverConfig.comment"></textarea> <textarea class="form-control" rows="4" name="comment"
ng-model="serverConfig.comment"></textarea>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="col-sm-offset-2 col-sm-10"> <div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary" <button type="submit" class="btn btn-primary" ng-disabled="saveBtnDisabled"
ng-disabled="saveBtnDisabled"
ng-click="create()"> ng-click="create()">
保存 {{'Common.Save' | translate }}
</button> </button>
</div> </div>
</div> </div>
...@@ -70,34 +75,40 @@ ...@@ -70,34 +75,40 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div ng-include="'views/common/footer.html'"></div> <div ng-include="'views/common/footer.html'"></div>
<!--angular--> <!--angular-->
<script src="vendor/angular/angular.min.js"></script> <script src="vendor/angular/angular.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>
<script src="vendor/angular/angular-cookies.min.js"></script>
<!-- jquery.js --> <script src="vendor/angular/angular-translate.2.18.1/angular-translate.min.js"></script>
<script src="vendor/jquery.min.js" type="text/javascript"></script> <script src="vendor/angular/angular-translate.2.18.1/angular-translate-loader-static-files.min.js"></script>
<script src="vendor/select2/select2.min.js" type="text/javascript"></script> <script src="vendor/angular/angular-translate.2.18.1/angular-translate-storage-cookie.min.js"></script>
<!-- bootstrap.js --> <!-- jquery.js -->
<script src="vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script> <script src="vendor/jquery.min.js" type="text/javascript"></script>
<script src="vendor/select2/select2.min.js" type="text/javascript"></script>
<script type="application/javascript" src="scripts/app.js"></script> <!-- bootstrap.js -->
<script type="application/javascript" src="scripts/directive/directive.js"></script> <script src="vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
<script type="application/javascript" src="scripts/AppUtils.js"></script>
<script type="application/javascript" src="scripts/services/AppService.js"></script> <script type="application/javascript" src="scripts/app.js"></script>
<script type="application/javascript" src="scripts/services/EnvService.js"></script> <script type="application/javascript" src="scripts/directive/directive.js"></script>
<script type="application/javascript" src="scripts/services/UserService.js"></script> <script type="application/javascript" src="scripts/AppUtils.js"></script>
<script type="application/javascript" src="scripts/services/CommonService.js"></script>
<script type="application/javascript" src="scripts/services/ServerConfigService.js"></script>
<script type="application/javascript" src="scripts/services/PermissionService.js"></script>
<script type="application/javascript" src="scripts/controller/ServerConfigController.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/UserService.js"></script>
<script type="application/javascript" src="scripts/services/CommonService.js"></script>
<script type="application/javascript" src="scripts/services/ServerConfigService.js"></script>
<script type="application/javascript" src="scripts/services/PermissionService.js"></script>
<script type="application/javascript" src="scripts/controller/ServerConfigController.js"></script>
</body> </body>
</html> </html>
\ No newline at end of file
<!doctype html> <!doctype html>
<html ng-app="systemRole"> <html ng-app="systemRole">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="icon" href="../img/config.png"> <link rel="icon" href="../img/config.png">
...@@ -9,44 +10,49 @@ ...@@ -9,44 +10,49 @@
<link rel="stylesheet" type="text/css" media='all' href="../vendor/angular/loading-bar.min.css"> <link rel="stylesheet" type="text/css" media='all' href="../vendor/angular/loading-bar.min.css">
<link rel="stylesheet" type="text/css" href="../styles/common-style.css"> <link rel="stylesheet" type="text/css" href="../styles/common-style.css">
<link rel="stylesheet" type="text/css" href="../vendor/select2/select2.min.css"> <link rel="stylesheet" type="text/css" href="../vendor/select2/select2.min.css">
<title>系统权限管理</title> <title>{{'SystemRole.Title' | translate }}</title>
</head> </head>
<body> <body>
<apollonav></apollonav> <apollonav></apollonav>
<div class="container-fluid" ng-controller="SystemRoleController"> <div class="container-fluid" ng-controller="SystemRoleController">
<div class="col-md-10 col-md-offset-1 panel"> <div class="col-md-10 col-md-offset-1 panel">
<section class="panel-body" ng-show="isRootUser"> <section class="panel-body" ng-show="isRootUser">
<section class="row"> <section class="row">
<h5>为用户添加创建应用权限 <h5>{{'SystemRole.AddCreateAppRoleToUser' | translate }}
<small> <small>
(系统参数中设置 role.create-application.enabled=true 会限制只有超级管理员和拥有创建应用权限的帐号可以创建项目) {{'SystemRole.AddCreateAppRoleToUserTips' | translate }}
</small> </small>
</h5> </h5>
<hr> <hr>
<div class="row"> <div class="row">
<div class="form-horizontal"> <div class="form-horizontal">
<div class="form-group"> <div class="form-group">
<label class="col-sm-2 control-label">用户选择<br></label> <label
class="col-sm-2 control-label">{{'SystemRole.ChooseUser' | translate }}<br></label>
<div class="col-sm-8"> <div class="col-sm-8">
<form class="form-inline" ng-submit="addCreateApplicationRoleToUser()"> <form class="form-inline" ng-submit="addCreateApplicationRoleToUser()">
<div class="form-group"> <div class="form-group">
<apollouserselector apollo-id="modifySystemRoleWidgetId"></apollouserselector> <apollouserselector apollo-id="modifySystemRoleWidgetId">
</apollouserselector>
</div> </div>
<button type="submit" class="btn btn-default" style="margin-left: 20px;">添加</button> <button type="submit" class="btn btn-default"
style="margin-left: 20px;">{{'SystemRole.Add' | translate }}</button>
</form> </form>
<div class="item-container"> <div class="item-container">
<h5>已拥有权限用户</h5> <h5>{{'SystemRole.AuthorizedUser' | translate }}</h5>
<div class="btn-group item-info" ng-repeat="user in hasCreateApplicationPermissionUserList"> <div class="btn-group item-info"
ng-repeat="user in hasCreateApplicationPermissionUserList">
<button type="button" class="btn btn-default" ng-bind="user"></button> <button type="button" class="btn btn-default" ng-bind="user"></button>
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" <button type="button" class="btn btn-default dropdown-toggle"
aria-haspopup="true" aria-expanded="false" ng-click="deleteCreateApplicationRoleFromUser(user)"> data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"
ng-click="deleteCreateApplicationRoleFromUser(user)">
<span class="glyphicon glyphicon-remove"></span> <span class="glyphicon glyphicon-remove"></span>
</button> </button>
</div> </div>
...@@ -60,9 +66,9 @@ ...@@ -60,9 +66,9 @@
</section> </section>
<section class="row"> <section class="row">
<h5>修改应用管理员分配权限 <h5>{{'SystemRole.ModifyAppAdminUser' | translate }}
<small> <small>
(系统参数中设置 role.manage-app-master.enabled=true 会限制只有超级管理员和拥有管理员分配权限的帐号可以修改项目管理员) {{'SystemRole.ModifyAppAdminUserTips' | translate }}
</small> </small>
</h5> </h5>
<hr> <hr>
...@@ -70,29 +76,32 @@ ...@@ -70,29 +76,32 @@
<div class="form-group" valdr-form-group> <div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
应用AppId</label> {{'SystemRole.AppIdTips' | translate }}
</label>
<div class="col-sm-5"> <div class="col-sm-5">
<input type="text" class="form-control" ng-model="app.appId"> <input type="text" class="form-control" ng-model="app.appId">
<small>(请先查询应用信息)</small> <small>{{'SystemRole.Title' | translate }}</small>
</div> </div>
<div class="col-sm-1"> <div class="col-sm-1">
<button class="btn btn-info" ng-click="getAppInfo()">查询</button> <button class="btn btn-info"
ng-click="getAppInfo()">{{'Common.Search' | translate }}</button>
</div> </div>
</div> </div>
<div class="form-group" valdr-form-group> <div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
应用信息</label> {{'SystemRole.AppInfo' | translate }}</label>
<div class="col-sm-5"> <div class="col-sm-5">
<h5 ng-show="app.info" ng-bind="app.info"></h5> <h5 ng-show="app.info" ng-bind="app.info"></h5>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-2 control-label">用户选择<br></label> <label class="col-sm-2 control-label">{{'SystemRole.ChooseUser' | translate }}<br></label>
<div class="col-sm-8"> <div class="col-sm-8">
<form class="form-inline"> <form class="form-inline">
<div class="form-group"> <div class="form-group">
<apollouserselector apollo-id="modifyManageAppMasterRoleWidgetId"></apollouserselector> <apollouserselector apollo-id="modifyManageAppMasterRoleWidgetId">
</apollouserselector>
</div> </div>
</form> </form>
</div> </div>
...@@ -101,14 +110,12 @@ ...@@ -101,14 +110,12 @@
<div class="form-group"> <div class="form-group">
<div class="col-sm-offset-2 col-sm-9"> <div class="col-sm-offset-2 col-sm-9">
<button type="submit" class="btn btn-primary" <button type="submit" class="btn btn-primary"
ng-disabled="operateManageAppMasterRoleBtn" ng-disabled="operateManageAppMasterRoleBtn" ng-click="allowAppMasterAssignRole()">
ng-click="allowAppMasterAssignRole()"> {{'SystemRole.AllowAppMasterAssignRole' | translate }}
允许此用户作为管理员时添加Master
</button> </button>
<button type="submit" class="btn btn-primary" <button type="submit" class="btn btn-primary"
ng-disabled="operateManageAppMasterRoleBtn" ng-disabled="operateManageAppMasterRoleBtn" ng-click="deleteAppMasterAssignRole()">
ng-click="deleteAppMasterAssignRole()"> {{'SystemRole.DeleteAppMasterAssignRole' | translate }}
禁止此用户作为管理员时添加Master
</button> </button>
</div> </div>
</div> </div>
...@@ -118,52 +125,58 @@ ...@@ -118,52 +125,58 @@
</section> </section>
<section class="panel-body text-center" ng-if="!isRootUser"> <section class="panel-body text-center" ng-if="!isRootUser">
<h4>当前页面只对Apollo管理员开放</h4> <h4>{{'Common.IsRootUser' | translate }}</h4>
</section> </section>
</div> </div>
</div> </div>
<div ng-include="'../views/common/footer.html'"></div> <div ng-include="'../views/common/footer.html'"></div>
<!-- jquery.js --> <!-- jquery.js -->
<script src="../vendor/jquery.min.js" type="text/javascript"></script> <script src="../vendor/jquery.min.js" type="text/javascript"></script>
<!--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-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>
<script src="vendor/angular/angular-cookies.min.js"></script>
<!--valdr--> <script src="vendor/angular/angular-translate.2.18.1/angular-translate.min.js"></script>
<script src="../vendor/valdr/valdr.min.js" type="text/javascript"></script> <script src="vendor/angular/angular-translate.2.18.1/angular-translate-loader-static-files.min.js"></script>
<script src="../vendor/valdr/valdr-message.min.js" type="text/javascript"></script> <script src="vendor/angular/angular-translate.2.18.1/angular-translate-storage-cookie.min.js"></script>
<!-- bootstrap.js --> <!--valdr-->
<script src="../vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script> <script src="../vendor/valdr/valdr.min.js" type="text/javascript"></script>
<script src="../vendor/valdr/valdr-message.min.js" type="text/javascript"></script>
<script src="../vendor/lodash.min.js"></script> <!-- bootstrap.js -->
<script src="../vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
<script src="../vendor/select2/select2.min.js" type="text/javascript"></script> <script src="../vendor/lodash.min.js"></script>
<!--biz-->
<!--must import-->
<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/EnvService.js"></script>
<script type="application/javascript" src="../scripts/services/UserService.js"></script>
<script type="application/javascript" src="../scripts/services/CommonService.js"></script>
<script type="application/javascript" src="../scripts/services/PermissionService.js"></script>
<script type="application/javascript" src="../scripts/services/ClusterService.js"></script>
<script type="application/javascript" src="../scripts/services/NamespaceService.js"></script>
<script type="application/javascript" src="../scripts/services/SystemRoleService.js"></script>
<script type="application/javascript" src="../scripts/AppUtils.js"></script> <script src="../vendor/select2/select2.min.js" type="text/javascript"></script>
<!--biz-->
<!--must import-->
<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/EnvService.js"></script>
<script type="application/javascript" src="../scripts/services/UserService.js"></script>
<script type="application/javascript" src="../scripts/services/CommonService.js"></script>
<script type="application/javascript" src="../scripts/services/PermissionService.js"></script>
<script type="application/javascript" src="../scripts/services/ClusterService.js"></script>
<script type="application/javascript" src="../scripts/services/NamespaceService.js"></script>
<script type="application/javascript" src="../scripts/services/SystemRoleService.js"></script>
<script type="application/javascript" src="../scripts/PageCommon.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/valdr.js"></script>
<script type="application/javascript" src="../scripts/controller/role/SystemRoleController.js"></script> <script type="application/javascript" src="../scripts/PageCommon.js"></script>
<script type="application/javascript" src="../scripts/directive/directive.js"></script>
<script type="application/javascript" src="../scripts/valdr.js"></script>
<script type="application/javascript" src="../scripts/controller/role/SystemRoleController.js"></script>
</body> </body>
</html> </html>
<!doctype html> <!doctype html>
<html ng-app="system_info"> <html ng-app="system_info">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="icon" href="../img/config.png"> <link rel="icon" href="../img/config.png">
...@@ -9,80 +10,89 @@ ...@@ -9,80 +10,89 @@
<link rel="stylesheet" type="text/css" media='all' href="../vendor/angular/loading-bar.min.css"> <link rel="stylesheet" type="text/css" media='all' href="../vendor/angular/loading-bar.min.css">
<link rel="stylesheet" type="text/css" href="../styles/common-style.css"> <link rel="stylesheet" type="text/css" href="../styles/common-style.css">
<link rel="stylesheet" type="text/css" href="../vendor/select2/select2.min.css"> <link rel="stylesheet" type="text/css" href="../vendor/select2/select2.min.css">
<title>系统信息</title> <title>{{'SystemInfo.Title' | translate }}</title>
</head> </head>
<body> <body>
<apollonav></apollonav> <apollonav></apollonav>
<div class="container-fluid" ng-controller="SystemInfoController"> <div class="container-fluid" ng-controller="SystemInfoController">
<div class="col-md-10 col-md-offset-1 panel"> <div class="col-md-10 col-md-offset-1 panel">
<section class="panel-body" ng-show="isRootUser"> <section class="panel-body" ng-show="isRootUser">
<section class="row"> <section class="row">
<h3>系统信息 <h3>{{'SystemInfo.Title' | translate }}
</h3> </h3>
<h6 ng-show="systemInfo.version">系统版本: {{systemInfo.version}}</h6> <h6 ng-show="systemInfo.version">{{'SystemInfo.SystemVersion' | translate }}: {{systemInfo.version}}
<h6>环境列表来自于ApolloPortalDB.ServerConfig中的<strong>apollo.portal.envs</strong>配置,可以到<a href="server_config.html">系统参数</a>页面配置, </h6>
更多信息可以参考<a href="https://github.com/ctripcorp/apollo/wiki/%E5%88%86%E5%B8%83%E5%BC%8F%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97">分布式部署指南</a>中的<strong>apollo.portal.envs - 可支持的环境列表</strong>章节。 <h6 translate="SystemInfo.Tips1" translate-value-server-config-url="server_config.html"
translate-value-wiki-url="https://github.com/ctripcorp/apollo/wiki/%E5%88%86%E5%B8%83%E5%BC%8F%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97">
</h6> </h6>
<h6>Meta server地址展示了该环境配置的meta server信息,更多信息可以参考<a href="https://github.com/ctripcorp/apollo/wiki/%E5%88%86%E5%B8%83%E5%BC%8F%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97">分布式部署指南</a>中的<strong>配置apollo-portal的meta service信息</strong>章节。
<h6 translate="SystemInfo.Tips2"
translate-value-wiki-url="https://github.com/ctripcorp/apollo/wiki/%E5%88%86%E5%B8%83%E5%BC%8F%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97">
</h6> </h6>
<div ng-repeat="env in systemInfo.environments"> <div ng-repeat="env in systemInfo.environments">
<hr> <hr>
<h4>环境: {{env.env}} <h4>{{'Common.Environment' | translate }}: {{env.env}}
</h4> </h4>
<h5>Active: {{env.active}} <h5>{{'SystemInfo.Active' | translate }}: {{env.active}}
<span ng-show="env.active == false" style="color: #a94442;">(当前环境状态异常,请结合下方系统信息和Admin Service的Check Health结果排查)</span> <span ng-show="env.active == false"
style="color: #a94442;">{{'SystemInfo.ActiveTips' | translate }}</span>
</h5> </h5>
<h5>Meta server地址: {{env.metaServerAddress}}</h5> <h5>{{'SystemInfo.MetaServerAddress' | translate }}: {{env.metaServerAddress}}</h5>
<div ng-show="env.errorMessage" ng-bind="env.errorMessage" class="alert alert-danger" role="alert"> <div ng-show="env.errorMessage" ng-bind="env.errorMessage" class="alert alert-danger"
role="alert">
</div> </div>
<h4 class="text-center">Config Services</h4> <h4 class="text-center">{{'SystemInfo.ConfigServices' | translate }}</h4>
<table class="table table-striped table-hover table-bordered"> <table class="table table-striped table-hover table-bordered">
<thead> <thead>
<tr> <tr>
<th>Name</th> <th>{{'SystemInfo.ConfigServices.Name' | translate }}</th>
<th>Instance Id</th> <th>{{'SystemInfo.ConfigServices.InstanceId' | translate }}</th>
<th>Home Page Url</th> <th>{{'SystemInfo.ConfigServices.HomePageUrl' | translate }}</th>
<th>Check Health</th> <th>{{'SystemInfo.ConfigServices.CheckHealth' | translate }}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr ng-show="(!env.configServices || env.configServices.length < 1)"> <tr ng-show="(!env.configServices || env.configServices.length < 1)">
<td colspan="4">No config service found!</td> <td colspan="4">{{'SystemInfo.NoConfigServiceTips' | translate }}</td>
</tr> </tr>
<tr ng-show="env.configServices && env.configServices.length > 0" ng-repeat="service in env.configServices"> <tr ng-show="env.configServices && env.configServices.length > 0"
ng-repeat="service in env.configServices">
<td>{{service.appName}}</td> <td>{{service.appName}}</td>
<td>{{service.instanceId}}</td> <td>{{service.instanceId}}</td>
<td>{{service.homepageUrl}}</td> <td>{{service.homepageUrl}}</td>
<td><a href="javascript:;" ng-click="check(service.instanceId, service.homepageUrl)">check</a> <td><a href="javascript:;"
ng-click="check(service.instanceId, service.homepageUrl)">{{'SystemInfo.Check' | translate }}</a>
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<h4 class="text-center">Admin Services</h4> <h4 class="text-center">{{'SystemInfo.AdminServices' | translate }}</h4>
<table class="table table-striped table-hover table-bordered"> <table class="table table-striped table-hover table-bordered">
<thead> <thead>
<tr> <tr>
<th>Name</th> <th>{{'SystemInfo.AdminServices.Name' | translate }}</th>
<th>Instance Id</th> <th>{{'SystemInfo.AdminServices.InstanceId' | translate }}</th>
<th>Home Page Url</th> <th>{{'SystemInfo.AdminServices.HomePageUrl' | translate }}</th>
<th>Check Health</th> <th>{{'SystemInfo.AdminServices.CheckHealth' | translate }}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr ng-show="(!env.adminServices || env.adminServices.length < 1)"> <tr ng-show="(!env.adminServices || env.adminServices.length < 1)">
<td colspan="4">No admin service found!</td> <td colspan="4">{{'SystemInfo.NoAdminServiceTips' | translate }}</td>
</tr> </tr>
<tr ng-show="env.adminServices && env.adminServices.length > 0" ng-repeat="service in env.adminServices"> <tr ng-show="env.adminServices && env.adminServices.length > 0"
ng-repeat="service in env.adminServices">
<td>{{service.appName}}</td> <td>{{service.appName}}</td>
<td>{{service.instanceId}}</td> <td>{{service.instanceId}}</td>
<td>{{service.homepageUrl}}</td> <td>{{service.homepageUrl}}</td>
<td><a href="javascript:;" ng-click="check(service.instanceId, service.homepageUrl)">check</a> <td><a href="javascript:;"
ng-click="check(service.instanceId, service.homepageUrl)">{{'SystemInfo.Check' | translate }}</a>
</tr> </tr>
</tbody> </tbody>
</table> </table>
...@@ -92,52 +102,58 @@ ...@@ -92,52 +102,58 @@
</section> </section>
<section class="panel-body text-center" ng-if="!isRootUser"> <section class="panel-body text-center" ng-if="!isRootUser">
<h4>当前页面只对Apollo管理员开放</h4> <h4>{{'Common.IsRootUser' | translate }}</h4>
</section> </section>
</div> </div>
</div> </div>
<div ng-include="'../views/common/footer.html'"></div>
<div ng-include="'../views/common/footer.html'"></div> <!-- jquery.js -->
<script src="../vendor/jquery.min.js" type="text/javascript"></script>
<!-- jquery.js --> <!--angular-->
<script src="../vendor/jquery.min.js" type="text/javascript"></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-toastr-1.4.1.tpls.min.js"></script>
<script src="../vendor/angular/loading-bar.min.js"></script>
<script src="vendor/angular/angular-cookies.min.js"></script>
<!--angular--> <script src="vendor/angular/angular-translate.2.18.1/angular-translate.min.js"></script>
<script src="../vendor/angular/angular.min.js"></script> <script src="vendor/angular/angular-translate.2.18.1/angular-translate-loader-static-files.min.js"></script>
<script src="../vendor/angular/angular-route.min.js"></script> <script src="vendor/angular/angular-translate.2.18.1/angular-translate-storage-cookie.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/loading-bar.min.js"></script>
<!--valdr--> <!--valdr-->
<script src="../vendor/valdr/valdr.min.js" type="text/javascript"></script> <script src="../vendor/valdr/valdr.min.js" type="text/javascript"></script>
<script src="../vendor/valdr/valdr-message.min.js" type="text/javascript"></script> <script src="../vendor/valdr/valdr-message.min.js" type="text/javascript"></script>
<!-- bootstrap.js --> <!-- bootstrap.js -->
<script src="../vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script> <script src="../vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
<script src="../vendor/lodash.min.js"></script> <script src="../vendor/lodash.min.js"></script>
<script src="../vendor/select2/select2.min.js" type="text/javascript"></script> <script src="../vendor/select2/select2.min.js" type="text/javascript"></script>
<!--biz--> <!--biz-->
<!--must import--> <!--must import-->
<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/UserService.js"></script>
<script type="application/javascript" src="../scripts/services/CommonService.js"></script> <script type="application/javascript" src="../scripts/services/CommonService.js"></script>
<script type="application/javascript" src="../scripts/services/PermissionService.js"></script> <script type="application/javascript" src="../scripts/services/PermissionService.js"></script>
<script type="application/javascript" src="../scripts/services/ClusterService.js"></script> <script type="application/javascript" src="../scripts/services/ClusterService.js"></script>
<script type="application/javascript" src="../scripts/services/NamespaceService.js"></script> <script type="application/javascript" src="../scripts/services/NamespaceService.js"></script>
<script type="application/javascript" src="../scripts/services/SystemInfoService.js"></script> <script type="application/javascript" src="../scripts/services/SystemInfoService.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/PageCommon.js"></script> <script type="application/javascript" src="../scripts/PageCommon.js"></script>
<script type="application/javascript" src="../scripts/directive/directive.js"></script> <script type="application/javascript" src="../scripts/directive/directive.js"></script>
<script type="application/javascript" src="../scripts/valdr.js"></script> <script type="application/javascript" src="../scripts/valdr.js"></script>
<script type="application/javascript" src="../scripts/controller/SystemInfoController.js"></script> <script type="application/javascript" src="../scripts/controller/SystemInfoController.js"></script>
</body> </body>
</html> </html>
\ No newline at end of file
<!doctype html> <!doctype html>
<html ng-app="user"> <html ng-app="user">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="icon" href="./img/config.png"> <link rel="icon" href="./img/config.png">
...@@ -10,40 +11,41 @@ ...@@ -10,40 +11,41 @@
<link rel="stylesheet" type="text/css" media='all' href="vendor/angular/loading-bar.min.css"> <link rel="stylesheet" type="text/css" media='all' href="vendor/angular/loading-bar.min.css">
<link rel="stylesheet" type="text/css" href="styles/common-style.css"> <link rel="stylesheet" type="text/css" href="styles/common-style.css">
<title>用户管理</title> <title>{{'UserMange.Title' | translate }}</title>
</head> </head>
<body> <body>
<apollonav></apollonav> <apollonav></apollonav>
<div class="container-fluid apollo-container"> <div class="container-fluid apollo-container">
<div class="row"> <div class="row">
<div class="col-md-8 col-md-offset-2"> <div class="col-md-8 col-md-offset-2">
<div class="panel"> <div class="panel">
<header class="panel-heading"> <header class="panel-heading">
用户管理 {{'UserMange.Title' | translate }}
<small> <small>
(仅对默认的Spring Security简单认证方式有效: -Dapollo_profile=github,auth) {{'UserMange.TitleTips' | translate }}
</small> </small>
</header> </header>
<form class="form-horizontal panel-body" name="appForm" ng-controller="UserController" <form class="form-horizontal panel-body" name="appForm" ng-controller="UserController"
valdr-type="App" valdr-type="App" ng-submit="createOrUpdateUser()">
ng-submit="createOrUpdateUser()">
<div class="form-group" valdr-form-group> <div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
用户名</label> {{'UserMange.UserName' | translate }}
</label>
<div class="col-sm-5"> <div class="col-sm-5">
<input type="text" class="form-control" name="username" ng-model="user.username"> <input type="text" class="form-control" name="username" ng-model="user.username">
<small>输入的用户名如果不存在,则新建。若已存在,则更新。</small> <small>{{'UserMange.UserNameTips' | translate }}</small>
</div> </div>
</div> </div>
<div class="form-group" valdr-form-group> <div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
密码</label> {{'UserMange.Pwd' | translate }}
</label>
<div class="col-sm-5"> <div class="col-sm-5">
<input type="text" class="form-control" name="password" ng-model="user.password"> <input type="text" class="form-control" name="password" ng-model="user.password">
</div> </div>
...@@ -51,7 +53,8 @@ ...@@ -51,7 +53,8 @@
<div class="form-group" valdr-form-group> <div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
邮箱</label> {{'UserMange.Email' | translate }}
</label>
<div class="col-sm-5"> <div class="col-sm-5">
<input type="text" class="form-control" name="password" ng-model="user.email"> <input type="text" class="form-control" name="password" ng-model="user.email">
</div> </div>
...@@ -61,7 +64,7 @@ ...@@ -61,7 +64,7 @@
<div class="col-sm-offset-2 col-sm-9"> <div class="col-sm-offset-2 col-sm-9">
<button type="submit" class="btn btn-primary" <button type="submit" class="btn btn-primary"
ng-disabled="appForm.$invalid || submitBtnDisabled">提交 ng-disabled="appForm.$invalid || submitBtnDisabled">{{'Common.Submit' | translate }}
</button> </button>
</div> </div>
</div> </div>
...@@ -70,39 +73,45 @@ ...@@ -70,39 +73,45 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div ng-include="'views/common/footer.html'"></div> <div ng-include="'views/common/footer.html'"></div>
<!--angular--> <!--angular-->
<script src="vendor/angular/angular.min.js"></script> <script src="vendor/angular/angular.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>
<script src="vendor/angular/angular-cookies.min.js"></script>
<!-- jquery.js --> <script src="vendor/angular/angular-translate.2.18.1/angular-translate.min.js"></script>
<script src="vendor/jquery.min.js" type="text/javascript"></script> <script src="vendor/angular/angular-translate.2.18.1/angular-translate-loader-static-files.min.js"></script>
<script src="vendor/select2/select2.min.js" type="text/javascript"></script> <script src="vendor/angular/angular-translate.2.18.1/angular-translate-storage-cookie.min.js"></script>
<!-- bootstrap.js --> <!-- jquery.js -->
<script src="vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script> <script src="vendor/jquery.min.js" type="text/javascript"></script>
<script src="vendor/select2/select2.min.js" type="text/javascript"></script>
<!--valdr--> <!-- bootstrap.js -->
<script src="vendor/valdr/valdr.min.js" type="text/javascript"></script> <script src="vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
<script src="vendor/valdr/valdr-message.min.js" type="text/javascript"></script>
<script type="application/javascript" src="scripts/app.js"></script> <!--valdr-->
<script type="application/javascript" src="scripts/services/AppService.js"></script> <script src="vendor/valdr/valdr.min.js" type="text/javascript"></script>
<script type="application/javascript" src="scripts/services/EnvService.js"></script> <script src="vendor/valdr/valdr-message.min.js" type="text/javascript"></script>
<script type="application/javascript" src="scripts/services/UserService.js"></script>
<script type="application/javascript" src="scripts/services/CommonService.js"></script>
<script type="application/javascript" src="scripts/AppUtils.js"></script>
<script type="application/javascript" src="scripts/services/OrganizationService.js"></script>
<script type="application/javascript" src="scripts/directive/directive.js"></script>
<script type="application/javascript" src="scripts/services/PermissionService.js"></script>
<script type="application/javascript" src="scripts/controller/UserController.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/EnvService.js"></script>
<script type="application/javascript" src="scripts/services/UserService.js"></script>
<script type="application/javascript" src="scripts/services/CommonService.js"></script>
<script type="application/javascript" src="scripts/AppUtils.js"></script>
<script type="application/javascript" src="scripts/services/OrganizationService.js"></script>
<script type="application/javascript" src="scripts/directive/directive.js"></script>
<script type="application/javascript" src="scripts/services/PermissionService.js"></script>
<script src="scripts/valdr.js" type="text/javascript"></script> <script type="application/javascript" src="scripts/controller/UserController.js"></script>
<script src="scripts/valdr.js" type="text/javascript"></script>
</body> </body>
</html> </html>
\ No newline at end of file
/*
AngularJS v1.4.1
(c) 2010-2015 Google, Inc. http://angularjs.org
License: MIT
*/
(function(n,h,p){'use strict';function E(a){var f=[];r(f,h.noop).chars(a);return f.join("")}function g(a,f){var d={},c=a.split(","),b;for(b=0;b<c.length;b++)d[f?h.lowercase(c[b]):c[b]]=!0;return d}function F(a,f){function d(a,b,d,l){b=h.lowercase(b);if(s[b])for(;e.last()&&t[e.last()];)c("",e.last());u[b]&&e.last()==b&&c("",b);(l=v[b]||!!l)||e.push(b);var m={};d.replace(G,function(b,a,f,c,d){m[a]=q(f||c||d||"")});f.start&&f.start(b,m,l)}function c(b,a){var c=0,d;if(a=h.lowercase(a))for(c=e.length-
1;0<=c&&e[c]!=a;c--);if(0<=c){for(d=e.length-1;d>=c;d--)f.end&&f.end(e[d]);e.length=c}}"string"!==typeof a&&(a=null===a||"undefined"===typeof a?"":""+a);var b,k,e=[],m=a,l;for(e.last=function(){return e[e.length-1]};a;){l="";k=!0;if(e.last()&&w[e.last()])a=a.replace(new RegExp("([\\W\\w]*)<\\s*\\/\\s*"+e.last()+"[^>]*>","i"),function(a,b){b=b.replace(H,"$1").replace(I,"$1");f.chars&&f.chars(q(b));return""}),c("",e.last());else{if(0===a.indexOf("\x3c!--"))b=a.indexOf("--",4),0<=b&&a.lastIndexOf("--\x3e",
b)===b&&(f.comment&&f.comment(a.substring(4,b)),a=a.substring(b+3),k=!1);else if(x.test(a)){if(b=a.match(x))a=a.replace(b[0],""),k=!1}else if(J.test(a)){if(b=a.match(y))a=a.substring(b[0].length),b[0].replace(y,c),k=!1}else K.test(a)&&((b=a.match(z))?(b[4]&&(a=a.substring(b[0].length),b[0].replace(z,d)),k=!1):(l+="<",a=a.substring(1)));k&&(b=a.indexOf("<"),l+=0>b?a:a.substring(0,b),a=0>b?"":a.substring(b),f.chars&&f.chars(q(l)))}if(a==m)throw L("badparse",a);m=a}c()}function q(a){if(!a)return"";A.innerHTML=
a.replace(/</g,"&lt;");return A.textContent}function B(a){return a.replace(/&/g,"&amp;").replace(M,function(a){var d=a.charCodeAt(0);a=a.charCodeAt(1);return"&#"+(1024*(d-55296)+(a-56320)+65536)+";"}).replace(N,function(a){return"&#"+a.charCodeAt(0)+";"}).replace(/</g,"&lt;").replace(/>/g,"&gt;")}function r(a,f){var d=!1,c=h.bind(a,a.push);return{start:function(a,k,e){a=h.lowercase(a);!d&&w[a]&&(d=a);d||!0!==C[a]||(c("<"),c(a),h.forEach(k,function(d,e){var k=h.lowercase(e),g="img"===a&&"src"===k||
"background"===k;!0!==O[k]||!0===D[k]&&!f(d,g)||(c(" "),c(e),c('="'),c(B(d)),c('"'))}),c(e?"/>":">"))},end:function(a){a=h.lowercase(a);d||!0!==C[a]||(c("</"),c(a),c(">"));a==d&&(d=!1)},chars:function(a){d||c(B(a))}}}var L=h.$$minErr("$sanitize"),z=/^<((?:[a-zA-Z])[\w:-]*)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*(>?)/,y=/^<\/\s*([\w:-]+)[^>]*>/,G=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,K=/^</,J=/^<\//,H=/\x3c!--(.*?)--\x3e/g,x=/<!DOCTYPE([^>]*?)>/i,
I=/<!\[CDATA\[(.*?)]]\x3e/g,M=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,N=/([^\#-~| |!])/g,v=g("area,br,col,hr,img,wbr");n=g("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr");p=g("rp,rt");var u=h.extend({},p,n),s=h.extend({},n,g("address,article,aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul")),t=h.extend({},p,g("a,abbr,acronym,b,bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,samp,small,span,strike,strong,sub,sup,time,tt,u,var"));
n=g("circle,defs,desc,ellipse,font-face,font-face-name,font-face-src,g,glyph,hkern,image,linearGradient,line,marker,metadata,missing-glyph,mpath,path,polygon,polyline,radialGradient,rect,stop,svg,switch,text,title,tspan,use");var w=g("script,style"),C=h.extend({},v,s,t,u,n),D=g("background,cite,href,longdesc,src,usemap,xlink:href");n=g("abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,scope,scrolling,shape,size,span,start,summary,tabindex,target,title,type,valign,value,vspace,width");
p=g("accent-height,accumulate,additive,alphabetic,arabic-form,ascent,baseProfile,bbox,begin,by,calcMode,cap-height,class,color,color-rendering,content,cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,font-size,font-stretch,font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,gradientUnits,hanging,height,horiz-adv-x,horiz-origin-x,ideographic,k,keyPoints,keySplines,keyTimes,lang,marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,mathematical,max,min,offset,opacity,orient,origin,overline-position,overline-thickness,panose-1,path,pathLength,points,preserveAspectRatio,r,refX,refY,repeatCount,repeatDur,requiredExtensions,requiredFeatures,restart,rotate,rx,ry,slope,stemh,stemv,stop-color,stop-opacity,strikethrough-position,strikethrough-thickness,stroke,stroke-dasharray,stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,stroke-opacity,stroke-width,systemLanguage,target,text-anchor,to,transform,type,u1,u2,underline-position,underline-thickness,unicode,unicode-range,units-per-em,values,version,viewBox,visibility,width,widths,x,x-height,x1,x2,xlink:actuate,xlink:arcrole,xlink:role,xlink:show,xlink:title,xlink:type,xml:base,xml:lang,xml:space,xmlns,xmlns:xlink,y,y1,y2,zoomAndPan",
!0);var O=h.extend({},D,p,n),A=document.createElement("pre");h.module("ngSanitize",[]).provider("$sanitize",function(){this.$get=["$$sanitizeUri",function(a){return function(f){var d=[];F(f,r(d,function(c,b){return!/^unsafe/.test(a(c,b))}));return d.join("")}}]});h.module("ngSanitize").filter("linky",["$sanitize",function(a){var f=/((ftp|https?):\/\/|(www\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"\u201d\u2019]/i,d=/^mailto:/i;return function(c,b){function k(a){a&&g.push(E(a))}function e(a,
c){g.push("<a ");h.isDefined(b)&&g.push('target="',b,'" ');g.push('href="',a.replace(/"/g,"&quot;"),'">');k(c);g.push("</a>")}if(!c)return c;for(var m,l=c,g=[],n,p;m=l.match(f);)n=m[0],m[2]||m[4]||(n=(m[3]?"http://":"mailto:")+n),p=m.index,k(l.substr(0,p)),e(n,m[0].replace(d,"")),l=l.substring(p+m[0].length);k(l);return a(g.join(""))}}])})(window,window.angular);
//# sourceMappingURL=angular-sanitize.min.js.map
\ No newline at end of file
/*!
* angular-translate - v2.18.1 - 2018-05-19
*
* Copyright (c) 2018 The angular-translate team, Pascal Precht; Licensed MIT
*/
!function(e,i){"function"==typeof define&&define.amd?define([],function(){return i()}):"object"==typeof module&&module.exports?module.exports=i():i()}(0,function(){function e(n,a){"use strict";return function(r){if(!(r&&(angular.isArray(r.files)||angular.isString(r.prefix)&&angular.isString(r.suffix))))throw new Error("Couldn't load static files, no files and prefix or suffix specified!");r.files||(r.files=[{prefix:r.prefix,suffix:r.suffix}]);for(var e=function(e){if(!e||!angular.isString(e.prefix)||!angular.isString(e.suffix))throw new Error("Couldn't load static file, no prefix or suffix specified!");var i=[e.prefix,r.key,e.suffix].join("");return angular.isObject(r.fileMap)&&r.fileMap[i]&&(i=r.fileMap[i]),a(angular.extend({url:i,method:"GET"},r.$http)).then(function(e){return e.data},function(){return n.reject(r.key)})},i=[],t=r.files.length,f=0;f<t;f++)i.push(e({prefix:r.files[f].prefix,key:r.key,suffix:r.files[f].suffix}));return n.all(i).then(function(e){for(var i=e.length,r={},t=0;t<i;t++)for(var f in e[t])r[f]=e[t][f];return r})}}return e.$inject=["$q","$http"],angular.module("pascalprecht.translate").factory("$translateStaticFilesLoader",e),e.displayName="$translateStaticFilesLoader","pascalprecht.translate"});
\ No newline at end of file
/*!
* angular-translate - v2.18.1 - 2018-05-19
*
* Copyright (c) 2018 The angular-translate team, Pascal Precht; Licensed MIT
*/
!function(t,e){"function"==typeof define&&define.amd?define([],function(){return e()}):"object"==typeof module&&module.exports?module.exports=e():e()}(0,function(){function t(t){"use strict";var n;if(1===angular.version.major&&4<=angular.version.minor){var o=t.get("$cookies");n={get:function(t){return o.get(t)},put:function(t,e){o.put(t,e)}}}else{var r=t.get("$cookieStore");n={get:function(t){return r.get(t)},put:function(t,e){r.put(t,e)}}}return{get:function(t){return n.get(t)},set:function(t,e){n.put(t,e)},put:function(t,e){n.put(t,e)}}}return t.$inject=["$injector"],angular.module("pascalprecht.translate").factory("$translateCookieStorage",t),t.displayName="$translateCookieStorage","pascalprecht.translate"});
\ No newline at end of file
/*!
* angular-translate - v2.18.1 - 2018-05-19
*
* Copyright (c) 2018 The angular-translate team, Pascal Precht; Licensed MIT
*/
!function(t,e){"function"==typeof define&&define.amd?define([],function(){return e()}):"object"==typeof module&&module.exports?module.exports=e():e()}(0,function(){function t(e){"use strict";var n=e.storageKey(),a=e.storage(),t=function(){var t=e.preferredLanguage();angular.isString(t)?e.use(t):a.put(n,e.use())};t.displayName="fallbackFromIncorrectStorageValue",a?a.get(n)?e.use(a.get(n)).catch(t):t():angular.isString(e.preferredLanguage())&&e.use(e.preferredLanguage())}function e(t,r,e,i){"use strict";var z,c,T,x,F,I,_,n,V,R,D,K,U,M,H,G,q={},Y=[],B=t,J=[],Q="translate-cloak",W=!1,X=!1,Z=".",tt=!1,et=!1,nt=0,at=!0,a="default",s={default:function(t){return(t||"").split("-").join("_")},java:function(t){var e=(t||"").split("-").join("_"),n=e.split("_");return 1<n.length?n[0].toLowerCase()+"_"+n[1].toUpperCase():e},bcp47:function(t){var e=(t||"").split("_").join("-"),n=e.split("-");switch(n.length){case 1:n[0]=n[0].toLowerCase();break;case 2:n[0]=n[0].toLowerCase(),4===n[1].length?n[1]=n[1].charAt(0).toUpperCase()+n[1].slice(1).toLowerCase():n[1]=n[1].toUpperCase();break;case 3:n[0]=n[0].toLowerCase(),n[1]=n[1].charAt(0).toUpperCase()+n[1].slice(1).toLowerCase(),n[2]=n[2].toUpperCase();break;default:return e}return n.join("-")},"iso639-1":function(t){return(t||"").split("_").join("-").split("-")[0].toLowerCase()}},o=function(){if(angular.isFunction(i.getLocale))return i.getLocale();var t,e,n=r.$get().navigator,a=["language","browserLanguage","systemLanguage","userLanguage"];if(angular.isArray(n.languages))for(t=0;t<n.languages.length;t++)if((e=n.languages[t])&&e.length)return e;for(t=0;t<a.length;t++)if((e=n[a[t]])&&e.length)return e;return null};o.displayName="angular-translate/service: getFirstBrowserLanguage";var rt=function(){var t=o()||"";return s[a]&&(t=s[a](t)),t};rt.displayName="angular-translate/service: getLocale";var it=function(t,e){for(var n=0,a=t.length;n<a;n++)if(t[n]===e)return n;return-1},st=function(){return this.toString().replace(/^\s+|\s+$/g,"")},f=function(t){return angular.isString(t)?t.toLowerCase():t},ot=function(t){if(t){for(var e,n=[],a=f(t),r=0,i=Y.length;r<i;r++)n.push(f(Y[r]));if(-1<(r=it(n,a)))return Y[r];if(c)for(var s in c)if(c.hasOwnProperty(s)){var o=!1,l=Object.prototype.hasOwnProperty.call(c,s)&&f(s)===f(t);if("*"===s.slice(-1)&&(o=f(s.slice(0,-1))===f(t.slice(0,s.length-1))),(l||o)&&(e=c[s],-1<it(n,f(e))))return e}var u=t.split("_");return 1<u.length&&-1<it(n,f(u[0]))?u[0]:void 0}},lt=function(t,e){if(!t&&!e)return q;if(t&&!e){if(angular.isString(t))return q[t]}else angular.isObject(q[t])||(q[t]={}),angular.extend(q[t],ut(e));return this};this.translations=lt,this.cloakClassName=function(t){return t?(Q=t,this):Q},this.nestedObjectDelimeter=function(t){return t?(Z=t,this):Z};var ut=function(t,e,n,a){var r,i,s;for(r in e||(e=[]),n||(n={}),t)Object.prototype.hasOwnProperty.call(t,r)&&(s=t[r],angular.isObject(s)?ut(s,e.concat(r),n,r):(i=e.length?""+e.join(Z)+Z+r:r,e.length&&r===a&&(n[""+e.join(Z)]="@:"+i),n[i]=s));return n};ut.displayName="flatObject",this.addInterpolation=function(t){return J.push(t),this},this.useMessageFormatInterpolation=function(){return this.useInterpolation("$translateMessageFormatInterpolation")},this.useInterpolation=function(t){return R=t,this},this.useSanitizeValueStrategy=function(t){return e.useStrategy(t),this},this.preferredLanguage=function(t){return t?(ct(t),this):z};var ct=function(t){return t&&(z=t),z};this.translationNotFoundIndicator=function(t){return this.translationNotFoundIndicatorLeft(t),this.translationNotFoundIndicatorRight(t),this},this.translationNotFoundIndicatorLeft=function(t){return t?(U=t,this):U},this.translationNotFoundIndicatorRight=function(t){return t?(M=t,this):M},this.fallbackLanguage=function(t){return ft(t),this};var ft=function(t){return t?(angular.isString(t)?(x=!0,T=[t]):angular.isArray(t)&&(x=!1,T=t),angular.isString(z)&&it(T,z)<0&&T.push(z),this):x?T[0]:T};this.use=function(t){if(t){if(!q[t]&&!D)throw new Error("$translateProvider couldn't find translationTable for langKey: '"+t+"'");return F=t,this}return F},this.resolveClientLocale=function(){return rt()};var gt=function(t){return t?(B=t,this):n?n+B:B};this.storageKey=gt,this.useUrlLoader=function(t,e){return this.useLoader("$translateUrlLoader",angular.extend({url:t},e))},this.useStaticFilesLoader=function(t){return this.useLoader("$translateStaticFilesLoader",t)},this.useLoader=function(t,e){return D=t,K=e||{},this},this.useLocalStorage=function(){return this.useStorage("$translateLocalStorage")},this.useCookieStorage=function(){return this.useStorage("$translateCookieStorage")},this.useStorage=function(t){return _=t,this},this.storagePrefix=function(t){return t?(n=t,this):t},this.useMissingTranslationHandlerLog=function(){return this.useMissingTranslationHandler("$translateMissingTranslationHandlerLog")},this.useMissingTranslationHandler=function(t){return V=t,this},this.usePostCompiling=function(t){return W=!!t,this},this.forceAsyncReload=function(t){return X=!!t,this},this.uniformLanguageTag=function(t){return t?angular.isString(t)&&(t={standard:t}):t={},a=t.standard,this},this.determinePreferredLanguage=function(t){var e=t&&angular.isFunction(t)?t():rt();return z=Y.length&&ot(e)||e,this},this.registerAvailableLanguageKeys=function(t,e){return t?(Y=t,e&&(c=e),this):Y},this.useLoaderCache=function(t){return!1===t?H=void 0:!0===t?H=!0:void 0===t?H="$translationCache":t&&(H=t),this},this.directivePriority=function(t){return void 0===t?nt:(nt=t,this)},this.statefulFilter=function(t){return void 0===t?at:(at=t,this)},this.postProcess=function(t){return G=t||void 0,this},this.keepContent=function(t){return et=!!t,this},this.$get=["$log","$injector","$rootScope","$q",function(t,o,s,m){var i,$,y,b=o.get(R||"$translateDefaultInterpolation"),S=!1,L={},f={},j=function(t,s,o,l,u,c){!F&&z&&(F=z);var a=u&&u!==F?ot(u)||u:F;if(u&&v(u),angular.isArray(t)){return function(t){for(var a={},e=[],n=function(e){var n=m.defer(),t=function(t){a[e]=t,n.resolve([e,t])};return j(e,s,o,l,u,c).then(t,t),n.promise},r=0,i=t.length;r<i;r++)e.push(n(t[r]));return m.all(e).then(function(){return a})}(t)}var e=m.defer();t&&(t=st.apply(t));var n=function(){var t=f[a]||f[z];if($=0,_&&!t){var e=i.get(B);if(t=f[e],T&&T.length){var n=it(T,e);$=0===n?1:0,it(T,z)<0&&T.push(z)}}return t}();if(n){var r=function(){u||(a=F),h(t,s,o,l,a,c).then(e.resolve,e.reject)};r.displayName="promiseResolved",n.finally(r).catch(angular.noop)}else h(t,s,o,l,a,c).then(e.resolve,e.reject);return e.promise},w=function(t){return U&&(t=[U,t].join(" ")),M&&(t=[t,M].join(" ")),t},l=function(t){F=t,_&&i.put(j.storageKey(),F),s.$emit("$translateChangeSuccess",{language:t}),b.setLocale(F);var e=function(t,e){L[e].setLocale(F)};e.displayName="eachInterpolatorLocaleSetter",angular.forEach(L,e),s.$emit("$translateChangeEnd",{language:t})},u=function(n){if(!n)throw"No language key specified for loading.";var a=m.defer();s.$emit("$translateLoadingStart",{language:n}),S=!0;var t=H;"string"==typeof t&&(t=o.get(t));var e=angular.extend({},K,{key:n,$http:angular.extend({},{cache:t},K.$http)}),r=function(t){var e={};s.$emit("$translateLoadingSuccess",{language:n}),angular.isArray(t)?angular.forEach(t,function(t){angular.extend(e,ut(t))}):angular.extend(e,ut(t)),S=!1,a.resolve({key:n,table:e}),s.$emit("$translateLoadingEnd",{language:n})};r.displayName="onLoaderSuccess";var i=function(t){s.$emit("$translateLoadingError",{language:t}),a.reject(t),s.$emit("$translateLoadingEnd",{language:t})};return i.displayName="onLoaderError",o.get(D)(e).then(r,i),a.promise};if(_&&(!(i=o.get(_)).get||!i.put))throw new Error("Couldn't use storage '"+_+"', missing get() or put() method!");if(J.length){var e=function(t){var e=o.get(t);e.setLocale(z||F),L[e.getInterpolationIdentifier()]=e};e.displayName="interpolationFactoryAdder",angular.forEach(J,e)}var c=function(a,r,i,s,o){var l=m.defer(),t=function(t){if(Object.prototype.hasOwnProperty.call(t,r)&&null!==t[r]){s.setLocale(a);var e=t[r];if("@:"===e.substr(0,2))c(a,e.substr(2),i,s,o).then(l.resolve,l.reject);else{var n=s.interpolate(t[r],i,"service",o,r);n=O(r,t[r],n,i,a),l.resolve(n)}s.setLocale(F)}else l.reject()};return t.displayName="fallbackTranslationResolver",function(t){var e=m.defer();if(Object.prototype.hasOwnProperty.call(q,t))e.resolve(q[t]);else if(f[t]){var n=function(t){lt(t.key,t.table),e.resolve(t.table)};n.displayName="translationTableResolver",f[t].then(n,e.reject)}else e.reject();return e.promise}(a).then(t,l.reject),l.promise},g=function(t,e,n,a,r){var i,s=q[t];if(s&&Object.prototype.hasOwnProperty.call(s,e)&&null!==s[e]){if(a.setLocale(t),i=a.interpolate(s[e],n,"filter",r,e),i=O(e,s[e],i,n,t,r),!angular.isString(i)&&angular.isFunction(i.$$unwrapTrustedValue)){var o=i.$$unwrapTrustedValue();if("@:"===o.substr(0,2))return g(t,o.substr(2),n,a,r)}else if("@:"===i.substr(0,2))return g(t,i.substr(2),n,a,r);a.setLocale(F)}return i},C=function(t,e,n,a){return V?o.get(V)(t,F,e,n,a):t},N=function(t,e,n,a,r,i){var s=m.defer();if(t<T.length){var o=T[t];c(o,e,n,a,i).then(function(t){s.resolve(t)},function(){return N(t+1,e,n,a,r,i).then(s.resolve,s.reject)})}else if(r)s.resolve(r);else{var l=C(e,n,r);V&&l?s.resolve(l):s.reject(w(e))}return s.promise},p=function(t,e,n,a,r){var i;if(t<T.length){var s=T[t];(i=g(s,e,n,a,r))||""===i||(i=p(t+1,e,n,a))}return i},h=function(t,e,n,a,r,i){var s,o,l,u,c,f=m.defer(),g=r?q[r]:q,p=n?L[n]:b;if(g&&Object.prototype.hasOwnProperty.call(g,t)&&null!==g[t]){var h=g[t];if("@:"===h.substr(0,2))j(h.substr(2),e,n,a,r,i).then(f.resolve,f.reject);else{var d=p.interpolate(h,e,"service",i,t);d=O(t,h,d,e,r),f.resolve(d)}}else{var v;V&&!S&&(v=C(t,e,a)),r&&T&&T.length?(s=t,o=e,l=p,u=a,c=i,N(0<y?y:$,s,o,l,u,c)).then(function(t){f.resolve(t)},function(t){f.reject(w(t))}):V&&!S&&v?a?f.resolve(a):f.resolve(v):a?f.resolve(a):f.reject(w(t))}return f.promise},d=function(t,e,n,a,r){var i,s=a?q[a]:q,o=b;if(L&&Object.prototype.hasOwnProperty.call(L,n)&&(o=L[n]),s&&Object.prototype.hasOwnProperty.call(s,t)&&null!==s[t]){var l=s[t];"@:"===l.substr(0,2)?i=d(l.substr(2),e,n,a,r):(i=o.interpolate(l,e,"filter",r,t),i=O(t,l,i,e,a,r))}else{var u;V&&!S&&(u=C(t,e,r)),i=a&&T&&T.length?p(($=0)<y?y:$,t,e,o,r):V&&!S&&u?u:w(t)}return i},O=function(t,e,n,a,r,i){var s=G;return s&&("string"==typeof s&&(s=o.get(s)),s)?s(t,e,n,a,r,i):n},v=function(t){q[t]||!D||f[t]||(f[t]=u(t).then(function(t){return lt(t.key,t.table),t}))};j.preferredLanguage=function(t){return t&&ct(t),z},j.cloakClassName=function(){return Q},j.nestedObjectDelimeter=function(){return Z},j.fallbackLanguage=function(t){if(null!=t){if(ft(t),D&&T&&T.length)for(var e=0,n=T.length;e<n;e++)f[T[e]]||(f[T[e]]=u(T[e]));j.use(j.use())}return x?T[0]:T},j.useFallbackLanguage=function(t){if(null!=t)if(t){var e=it(T,t);-1<e&&(y=e)}else y=0},j.proposedLanguage=function(){return I},j.storage=function(){return i},j.negotiateLocale=ot,j.use=function(e){if(!e)return F;var n=m.defer();n.promise.then(null,angular.noop),s.$emit("$translateChangeStart",{language:e});var t=ot(e);return 0<Y.length&&!t?m.reject(e):(t&&(e=t),I=e,!X&&q[e]||!D||f[e]?f[e]?f[e].then(function(t){return I===t.key&&l(t.key),n.resolve(t.key),t},function(t){return!F&&T&&0<T.length&&T[0]!==t?j.use(T[0]).then(n.resolve,n.reject):n.reject(t)}):(n.resolve(e),l(e)):(f[e]=u(e).then(function(t){return lt(t.key,t.table),n.resolve(t.key),I===e&&l(t.key),t},function(t){return s.$emit("$translateChangeError",{language:t}),n.reject(t),s.$emit("$translateChangeEnd",{language:t}),m.reject(t)}),f[e].finally(function(){var t;I===(t=e)&&(I=void 0),f[t]=void 0}).catch(angular.noop)),n.promise)},j.resolveClientLocale=function(){return rt()},j.storageKey=function(){return gt()},j.isPostCompilingEnabled=function(){return W},j.isForceAsyncReloadEnabled=function(){return X},j.isKeepContent=function(){return et},j.refresh=function(t){if(!D)throw new Error("Couldn't refresh translation table, no loader registered!");s.$emit("$translateRefreshStart",{language:t});var e=m.defer(),n={};function a(e){var t=u(e);return(f[e]=t).then(function(t){q[e]={},lt(e,t.table),n[e]=!0},angular.noop),t}if(e.promise.then(function(){for(var t in q)q.hasOwnProperty(t)&&(t in n||delete q[t]);F&&l(F)},angular.noop).finally(function(){s.$emit("$translateRefreshEnd",{language:t})}),t)q[t]?a(t).then(e.resolve,e.reject):e.reject();else{var r=T&&T.slice()||[];F&&-1===r.indexOf(F)&&r.push(F),m.all(r.map(a)).then(e.resolve,e.reject)}return e.promise},j.instant=function(t,e,n,a,r){var i=a&&a!==F?ot(a)||a:F;if(null===t||angular.isUndefined(t))return t;if(a&&v(a),angular.isArray(t)){for(var s={},o=0,l=t.length;o<l;o++)s[t[o]]=j.instant(t[o],e,n,a,r);return s}if(angular.isString(t)&&t.length<1)return t;t&&(t=st.apply(t));var u,c,f=[];z&&f.push(z),i&&f.push(i),T&&T.length&&(f=f.concat(T));for(var g=0,p=f.length;g<p;g++){var h=f[g];if(q[h]&&void 0!==q[h][t]&&(u=d(t,e,n,i,r)),void 0!==u)break}u||""===u||(U||M?u=w(t):(u=b.interpolate(t,e,"filter",r),V&&!S&&(c=C(t,e,r)),V&&!S&&c&&(u=c)));return u},j.versionInfo=function(){return"2.18.1"},j.loaderCache=function(){return H},j.directivePriority=function(){return nt},j.statefulFilter=function(){return at},j.isReady=function(){return tt};var n=m.defer();n.promise.then(function(){tt=!0}),j.onReady=function(t){var e=m.defer();return angular.isFunction(t)&&e.promise.then(t),tt?e.resolve():n.promise.then(e.resolve),e.promise},j.getAvailableLanguageKeys=function(){return 0<Y.length?Y:null},j.getTranslationTable=function(t){return(t=t||j.use())&&q[t]?angular.copy(q[t]):null};var a=s.$on("$translateReady",function(){n.resolve(),a(),a=null}),r=s.$on("$translateChangeEnd",function(){n.resolve(),r(),r=null});if(D){if(angular.equals(q,{})&&j.use()&&j.use(j.use()),T&&T.length)for(var E=function(t){return lt(t.key,t.table),s.$emit("$translateChangeEnd",{language:t.key}),t},k=0,P=T.length;k<P;k++){var A=T[k];!X&&q[A]||(f[A]=u(A).then(E))}}else s.$emit("$translateReady",{language:j.use()});return j}]}function n(s,o){"use strict";var t={};return t.setLocale=function(t){t},t.getInterpolationIdentifier=function(){return"default"},t.useSanitizeValueStrategy=function(t){return o.useStrategy(t),this},t.interpolate=function(t,e,n,a,r){var i;return e=e||{},e=o.sanitize(e,"params",a,n),angular.isNumber(t)?i=""+t:angular.isString(t)?(i=s(t)(e),i=o.sanitize(i,"text",a,n)):i="",i},t}function a(S,L,j,w,C){"use strict";var N=function(t){return angular.isString(t)?t.toLowerCase():t};return{restrict:"AE",scope:!0,priority:S.directivePriority(),compile:function(t,h){var d=h.translateValues?h.translateValues:void 0,v=h.translateInterpolation?h.translateInterpolation:void 0,m=h.translateSanitizeStrategy?h.translateSanitizeStrategy:void 0,$=t[0].outerHTML.match(/translate-value-+/i),y="^(.*)("+L.startSymbol()+".*"+L.endSymbol()+")(.*)",b="^(.*)"+L.startSymbol()+"(.*)"+L.endSymbol()+"(.*)";return function(r,l,u){r.interpolateParams={},r.preText="",r.postText="",r.translateNamespace=function t(e){if(e.translateNamespace)return e.translateNamespace;if(e.$parent)return t(e.$parent)}(r);var i={},s=function(t){if(angular.isFunction(s._unwatchOld)&&(s._unwatchOld(),s._unwatchOld=void 0),angular.equals(t,"")||!angular.isDefined(t)){var e=function(){return this.toString().replace(/^\s+|\s+$/g,"")}.apply(l.text()),n=e.match(y);if(angular.isArray(n)){r.preText=n[1],r.postText=n[3],i.translate=L(n[2])(r.$parent);var a=e.match(b);angular.isArray(a)&&a[2]&&a[2].length&&(s._unwatchOld=r.$watch(a[2],function(t){i.translate=t,c()}))}else i.translate=e||void 0}else i.translate=t;c()},t=function(e){u.$observe(e,function(t){i[e]=t,c()})};!function(t,e,n){if(e.translateValues&&angular.extend(t,w(e.translateValues)(r.$parent)),$)for(var a in n)Object.prototype.hasOwnProperty.call(e,a)&&"translateValue"===a.substr(0,14)&&"translateValues"!==a&&(t[N(a.substr(14,1))+a.substr(15)]=n[a])}(r.interpolateParams,u,h);var e=!0;for(var n in u.$observe("translate",function(t){void 0===t?s(""):""===t&&e||(i.translate=t,c()),e=!1}),u)u.hasOwnProperty(n)&&"translateAttr"===n.substr(0,13)&&13<n.length&&t(n);if(u.$observe("translateDefault",function(t){r.defaultText=t,c()}),m&&u.$observe("translateSanitizeStrategy",function(t){r.sanitizeStrategy=w(t)(r.$parent),c()}),d&&u.$observe("translateValues",function(t){t&&r.$parent.$watch(function(){angular.extend(r.interpolateParams,w(t)(r.$parent))})}),$){var a=function(n){u.$observe(n,function(t){var e=N(n.substr(14,1))+n.substr(15);r.interpolateParams[e]=t})};for(var o in u)Object.prototype.hasOwnProperty.call(u,o)&&"translateValue"===o.substr(0,14)&&"translateValues"!==o&&a(o)}var c=function(){for(var t in i)i.hasOwnProperty(t)&&void 0!==i[t]&&f(t,i[t],r,r.interpolateParams,r.defaultText,r.translateNamespace)},f=function(e,t,n,a,r,i){t?(i&&"."===t.charAt(0)&&(t=i+t),S(t,a,v,r,n.translateLanguage,n.sanitizeStrategy).then(function(t){g(t,n,!0,e)},function(t){g(t,n,!1,e)})):g(t,n,!1,e)},g=function(t,e,n,a){if(n||void 0!==e.defaultText&&(t=e.defaultText),"translate"===a){(n||!n&&!S.isKeepContent()&&void 0===u.translateKeepContent)&&l.empty().append(e.preText+t+e.postText);var r=S.isPostCompilingEnabled(),i=void 0!==h.translateCompile,s=i&&"false"!==h.translateCompile;(r&&!i||s)&&j(l.contents())(e)}else{var o=u.$attr[a];"data-"===o.substr(0,5)&&(o=o.substr(5)),o=o.substr(15),l.attr(o,t)}};(d||$||u.translateDefault)&&r.$watch("interpolateParams",c,!0),r.$on("translateLanguageChanged",c);var p=C.$on("$translateChangeSuccess",c);l.text().length?u.translate?s(u.translate):s(""):u.translate&&s(u.translate),c(),r.$on("$destroy",p)}}}}function r(u,c){"use strict";return{restrict:"A",priority:u.directivePriority(),link:function(n,a,r){var i,s,o,l={},t=function(){angular.forEach(i,function(t,e){t&&(l[e]=!0,n.translateNamespace&&"."===t.charAt(0)&&(t=n.translateNamespace+t),u(t,s,r.translateInterpolation,void 0,n.translateLanguage,o).then(function(t){a.attr(e,t)},function(t){a.attr(e,t)}))}),angular.forEach(l,function(t,e){i[e]||(a.removeAttr(e),delete l[e])})};f(n,r.translateAttr,function(t){i=t},t),f(n,r.translateValues,function(t){s=t},t),f(n,r.translateSanitizeStrategy,function(t){o=t},t),r.translateValues&&n.$watch(r.translateValues,t,!0),n.$on("translateLanguageChanged",t);var e=c.$on("$translateChangeSuccess",t);t(),n.$on("$destroy",e)}}}function f(t,e,n,a){"use strict";e&&("::"===e.substr(0,2)?e=e.substr(2):t.$watch(e,function(t){n(t),a()},!0),n(t.$eval(e)))}function i(s,o){"use strict";return{compile:function(t){var i=function(t){t.addClass(s.cloakClassName())};return i(t),function(t,e,n){var a=function(t){t.removeClass(s.cloakClassName())}.bind(this,e),r=i.bind(this,e);n.translateCloak&&n.translateCloak.length?(n.$observe("translateCloak",function(t){s(t).then(a,r)}),o.$on("$translateChangeSuccess",function(){s(n.translateCloak).then(a,r)})):s.onReady(a)}}}}function s(){"use strict";return{restrict:"A",scope:!0,compile:function(){return{pre:function(t,e,n){t.translateNamespace=function t(e){if(e.translateNamespace)return e.translateNamespace;if(e.$parent)return t(e.$parent)}(t),t.translateNamespace&&"."===n.translateNamespace.charAt(0)?t.translateNamespace+=n.translateNamespace:t.translateNamespace=n.translateNamespace}}}}}function o(){"use strict";return{restrict:"A",scope:!0,compile:function(){return function(e,t,n){n.$observe("translateLanguage",function(t){e.translateLanguage=t}),e.$watch("translateLanguage",function(){e.$broadcast("translateLanguageChanged")})}}}}function l(i,s){"use strict";var t=function(t,e,n,a){if(!angular.isObject(e)){var r=this||{__SCOPE_IS_NOT_AVAILABLE:"More info at https://github.com/angular/angular.js/commit/8863b9d04c722b278fa93c5d66ad1e578ad6eb1f"};e=i(e)(r)}return s.instant(t,e,n,a)};return s.statefulFilter()&&(t.$stateful=!0),t}function u(t){"use strict";return t("translations")}return t.$inject=["$translate"],e.$inject=["$STORAGE_KEY","$windowProvider","$translateSanitizationProvider","pascalprechtTranslateOverrider"],n.$inject=["$interpolate","$translateSanitization"],a.$inject=["$translate","$interpolate","$compile","$parse","$rootScope"],r.$inject=["$translate","$rootScope"],i.$inject=["$translate","$rootScope"],l.$inject=["$parse","$translate"],u.$inject=["$cacheFactory"],angular.module("pascalprecht.translate",["ng"]).run(t),t.displayName="runTranslate",angular.module("pascalprecht.translate").provider("$translateSanitization",function(){"use strict";var n,a,g,p=null,h=!1,d=!1;(g={sanitize:function(t,e){return"text"===e&&(t=i(t)),t},escape:function(t,e){return"text"===e&&(t=r(t)),t},sanitizeParameters:function(t,e){return"params"===e&&(t=o(t,i)),t},escapeParameters:function(t,e){return"params"===e&&(t=o(t,r)),t},sce:function(t,e,n){return"text"===e?t=s(t):"params"===e&&"filter"!==n&&(t=o(t,r)),t},sceParameters:function(t,e){return"params"===e&&(t=o(t,s)),t}}).escaped=g.escapeParameters,this.addStrategy=function(t,e){return g[t]=e,this},this.removeStrategy=function(t){return delete g[t],this},this.useStrategy=function(t){return h=!0,p=t,this},this.$get=["$injector","$log",function(u,c){var e,f={};return u.has("$sanitize")&&(n=u.get("$sanitize")),u.has("$sce")&&(a=u.get("$sce")),{useStrategy:(e=this,function(t){e.useStrategy(t)}),sanitize:function(t,e,n,a){if(p||h||d||(c.warn("pascalprecht.translate.$translateSanitization: No sanitization strategy has been configured. This can have serious security implications. See http://angular-translate.github.io/docs/#/guide/19_security for details."),d=!0),n||null===n||(n=p),!n)return t;a||(a="service");var r,i,s,o,l=angular.isArray(n)?n:[n];return r=t,i=e,s=a,o=l,angular.forEach(o,function(e){if(angular.isFunction(e))r=e(r,i,s);else if(angular.isFunction(g[e]))r=g[e](r,i,s);else{if(!angular.isString(g[e]))throw new Error("pascalprecht.translate.$translateSanitization: Unknown sanitization strategy: '"+e+"'");if(!f[g[e]])try{f[g[e]]=u.get(g[e])}catch(t){throw f[g[e]]=function(){},new Error("pascalprecht.translate.$translateSanitization: Unknown sanitization strategy: '"+e+"'")}r=f[g[e]](r,i,s)}}),r}}}];var r=function(t){var e=angular.element("<div></div>");return e.text(t),e.html()},i=function(t){if(!n)throw new Error("pascalprecht.translate.$translateSanitization: Error cannot find $sanitize service. Either include the ngSanitize module (https://docs.angularjs.org/api/ngSanitize) or use a sanitization strategy which does not depend on $sanitize, such as 'escape'.");return n(t)},s=function(t){if(!a)throw new Error("pascalprecht.translate.$translateSanitization: Error cannot find $sce service.");return a.trustAsHtml(t)},o=function(t,n,a){if(angular.isDate(t))return t;if(angular.isObject(t)){var r=angular.isArray(t)?[]:{};if(a){if(-1<a.indexOf(t))throw new Error("pascalprecht.translate.$translateSanitization: Error cannot interpolate parameter due recursive object")}else a=[];return a.push(t),angular.forEach(t,function(t,e){angular.isFunction(t)||(r[e]=o(t,n,a))}),a.splice(-1,1),r}return angular.isNumber(t)?t:!0===t||!1===t?t:angular.isUndefined(t)||null===t?t:n(t)}}),angular.module("pascalprecht.translate").constant("pascalprechtTranslateOverrider",{}).provider("$translate",e),e.displayName="displayName",angular.module("pascalprecht.translate").factory("$translateDefaultInterpolation",n),n.displayName="$translateDefaultInterpolation",angular.module("pascalprecht.translate").constant("$STORAGE_KEY","NG_TRANSLATE_LANG_KEY"),angular.module("pascalprecht.translate").directive("translate",a),a.displayName="translateDirective",angular.module("pascalprecht.translate").directive("translateAttr",r),r.displayName="translateAttrDirective",angular.module("pascalprecht.translate").directive("translateCloak",i),i.displayName="translateCloakDirective",angular.module("pascalprecht.translate").directive("translateNamespace",s),s.displayName="translateNamespaceDirective",angular.module("pascalprecht.translate").directive("translateLanguage",o),o.displayName="translateLanguageDirective",angular.module("pascalprecht.translate").filter("translate",l),l.displayName="translateFilterFactory",angular.module("pascalprecht.translate").factory("$translationCache",u),u.displayName="$translationCache","pascalprecht.translate"});
\ No newline at end of file
<div class="footer"> <div class="footer">
<hr> <hr>
<p class="text-center"> <p class="text-center">
<span class="glyphicon glyphicon-copyright-mark" aria-hidden="true"></span>携程 框架研发部 <span class="glyphicon glyphicon-copyright-mark" aria-hidden="true"></span>{{'Common.Ctrip' | translate }} {{'Common.CtripDepartment' | translate }}
<a href="https://github.com/ctripcorp/apollo" target="_blank"> <a href="https://github.com/ctripcorp/apollo" target="_blank">
<img src="../../img/github.png" style="width: 50px; height: 20px;"> <img src="../../img/github.png" style="width: 50px; height: 20px;">
</a> </a>
......
...@@ -4,13 +4,13 @@ ...@@ -4,13 +4,13 @@
<img class="navbar-brand side-bar-switch cursor-pointer" src="../../img/show_sidebar.png" <img class="navbar-brand side-bar-switch cursor-pointer" src="../../img/show_sidebar.png"
onMouseOver="this.style.background='#f1f2f7'" onMouseOver="this.style.background='#f1f2f7'"
onMouseOut="this.style.background='#fff'" onMouseOut="this.style.background='#fff'"
data-tooltip="tooltip" data-placement="bottom" title="显示导航栏" data-tooltip="tooltip" data-placement="bottom" title="{{'Common.Nav.ShowNavBar' | translate }}"
ng-show="viewMode == 2 && !showSideBar" ng-show="viewMode == 2 && !showSideBar"
ng-click="showSideBar = !showSideBar"> ng-click="showSideBar = !showSideBar">
<img class="navbar-brand side-bar-switch cursor-pointer" src="../../img/hide_sidebar.png" <img class="navbar-brand side-bar-switch cursor-pointer" src="../../img/hide_sidebar.png"
onMouseOver="this.style.background='#f1f2f7'" onMouseOver="this.style.background='#f1f2f7'"
onMouseOut="this.style.background='#fff'" onMouseOut="this.style.background='#fff'"
data-tooltip="tooltip" data-placement="bottom" title="隐藏导航栏" data-tooltip="tooltip" data-placement="bottom" title="{{'Common.Nav.HideNavBar' | translate }}"
ng-show="viewMode == 2 && showSideBar" ng-show="viewMode == 2 && showSideBar"
ng-click="showSideBar = !showSideBar"> ng-click="showSideBar = !showSideBar">
<a class="navbar-brand logo" href="/"> <a class="navbar-brand logo" href="/">
...@@ -22,20 +22,29 @@ ...@@ -22,20 +22,29 @@
<ul class="nav navbar-nav navbar-right"> <ul class="nav navbar-nav navbar-right">
<li> <li>
<a href="{{pageSetting.wikiAddress}}" target="_blank"> <a href="{{pageSetting.wikiAddress}}" target="_blank">
<span class="glyphicon glyphicon-question-sign"></span> 帮助 <span class="glyphicon glyphicon-question-sign"></span> {{'Common.Nav.Help' | translate }}
</a> </a>
</li> </li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<span class="glyphicon .glyphicon-glyphicon-font"></span>&nbsp;Language<span class="caret"></span></a>
<ul class="dropdown-menu">
<li value="en"><a href="javascript:void(0)" ng-click="changeLanguage('en')">English</a></li>
<li value="zh-cn"><a href="javascript:void(0)" ng-click="changeLanguage('zh-cn')">简体中文</a></li>
</ul>
</li>
<li class="dropdown" ng-if="hasRootPermission"> <li class="dropdown" ng-if="hasRootPermission">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<span class="glyphicon glyphicon-cog"></span>&nbsp;管理员工具 <span class="glyphicon glyphicon-cog"></span>&nbsp;{{'Common.Nav.AdminTools' | translate }}
<span class="caret"></span></a> <span class="caret"></span></a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a href="/user-manage.html" target="_blank">用户管理</a></li> <li><a href="/user-manage.html" target="_blank">{{'Common.Nav.UserManage' | translate }}</a></li>
<li><a href="/system-role-manage.html" target="_blank">系统权限管理</a></li> <li><a href="/system-role-manage.html" target="_blank">{{'Common.Nav.SystemRoleManage' | translate }}</a></li>
<li><a href="/open/manage.html" target="_blank">开放平台授权管理</a></li> <li><a href="/open/manage.html" target="_blank">{{'Common.Nav.OpenMange' | translate }}</a></li>
<li><a href="/server_config.html" target="_blank">系统参数</a></li> <li><a href="/server_config.html" target="_blank">{{'Common.Nav.SystemConfig' | translate }}</a></li>
<li><a href="/delete_app_cluster_namespace.html" target="_blank">删除应用、集群、AppNamespace</a></li> <li><a href="/delete_app_cluster_namespace.html" target="_blank">{{'Common.Nav.DeleteApp-Cluster-Namespace' | translate }}</a></li>
<li><a href="/system_info.html" target="_blank">系统信息</a></li> <li><a href="/system_info.html" target="_blank">{{'Common.Nav.SystemInfo' | translate }}</a></li>
</ul> </ul>
</li> </li>
<li class="dropdown"> <li class="dropdown">
...@@ -43,7 +52,7 @@ ...@@ -43,7 +52,7 @@
<span class="glyphicon glyphicon-user"></span>&nbsp;{{userName}} <span class="glyphicon glyphicon-user"></span>&nbsp;{{userName}}
<span class="caret"></span></a> <span class="caret"></span></a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a href="/user/logout">退出</a></li> <li><a href="/user/logout">{{'Common.Nav.Logout' | translate }}</a></li>
</ul> </ul>
</li> </li>
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal" <button type="button" class="btn btn-default" data-dismiss="modal"
ng-show="showCancelBtn" ng-click="cancel()">取消</button> ng-show="showCancelBtn" ng-click="cancel()">{{'Common.Cancel' | translate }}</button>
<button type="button" class="btn btn-danger" data-dismiss="modal" <button type="button" class="btn btn-danger" data-dismiss="modal"
ng-click="confirm()"> ng-click="confirm()">
{{confirmBtnText}} {{confirmBtnText}}
......
...@@ -5,22 +5,22 @@ ...@@ -5,22 +5,22 @@
<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"> <h4 class="modal-title">
删除Namespace {{'Component.DeleteNamespace.Title' | translate }}
</h4> </h4>
</div> </div>
<div class="modal-body form-horizontal" ng-show="toDeleteNamespace.isPublic"> <div class="modal-body form-horizontal" ng-show="toDeleteNamespace.isPublic">
删除Namespace将导致实例获取不到此Namespace的配置,确定要删除吗? {{'Component.DeleteNamespace.PublicContent' | translate }}
</div> </div>
<div class="modal-body form-horizontal" ng-show="!toDeleteNamespace.isPublic"> <div class="modal-body form-horizontal" ng-show="!toDeleteNamespace.isPublic">
删除私有Namespace将导致实例获取不到此Namespace的配置,且页面会提示缺失Namespace(除非使用管理员工具删除AppNamespace),确定要删除吗? {{'Component.DeleteNamespace.PrivateContent' | translate }}
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal"> <button type="button" class="btn btn-default" data-dismiss="modal">
取消 {{'Common.Cancel' | translate }}
</button> </button>
<button type="button" class="btn btn-danger" data-dismiss="modal" <button type="button" class="btn btn-danger" data-dismiss="modal"
ng-click="doDeleteNamespace()"> ng-click="doDeleteNamespace()">
确认 {{'Common.Ok' | translate }}
</button> </button>
</div> </div>
</div> </div>
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
<tr> <tr>
<td><input type="checkbox" ng-checked="envAllSelected" ng-click="toggleEnvsCheckedStatus()"></td> <td><input type="checkbox" ng-checked="envAllSelected" ng-click="toggleEnvsCheckedStatus()"></td>
</td> </td>
<td>环境</td> <td>{{'Common.Environment' | translate }}</td>
<td>集群</td> <td>{{'Common.Cluster' | translate }}</td>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
aria-hidden="true">&times;</span> aria-hidden="true">&times;</span>
</button> </button>
<h4 class="modal-title"> <h4 class="modal-title">
编辑灰度规则 {{'Component.GrayscalePublishRule.Title' | translate }}
</h4> </h4>
</div> </div>
<div class="modal-body form-horizontal"> <div class="modal-body form-horizontal">
...@@ -14,61 +14,61 @@ ...@@ -14,61 +14,61 @@
ng-show="branch.parentNamespace.isPublic && !branch.parentNamespace.isLinkedNamespace"> ng-show="branch.parentNamespace.isPublic && !branch.parentNamespace.isLinkedNamespace">
<label class="control-label col-md-3 text-right"> <label class="control-label col-md-3 text-right">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
灰度的AppId</label> {{'Component.GrayscalePublishRule.AppId' | translate }}
</label>
<div class="col-md-4"> <div class="col-md-4">
<input type="text" class="form-control" <input type="text" class="form-control" ng-model="branch.editingRuleItem.clientAppId"
ng-model="branch.editingRuleItem.clientAppId" ng-model-options='{ debounce: 300 }' ng-change='initSelectIps()'>
ng-model-options='{ debounce: 300 }'
ng-change='initSelectIps()'
>
</div> </div>
</div> </div>
<div class="form-group" <div class="form-group"
ng-show="branch.parentNamespace.isPublic && !branch.parentNamespace.isLinkedNamespace"> ng-show="branch.parentNamespace.isPublic && !branch.parentNamespace.isLinkedNamespace">
<label class="control-label col-md-3 text-right">灰度应用规则</label> <label
class="control-label col-md-3 text-right">{{'Component.GrayscalePublishRule.AcceptRule' | translate }}</label>
<div class="col-md-9"> <div class="col-md-9">
<label class="form-control-static radio-inline"> <label class="form-control-static radio-inline">
<input type="radio" name="ApplyToAllInstances" value="false" <input type="radio" name="ApplyToAllInstances" value="false"
ng-checked="!branch.editingRuleItem.ApplyToAllInstances" ng-checked="!branch.editingRuleItem.ApplyToAllInstances"
ng-click="branch.editingRuleItem.ApplyToAllInstances = false"> ng-click="branch.editingRuleItem.ApplyToAllInstances = false">
应用到部分实例 {{'Component.GrayscalePublishRule.AcceptPartInstance' | translate }}
</label> </label>
<label class="form-control-static radio-inline"> <label class="form-control-static radio-inline">
<input type="radio" name="ApplyToAllInstances" value="true" <input type="radio" name="ApplyToAllInstances" value="true"
ng-checked="branch.editingRuleItem.ApplyToAllInstances" ng-checked="branch.editingRuleItem.ApplyToAllInstances"
ng-click="branch.editingRuleItem.ApplyToAllInstances = true"> ng-click="branch.editingRuleItem.ApplyToAllInstances = true">
应用到所有的实例 {{'Component.GrayscalePublishRule.AcceptAllInstance' | translate }}
</label> </label>
</div> </div>
</div> </div>
<div class="form-group" ng-show="!branch.editingRuleItem.ApplyToAllInstances"> <div class="form-group" ng-show="!branch.editingRuleItem.ApplyToAllInstances">
<label class="control-label col-md-3 text-right"> <label class="control-label col-md-3 text-right">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
灰度的IP</label> {{'Component.GrayscalePublishRule.IP' | translate }}
</label>
<div class="col-md-9"> <div class="col-md-9">
<div class="form-inline"> <div class="form-inline">
<div class="form-group"> <div class="form-group">
<select class="rules-ip-selector" multiple="multiple"> <select class="rules-ip-selector" multiple="multiple">
<option ng-repeat="instance in selectIps" <option ng-repeat="instance in selectIps" ng-bind="instance.ip">
ng-bind="instance.ip">
</option> </option>
</select> </select>
<div ng-show="branch.parentNamespace.isPublic && !branch.parentNamespace.isLinkedNamespace"> <div
<small>(实例列表会根据输入的AppId自动过滤)</small> ng-show="branch.parentNamespace.isPublic && !branch.parentNamespace.isLinkedNamespace">
<small>{{'Component.GrayscalePublishRule.AppIdFilterTips' | translate }}</small>
</div> </div>
<div style="margin-top: 5px"> <div style="margin-top: 5px">
<small>没找到你想要的IP?可以<a ng-click="manual =! manual">手动输入IP</a></small> <small>{{'Component.GrayscalePublishRule.IpTips' | translate }}<a
ng-click="manual =! manual">{{'Component.GrayscalePublishRule.EnterIp' | translate }}</a></small>
</div> </div>
</div> </div>
</div> </div>
<div class="form-inline" ng-show="manual"> <div class="form-inline" ng-show="manual">
<div class="form-group"> <div class="form-group">
<textarea class="form-control" ng-model="toAddIPs" rows="3" <textarea class="form-control" ng-model="toAddIPs" rows="3"
placeholder="输入IP列表,英文逗号隔开,输入完后点击添加按钮"></textarea> placeholder="{{'Component.GrayscalePublishRule.EnterIpTips' | translate }}"></textarea>
</div> </div>
<button class="btn-default btn add-rule" <button class="btn-default btn add-rule" ng-click="batchAddIPs(branch, toAddIPs)">
ng-click="batchAddIPs(branch, toAddIPs)"> {{'Component.GrayscalePublishRule.Add' | translate }}
添加
</button> </button>
</div> </div>
</div> </div>
...@@ -77,11 +77,9 @@ ...@@ -77,11 +77,9 @@
<div class="form-group" ng-show="!branch.editingRuleItem.ApplyToAllInstances"> <div class="form-group" ng-show="!branch.editingRuleItem.ApplyToAllInstances">
<div class="col-md-offset-1 col-md-10 item-container"> <div class="col-md-offset-1 col-md-10 item-container">
<section class="btn-group item-info" <section class="btn-group item-info" ng-repeat="ip in branch.editingRuleItem.draftIpList">
ng-repeat="ip in branch.editingRuleItem.draftIpList">
<button type="button" class="btn btn-default" ng-bind="ip"></button> <button type="button" class="btn btn-default" ng-bind="ip"></button>
<button type="button" class="btn btn-default dropdown-toggle" <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"
data-toggle="dropdown"
ng-click="removeRule(branch.editingRuleItem, ip)"> ng-click="removeRule(branch.editingRuleItem, ip)">
<span class="glyphicon glyphicon-remove"></span> <span class="glyphicon glyphicon-remove"></span>
</button> </button>
...@@ -91,9 +89,10 @@ ...@@ -91,9 +89,10 @@
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button class="btn btn-default" ng-click="cancelEditItem(branch)">取消</button> <button class="btn btn-default"
ng-click="cancelEditItem(branch)">{{'Common.Cancel' | translate }}</button>
<button class="btn btn-primary" ng-disabled="completeEditBtnDisable" <button class="btn btn-primary" ng-disabled="completeEditBtnDisable"
ng-click="completeEditItem(branch)">完成 ng-click="completeEditItem(branch)">{{'Common.Ok' | translate }}
</button> </button>
</div> </div>
</div> </div>
......
<form id="itemModal" class="modal fade" valdr-type="Item" name="itemForm" <form id="itemModal" class="modal fade" valdr-type="Item" name="itemForm" ng-submit="doItem()">
ng-submit="doItem()">
<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">
...@@ -7,57 +6,58 @@ ...@@ -7,57 +6,58 @@
aria-hidden="true">&times;</span></button> aria-hidden="true">&times;</span></button>
<h4 class="modal-title"> <h4 class="modal-title">
<span ng-show="item.tableViewOperType == 'create' && !toOperationNamespace.isBranch"> <span ng-show="item.tableViewOperType == 'create' && !toOperationNamespace.isBranch">
添加配置项 <small class="text-info">(温馨提示: 可以通过文本模式批量添加配置)</small> {{'Component.ConfigItem.Title' | translate }} <small
class="text-info">{{'Component.ConfigItem.TitleTips' | translate }}</small>
</span> </span>
<span ng-show="item.tableViewOperType == 'create' && toOperationNamespace.isBranch"> 添加灰度配置项</span> <span ng-show="item.tableViewOperType == 'create' && toOperationNamespace.isBranch">
<span ng-show="item.tableViewOperType == 'update'"> 修改配置项</span> {{'Component.ConfigItem.AddGrayscaleItem' | translate }}</span>
<span ng-show="item.tableViewOperType == 'update'">
{{'Component.ConfigItem.ModifyItem' | translate }}</span>
</h4> </h4>
</div> </div>
<div class="modal-body form-horizontal"> <div class="modal-body form-horizontal">
<div class="form-group"> <div class="form-group">
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield <apollorequiredfield ng-show="item.tableViewOperType == 'create'"></apollorequiredfield>
ng-show="item.tableViewOperType == 'create'"></apollorequiredfield> {{'Component.ConfigItem.ItemKey' | translate }}
Key
</label> </label>
<div class="col-sm-10" valdr-form-group> <div class="col-sm-10" valdr-form-group>
<input type="text" name="key" class="form-control" ng-model="item.key" tabindex="1" <input type="text" name="key" class="form-control" ng-model="item.key" tabindex="1"
ng-required="true" ng-disabled="item.tableViewOperType != 'create'"/> ng-required="true" ng-disabled="item.tableViewOperType != 'create'" />
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-2 control-label">Value</label> <label class="col-sm-2 control-label">{{'Component.ConfigItem.ItemValue' | translate }}</label>
<div class="col-sm-10" valdr-form-group> <div class="col-sm-10" valdr-form-group>
<textarea id="valueEditor" name="value" class="form-control" rows="6" tabindex="2" <textarea id="valueEditor" name="value" class="form-control" rows="6" tabindex="2"
ng-required="false" ng-required="false" ng-model="item.value">
ng-model="item.value">
</textarea> </textarea>
注意: 隐藏字符(空格、换行符、制表符Tab)容易导致配置出错,如果需要检测Value中隐藏字符请点击 <a ng-click="showHiddenChars()">检测隐藏字符</a> {{'Component.ConfigItem.ItemValueTips' | translate }} <a
ng-click="showHiddenChars()">{{'Component.ConfigItem.ItemValueShowDetection' | translate }}</a>
<br> <br>
<div class="bg-info" ng-show="showHiddenCharsContext && hiddenCharCounter == 0">无隐藏字符</div> <div class="bg-info" ng-show="showHiddenCharsContext && hiddenCharCounter == 0">
<div class="bg-info" ng-bind-html="valueWithHiddenChars" ng-show="showHiddenCharsContext && hiddenCharCounter > 0"></div> {{'Component.ConfigItem.ItemValueNotHiddenChars' | translate }}</div>
<div class="bg-info" ng-bind-html="valueWithHiddenChars"
ng-show="showHiddenCharsContext && hiddenCharCounter > 0"></div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-2 control-label">Comment</label> <label class="col-sm-2 control-label">{{'Component.ConfigItem.ItemComment' | translate }}</label>
<div class="col-sm-10" valdr-form-group> <div class="col-sm-10" valdr-form-group>
<textarea class="form-control" name="comment" ng-model="item.comment" tabindex="3" <textarea class="form-control" name="comment" ng-model="item.comment" tabindex="3" rows="2">
rows="2">
</textarea> </textarea>
</div> </div>
</div> </div>
<div class="form-group" <div class="form-group" ng-show="item.tableViewOperType == 'create' && !toOperationNamespace.isBranch">
ng-show="item.tableViewOperType == 'create' && !toOperationNamespace.isBranch">
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
选择集群</label> {{'Component.ConfigItem.ChooseCluster' | translate }}
</label>
<div class="col-sm-10"> <div class="col-sm-10">
<apolloclusterselector apollo-app-id="appId" <apolloclusterselector apollo-app-id="appId" apollo-default-all-checked="false"
apollo-default-all-checked="false" apollo-default-checked-env="env" apollo-default-checked-cluster="cluster"
apollo-default-checked-env="env"
apollo-default-checked-cluster="cluster"
apollo-select="collectSelectedClusters"> apollo-select="collectSelectedClusters">
</apolloclusterselector> </apolloclusterselector>
...@@ -66,11 +66,11 @@ ...@@ -66,11 +66,11 @@
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal"> <button type="button" class="btn btn-default" data-dismiss="modal">
取消 {{'Common.Cancel' | translate }}
</button> </button>
<button type="submit" class="btn btn-primary" <button type="submit" class="btn btn-primary"
ng-disabled="itemForm.$invalid || (item.addItemBtnDisabled && item.tableViewOperType == 'create')"> ng-disabled="itemForm.$invalid || (item.addItemBtnDisabled && item.tableViewOperType == 'create')">
提交 {{'Common.Submit' | translate }}
</button> </button>
</div> </div>
</div> </div>
......
...@@ -4,33 +4,32 @@ ...@@ -4,33 +4,32 @@
<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">全量发布</h4> <h4 class="modal-title">{{'Component.MergePublish.Title' | translate }}</h4>
</div> </div>
<div class="modal-body"> <div class="modal-body">
全量发布将会把灰度版本的配置合并到主分支,并发布。 {{'Component.MergePublish.Tips' | translate }}
<br> <br>
<h5>全量发布后,您希望</h5> <h5>{{'Component.MergePublish.NextStep' | translate }}</h5>
<div class="radio"> <div class="radio">
<label ng-click="toReleaseNamespace.mergeAfterDeleteBranch = 'true'"> <label ng-click="toReleaseNamespace.mergeAfterDeleteBranch = 'true'">
<input type="radio" name="deleteBranch" <input type="radio" name="deleteBranch" ng-checked="!toReleaseNamespace.mergeAfterDeleteBranch ||
ng-checked="!toReleaseNamespace.mergeAfterDeleteBranch ||
toReleaseNamespace.mergeAfterDeleteBranch == 'true'"> toReleaseNamespace.mergeAfterDeleteBranch == 'true'">
删除灰度版本 {{'Component.MergePublish.DeleteGrayscale' | translate }}
</label> </label>
</div> </div>
<div class="radio"> <div class="radio">
<label ng-click="toReleaseNamespace.mergeAfterDeleteBranch = 'false'"> <label ng-click="toReleaseNamespace.mergeAfterDeleteBranch = 'false'">
<input type="radio" name="deleteBranch" <input type="radio" name="deleteBranch"
ng-checked="toReleaseNamespace.mergeAfterDeleteBranch == 'false'"> ng-checked="toReleaseNamespace.mergeAfterDeleteBranch == 'false'">
保留灰度版本 {{'Component.MergePublish.ReservedGrayscale' | translate }}
</label> </label>
</div> </div>
</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"
<button type="button" class="btn btn-primary" data-dismiss="modal" data-dismiss="modal">{{'Common.Cancel' | translate }}</button>
ng-click="showReleaseModal()"> <button type="button" class="btn btn-primary" data-dismiss="modal" ng-click="showReleaseModal()">
确定 {{'Common.Ok' | translate }}
</button> </button>
</div> </div>
</div> </div>
......
<section class="branch-panel-body" <section class="branch-panel-body" ng-if="namespace.initialized &&
ng-if="namespace.initialized &&
(namespace.hasBranch && namespace.displayControl.currentOperateBranch != 'master')"> (namespace.hasBranch && namespace.displayControl.currentOperateBranch != 'master')">
<!--main header--> <!--main header-->
<header class="panel-heading"> <header class="panel-heading">
...@@ -8,45 +7,44 @@ ...@@ -8,45 +7,44 @@
<div class="col-md-6 col-sm-6 header-namespace"> <div class="col-md-6 col-sm-6 header-namespace">
<b class="namespace-name" ng-bind="namespace.viewName"></b> <b class="namespace-name" ng-bind="namespace.viewName"></b>
<span class="label label-warning no-radius namespace-label" <span class="label label-warning no-radius namespace-label"
ng-show="namespace.branch.itemModifiedCnt > 0">有修改 ng-show="namespace.branch.itemModifiedCnt > 0">{{'Component.Namespace.Branch.IsChanged' | translate }}
<span class="badge label badge-white namespace-label" <span class="badge label badge-white namespace-label"
ng-bind="namespace.branch.itemModifiedCnt"></span> ng-bind="namespace.branch.itemModifiedCnt"></span>
</span> </span>
<span class="label label-primary no-radius namespace-label" <span class="label label-primary no-radius namespace-label"
ng-show="namespace.branch.lockOwner">当前修改者: ng-show="namespace.branch.lockOwner">{{'Component.Namespace.Branch.ChangeUser' | translate }}:
<span ng-bind="namespace.branch.lockOwner"></span> <span ng-bind="namespace.branch.lockOwner"></span>
</span> </span>
</div> </div>
<div class="col-md-6 col-sm-6 text-right header-buttons"> <div class="col-md-6 col-sm-6 text-right header-buttons">
<a type="button" class="btn btn-success btn-sm" <a type="button" class="btn btn-success btn-sm" data-tooltip="tooltip" data-placement="bottom"
data-tooltip="tooltip" data-placement="bottom" title="继续灰度发布" title="{{'Component.Namespace.Branch.ContinueGrayscalePublish' | translate }}"
ng-show="(namespace.hasReleasePermission || namespace.hasModifyPermission)" ng-show="(namespace.hasReleasePermission || namespace.hasModifyPermission)"
ng-click="publish(namespace.branch)"> ng-click="publish(namespace.branch)">
灰度发布 {{'Component.Namespace.Branch.GrayscalePublish' | translate }}
</a> </a>
<a type="button" class="btn btn-primary btn-sm" <a type="button" class="btn btn-primary btn-sm" data-tooltip="tooltip" data-placement="bottom"
data-tooltip="tooltip" data-placement="bottom" title="合并到主版本并发布主版本配置" title="{{'Component.Namespace.Branch.MergeToMasterAndPublish' | translate }}"
ng-show="(namespace.hasReleasePermission || namespace.hasModifyPermission)" ng-show="(namespace.hasReleasePermission || namespace.hasModifyPermission)"
ng-click="mergeAndPublish(namespace.branch)"> ng-click="mergeAndPublish(namespace.branch)">
全量发布 {{'Component.Namespace.Branch.AllPublish' | translate }}
</a> </a>
<a type="button" class="btn btn-warning btn-sm" <a type="button" class="btn btn-warning btn-sm" data-tooltip="tooltip" data-placement="bottom"
data-tooltip="tooltip" data-placement="bottom" title="废弃灰度版本" title="{{'Component.Namespace.Branch.DiscardGrayscaleVesion' | translate }}" ng-show="(namespace.hasReleasePermission
ng-show="(namespace.hasReleasePermission
|| (!namespace.branch.latestRelease && namespace.hasModifyPermission))" || (!namespace.branch.latestRelease && namespace.hasModifyPermission))"
ng-click="preDeleteBranch(namespace.branch)"> ng-click="preDeleteBranch(namespace.branch)">
放弃灰度 {{'Component.Namespace.Branch.DiscardGrayscale' | translate }}
</a> </a>
</div> </div>
</div> </div>
</header> </header>
<div id="BODY{{namespace.branch.id}}" ng-class="{'collapse in': showNamespaceBody, 'collapse' : !showNamespaceBody}"> <div id="BODY{{namespace.branch.id}}"
<div class="J_namespace-release-tip well well-sm no-radius text-center" ng-class="{'collapse in': showNamespaceBody, 'collapse' : !showNamespaceBody}">
ng-show="namespace.isConfigHidden"> <div class="J_namespace-release-tip well well-sm no-radius text-center" ng-show="namespace.isConfigHidden">
<span style="color: red">您不是该项目的管理员,也没有该Namespace的编辑或发布权限,无法查看配置信息。</span> <span style="color: red">{{'Component.Namespace.Branch.NoPermissionTips' | translate }}</span>
</div> </div>
<!--second header--> <!--second header-->
...@@ -58,13 +56,13 @@ ...@@ -58,13 +56,13 @@
ng-show="namespace.isPropertiesFormat"> ng-show="namespace.isPropertiesFormat">
<a ng-class="{node_active:namespace.branch.viewType == 'table'}"> <a ng-class="{node_active:namespace.branch.viewType == 'table'}">
<img src="img/table.png"> <img src="img/table.png">
配置 {{'Component.Namespace.Branch.Tab.Configuration' | translate }}
</a> </a>
</li> </li>
<li role="presentation" ng-click="switchView(namespace.branch, 'rule')"> <li role="presentation" ng-click="switchView(namespace.branch, 'rule')">
<a ng-class="{node_active:namespace.branch.viewType == 'rule'}"> <a ng-class="{node_active:namespace.branch.viewType == 'rule'}">
<img src="img/rule.png"> <img src="img/rule.png">
灰度规则 {{'Component.Namespace.Branch.Tab.GrayscaleRule' | translate }}
<span class="badge badge-grey" <span class="badge badge-grey"
ng-bind="namespace.branch.grayIps.length + namespace.branch.grayApps.length"></span> ng-bind="namespace.branch.grayIps.length + namespace.branch.grayApps.length"></span>
</a> </a>
...@@ -72,7 +70,7 @@ ...@@ -72,7 +70,7 @@
<li role="presentation" ng-click="switchView(namespace.branch, 'instance')"> <li role="presentation" ng-click="switchView(namespace.branch, 'instance')">
<a ng-class="{node_active:namespace.branch.viewType == 'instance'}"> <a ng-class="{node_active:namespace.branch.viewType == 'instance'}">
<img src="img/machine.png"> <img src="img/machine.png">
灰度实例列表 {{'Component.Namespace.Branch.Tab.GrayscaleInstance' | translate }}
<span class="badge badge-grey" <span class="badge badge-grey"
ng-bind="namespace.branch.latestReleaseInstances.total"></span> ng-bind="namespace.branch.latestReleaseInstances.total"></span>
</a> </a>
...@@ -80,7 +78,7 @@ ...@@ -80,7 +78,7 @@
<li role="presentation" ng-click="switchView(namespace.branch, 'history')"> <li role="presentation" ng-click="switchView(namespace.branch, 'history')">
<a ng-class="{node_active:namespace.branch.viewType == 'history'}"> <a ng-class="{node_active:namespace.branch.viewType == 'history'}">
<img src="img/change.png"> <img src="img/change.png">
更改历史 {{'Component.Namespace.Branch.Tab.ChangeHistory' | translate }}
</a> </a>
</li> </li>
</ul> </ul>
...@@ -94,46 +92,45 @@ ...@@ -94,46 +92,45 @@
<div class="panel panel-default" ng-if="namespace.hasBranch"> <div class="panel panel-default" ng-if="namespace.hasBranch">
<div class="panel-heading"> <div class="panel-heading">
灰度的配置 {{'Component.Namespace.Branch.Body.Item' | translate }}
<button type="button" class="btn btn-primary btn-sm pull-right" style="margin-top: -4px;" <button type="button" class="btn btn-primary btn-sm pull-right" style="margin-top: -4px;"
ng-show="namespace.hasModifyPermission" ng-show="namespace.hasModifyPermission" ng-click="createItem(namespace.branch)">
ng-click="createItem(namespace.branch)">
<img src="img/plus.png"> <img src="img/plus.png">
新增灰度配置 {{'Component.Namespace.Branch.Body.AddedItem' | translate }}
</button> </button>
</div> </div>
<table class="table table-bordered table-striped table-hover"> <table class="table table-bordered table-striped table-hover">
<thead> <thead>
<tr> <tr>
<th>发布状态</th> <th>{{'Component.Namespace.Branch.Body.PublishState' | translate }}</th>
<th class="hover" title="排序" <th class="hover" title="{{'Component.Namespace.Branch.Body.ItemSort' | translate }}"
ng-click="col='item.key';desc=!desc;"> ng-click="col='item.key';desc=!desc;">
Key&nbsp; {{'Component.Namespace.Branch.Body.ItemKey' | translate }}&nbsp;
<span class="glyphicon glyphicon-sort"></span> <span class="glyphicon glyphicon-sort"></span>
</th> </th>
<th> <th>
主版本的值 {{'Component.Namespace.Branch.Body.ItemMasterValue' | translate }}
</th> </th>
<th> <th>
灰度的值 {{'Component.Namespace.Branch.Body.ItemGrayscaleValue' | translate }}
</th> </th>
<th> <th>
备注 {{'Component.Namespace.Branch.Body.ItemComment' | translate }}
</th> </th>
<th class="hover" title="排序" <th class="hover" title="{{'Component.Namespace.Branch.Body.ItemSort' | translate }}"
ng-click="col='item.dataChangeLastModifiedBy';desc=!desc;"> ng-click="col='item.dataChangeLastModifiedBy';desc=!desc;">
最后修改人 {{'Component.Namespace.Branch.Body.ItemLastModify' | translate }}
<span class="glyphicon glyphicon-sort"></span> <span class="glyphicon glyphicon-sort"></span>
</th> </th>
<th class="hover" title="排序" <th class="hover" title="{{'Component.Namespace.Branch.Body.ItemSort' | translate }}"
ng-click="col='item.dataChangeLastModifiedTime';desc=!desc;"> ng-click="col='item.dataChangeLastModifiedTime';desc=!desc;">
最后修改时间 {{'Component.Namespace.Branch.Body.ItemLastModifyTime' | translate }}
<span class="glyphicon glyphicon-sort"></span> <span class="glyphicon glyphicon-sort"></span>
</th> </th>
<th> <th>
操作 {{'Component.Namespace.Branch.Body.ItemOperator' | translate }}
</th> </th>
</tr> </tr>
</thead> </thead>
...@@ -142,31 +139,41 @@ ...@@ -142,31 +139,41 @@
<tr ng-repeat="config in namespace.branch.branchItems |orderBy:col:desc" <tr ng-repeat="config in namespace.branch.branchItems |orderBy:col:desc"
ng-if="config.item.key"> ng-if="config.item.key">
<td width="7%" class="text-center"> <td width="7%" class="text-center">
<span class="label label-warning no-radius cursor-pointer" <span class="label label-warning no-radius cursor-pointer" data-tooltip="tooltip"
data-tooltip="tooltip" data-placement="bottom" title="点击查看已发布的值" data-placement="bottom"
title="{{'Component.Namespace.Branch.Body.ClickToSeeItemValue' | translate }}"
ng-if="config.isModified || config.isDeleted" ng-if="config.isModified || config.isDeleted"
ng-click="showText(config.oldValue)">未发布</span> ng-click="showText(config.oldValue)">{{'Component.Namespace.Branch.Body.ItemNoPublish' | translate }}</span>
<span class="label label-default-light no-radius" <span class="label label-default-light no-radius" data-tooltip="tooltip"
data-tooltip="tooltip" data-placement="bottom" title="已生效的配置" data-placement="bottom"
ng-if="!config.isModified">已发布</span> title="{{'Component.Namespace.Branch.Body.ItemEffective' | translate }}"
</td> ng-if="!config.isModified">{{'Component.Namespace.Branch.Body.ItemPublished' | translate }}</span>
<td width="15%" class="cursor-pointer" title="点击查看" ng-click="showText(config.item.key)"> </td>
<td width="15%" class="cursor-pointer"
title="{{'Component.Namespace.Branch.Body.ClickToSee' | translate }}"
ng-click="showText(config.item.key)">
<span ng-bind="config.item.key | limitTo: 250"></span> <span ng-bind="config.item.key | limitTo: 250"></span>
<span ng-bind="config.item.key.length > 250 ? '...' :''"></span> <span ng-bind="config.item.key.length > 250 ? '...' :''"></span>
<span class="label label-danger" ng-if="config.isDeleted" <span class="label label-danger" ng-if="config.isDeleted" data-tooltip="tooltip"
data-tooltip="tooltip" data-placement="bottom" title="删除的配置"></span> data-placement="bottom"
title="{{'Component.Namespace.Branch.Body.DeletedItem' | translate }}">{{'Component.Namespace.Branch.Body.Delete' | translate }}</span>
<span class="label label-info" ng-if="!config.isDeleted && config.masterItemExists" <span class="label label-info" ng-if="!config.isDeleted && config.masterItemExists"
data-tooltip="tooltip" data-placement="bottom" title="修改主版本的配置"></span> data-tooltip="tooltip" data-placement="bottom"
title="{{'Component.Namespace.Branch.Body.ChangedFormMaster' | translate }}">{{'Component.Namespace.Branch.Body.Modify' | translate }}</span>
<span class="label label-success" <span class="label label-success"
ng-if="!config.isDeleted && !config.masterItemExists" ng-if="!config.isDeleted && !config.masterItemExists" data-tooltip="tooltip"
data-tooltip="tooltip" data-placement="bottom" title="灰度版本特有的配置"></span> data-placement="bottom"
title="{{'Component.Namespace.Branch.Body.AddedByGrayscale' | translate }}">{{'Component.Namespace.Branch.Body.Added' | translate }}</span>
</td> </td>
<td width="20%" class="cursor-pointer" title="点击查看" <td width="20%" class="cursor-pointer"
title="{{'Component.Namespace.Branch.Body.ClickToSee' | translate }}"
ng-click="showText(config.masterReleaseValue)"> ng-click="showText(config.masterReleaseValue)">
<span ng-bind="config.masterReleaseValue | limitTo: 250"></span> <span ng-bind="config.masterReleaseValue | limitTo: 250"></span>
<span ng-bind="config.item.value.length > 250 ? '...': ''"></span> <span ng-bind="config.item.value.length > 250 ? '...': ''"></span>
</td> </td>
<td width="20%" class="cursor-pointer" title="点击查看" ng-click="showText(config.item.value)"> <td width="20%" class="cursor-pointer"
title="{{'Component.Namespace.Branch.Body.ClickToSee' | translate }}"
ng-click="showText(config.item.value)">
<span ng-bind="config.item.value | limitTo: 250"></span> <span ng-bind="config.item.value | limitTo: 250"></span>
<span ng-bind="config.item.value.length > 250 ? '...': ''"></span> <span ng-bind="config.item.value.length > 250 ? '...': ''"></span>
</td> </td>
...@@ -181,13 +188,13 @@ ...@@ -181,13 +188,13 @@
</td> </td>
<td width="9%" class="text-center"> <td width="9%" class="text-center">
<img src="img/edit.png" <img src="img/edit.png" data-tooltip="tooltip" data-placement="bottom"
data-tooltip="tooltip" data-placement="bottom" title="修改" title="{{'Component.Namespace.Branch.Body.Op.Modify' | translate }}"
ng-if="!config.isDeleted" ng-if="!config.isDeleted" ng-click="editItem(namespace.branch, config.item)"
ng-click="editItem(namespace.branch, config.item)"
ng-show="namespace.hasModifyPermission"> ng-show="namespace.hasModifyPermission">
<img style="margin-left: 5px;" src="img/cancel.png" <img style="margin-left: 5px;" src="img/cancel.png" data-tooltip="tooltip"
data-tooltip="tooltip" data-placement="bottom" title="删除" data-placement="bottom"
title="{{'Component.Namespace.Branch.Body.Op.Delete' | translate }}"
ng-if="!config.isDeleted" ng-if="!config.isDeleted"
ng-click="preDeleteItem(namespace.branch, config.item)" ng-click="preDeleteItem(namespace.branch, config.item)"
ng-show="namespace.hasModifyPermission"> ng-show="namespace.hasModifyPermission">
...@@ -201,37 +208,37 @@ ...@@ -201,37 +208,37 @@
<div class="panel panel-default" <div class="panel panel-default"
ng-if="namespace.branch.masterItems && namespace.branch.masterItems.length > 0"> ng-if="namespace.branch.masterItems && namespace.branch.masterItems.length > 0">
<div class="panel-heading"> <div class="panel-heading">
主版本的配置 {{'Component.Namespace.MasterBranch.Body.Title' | translate }}
</div> </div>
<table class="table table-bordered table-striped table-hover"> <table class="table table-bordered table-striped table-hover">
<thead> <thead>
<tr> <tr>
<th>发布状态</th> <th>{{'Component.Namespace.MasterBranch.Body.PublishState' | translate }}</th>
<th class="hover" title="排序" <th class="hover" title="{{'Component.Namespace.Branch.Body.ItemSort' | translate }}"
ng-click="col='item.key';desc=!desc;"> ng-click="col='item.key';desc=!desc;">
Key&nbsp; {{'Component.Namespace.MasterBranch.Body.ItemKey' | translate }}&nbsp;
<span class="glyphicon glyphicon-sort"></span> <span class="glyphicon glyphicon-sort"></span>
</th> </th>
<th> <th>
Value {{'Component.Namespace.MasterBranch.Body.ItemValue' | translate }}
</th> </th>
<th> <th>
备注 {{'Component.Namespace.MasterBranch.Body.ItemComment' | translate }}
</th> </th>
<th class="hover" title="排序" <th class="hover" title="{{'Component.Namespace.Branch.Body.ItemSort' | translate }}"
ng-click="col='item.dataChangeLastModifiedBy';desc=!desc;"> ng-click="col='item.dataChangeLastModifiedBy';desc=!desc;">
最后修改人 {{'Component.Namespace.MasterBranch.Body.ItemLastModify' | translate }}
<span class="glyphicon glyphicon-sort"></span> <span class="glyphicon glyphicon-sort"></span>
</th> </th>
<th class="hover" title="排序" <th class="hover" title="{{'Component.Namespace.Branch.Body.ItemSort' | translate }}"
ng-click="col='item.dataChangeLastModifiedTime';desc=!desc;"> ng-click="col='item.dataChangeLastModifiedTime';desc=!desc;">
最后修改时间 {{'Component.Namespace.MasterBranch.Body.ItemLastModifyTime' | translate }}
<span class="glyphicon glyphicon-sort"></span> <span class="glyphicon glyphicon-sort"></span>
</th> </th>
<th> <th>
操作 {{'Component.Namespace.MasterBranch.Body.ItemOperator' | translate }}
</th> </th>
</tr> </tr>
</thead> </thead>
...@@ -240,26 +247,35 @@ ...@@ -240,26 +247,35 @@
<tr ng-repeat="config in namespace.branch.masterItems |orderBy:col:desc" <tr ng-repeat="config in namespace.branch.masterItems |orderBy:col:desc"
ng-if="config.item.key"> ng-if="config.item.key">
<td width="8%" class="text-center"> <td width="8%" class="text-center">
<span class="label label-warning no-radius cursor-pointer" <span class="label label-warning no-radius cursor-pointer" data-tooltip="tooltip"
data-tooltip="tooltip" data-placement="bottom" title="点击查看已发布的值" data-placement="bottom"
title="{{'Component.Namespace.MasterBranch.Body.ClickToSeeItemValue' | translate }}"
ng-if="config.isModified || config.isDeleted" ng-if="config.isModified || config.isDeleted"
ng-click="showText(config.oldValue)">未发布</span> ng-click="showText(config.oldValue)">{{'Component.Namespace.MasterBranch.Body.ItemNoPublish' | translate }}</span>
<span class="label label-default-light no-radius" <span class="label label-default-light no-radius" data-tooltip="tooltip"
data-tooltip="tooltip" data-placement="bottom" title="已生效的配置" data-placement="bottom"
ng-if="!config.isModified">已发布</span> title="{{'Component.Namespace.MasterBranch.Body.ItemEffective' | translate }}"
</td> ng-if="!config.isModified">{{'Component.Namespace.MasterBranch.Body.ItemPublished' | translate }}</span>
<td width="15%" class="cursor-pointer" title="点击查看" ng-click="showText(config.item.key)"> </td>
<td width="15%" class="cursor-pointer"
title="{{'Component.Namespace.Branch.Body.ClickToSee' | translate }}"
ng-click="showText(config.item.key)">
<span ng-bind="config.item.key | limitTo: 250"></span> <span ng-bind="config.item.key | limitTo: 250"></span>
<span ng-bind="config.item.key.length > 250 ? '...' :''"></span> <span ng-bind="config.item.key.length > 250 ? '...' :''"></span>
<span class="label label-success" ng-if="config.isModified && !config.oldValue" <span class="label label-success" ng-if="config.isModified && !config.oldValue"
data-tooltip="tooltip" data-placement="bottom" title="新增的配置"></span> data-tooltip="tooltip" data-placement="bottom"
title="{{'Component.Namespace.MasterBranch.Body.AddedItem' | translate }}">{{'Component.Namespace.Branch.Body.Added' | translate }}</span>
<span class="label label-info" <span class="label label-info"
ng-if="config.isModified && config.oldValue && !config.isDeleted" ng-if="config.isModified && config.oldValue && !config.isDeleted"
data-tooltip="tooltip" data-placement="bottom" title="修改的配置"></span> data-tooltip="tooltip" data-placement="bottom"
<span class="label label-danger" ng-if="config.isDeleted" title="{{'Component.Namespace.Branch.Body.ModifedItem' | translate }}">{{'Component.Namespace.Branch.Body.Modify' | translate }}</span>
data-tooltip="tooltip" data-placement="bottom" title="删除的配置"></span> <span class="label label-danger" ng-if="config.isDeleted" data-tooltip="tooltip"
</td> data-placement="bottom"
<td width="35%" class="cursor-pointer" title="点击查看" ng-click="showText(config.item.value)"> title="{{'Component.Namespace.Branch.Body.DeletedItem' | translate }}">{{'Component.Namespace.Branch.Body.Delete' | translate }}</span>
</td>
<td width="35%" class="cursor-pointer"
title="{{'Component.Namespace.Branch.Body.ClickToSee' | translate }}"
ng-click="showText(config.item.value)">
<span ng-bind="config.item.value | limitTo: 250"></span> <span ng-bind="config.item.value | limitTo: 250"></span>
<span ng-bind="config.item.value.length > 250 ? '...': ''"></span> <span ng-bind="config.item.value.length > 250 ? '...': ''"></span>
</td> </td>
...@@ -274,10 +290,9 @@ ...@@ -274,10 +290,9 @@
</td> </td>
<td width="5%" class="text-center"> <td width="5%" class="text-center">
<img src="img/gray.png" <img src="img/gray.png" data-tooltip="tooltip" data-placement="bottom"
data-tooltip="tooltip" data-placement="bottom" title="对此配置灰度" title="{{'Component.Namespace.MasterBranch.Body.ModifyItem' | translate }}"
ng-if="!config.isDeleted" ng-if="!config.isDeleted" ng-click="editItem(namespace.branch, config.item)"
ng-click="editItem(namespace.branch, config.item)"
ng-show="namespace.hasModifyPermission"> ng-show="namespace.hasModifyPermission">
</td> </td>
...@@ -292,15 +307,15 @@ ...@@ -292,15 +307,15 @@
<div class="alert alert-warning no-radius" <div class="alert alert-warning no-radius"
ng-show="!namespace.hasModifyPermission && !namespace.hasReleasePermission"> ng-show="!namespace.hasModifyPermission && !namespace.hasReleasePermission">
<strong>Tips:</strong> <strong>Tips:</strong>
您没有权限编辑灰度规则, 具有namespace修改权或者发布权的人员才可以编辑灰度规则. 如需要编辑灰度规则,请找项目管理员申请权限. {{'Component.Namespace.Branch.GrayScaleRule.NoPermissonTips' | translate }}
</div> </div>
<table class="table table-bordered table-hover"> <table class="table table-bordered table-hover">
<thead> <thead>
<tr> <tr>
<th>灰度的AppId</th> <th>{{'Component.Namespace.Branch.GrayScaleRule.AppId' | translate }}</th>
<th>灰度的IP列表</th> <th>{{'Component.Namespace.Branch.GrayScaleRule.IpList' | translate }}</th>
<th>操作</th> <th>{{'Component.Namespace.Branch.GrayScaleRule.Operator' | translate }}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
...@@ -308,14 +323,17 @@ ...@@ -308,14 +323,17 @@
<td width="20%" ng-bind="ruleItem.clientAppId"></td> <td width="20%" ng-bind="ruleItem.clientAppId"></td>
<td width="70%" ng-show="!ruleItem.ApplyToAllInstances" <td width="70%" ng-show="!ruleItem.ApplyToAllInstances"
ng-bind="ruleItem.clientIpList.join(', ')"></td> ng-bind="ruleItem.clientIpList.join(', ')"></td>
<td width="70%" ng-show="ruleItem.ApplyToAllInstances">ALL</td> <td width="70%" ng-show="ruleItem.ApplyToAllInstances">
{{'Component.Namespace.Branch.GrayScaleRule.ApplyToAllInstances' | translate }}</td>
<td class="text-center" width="10%"> <td class="text-center" width="10%">
<img src="img/edit.png" class="i-20 hover" <img src="img/edit.png" class="i-20 hover" data-tooltip="tooltip"
data-tooltip="tooltip" data-placement="bottom" title="修改" data-placement="bottom"
title="{{'Component.Namespace.Branch.GrayScaleRule.Modify' | translate }}"
ng-show="namespace.hasModifyPermission || namespace.hasReleasePermission" ng-show="namespace.hasModifyPermission || namespace.hasReleasePermission"
ng-click="editRuleItem(namespace.branch, ruleItem)"> ng-click="editRuleItem(namespace.branch, ruleItem)">
<img src="img/cancel.png" class="i-20 hover" style="margin-left: 5px;" <img src="img/cancel.png" class="i-20 hover" style="margin-left: 5px;"
data-tooltip="tooltip" data-placement="bottom" title="删除" data-tooltip="tooltip" data-placement="bottom"
title="{{'Component.Namespace.Branch.GrayScaleRule.Delete' | translate }}"
ng-show="namespace.hasModifyPermission || namespace.hasReleasePermission" ng-show="namespace.hasModifyPermission || namespace.hasReleasePermission"
ng-click="deleteRuleItem(namespace.branch, ruleItem)"> ng-click="deleteRuleItem(namespace.branch, ruleItem)">
</td> </td>
...@@ -323,14 +341,13 @@ ...@@ -323,14 +341,13 @@
</tbody> </tbody>
</table> </table>
<button class="btn btn-primary" <button class="btn btn-primary" ng-if="namespace.hasModifyPermission || namespace.hasReleasePermission"
ng-if="namespace.hasModifyPermission || namespace.hasReleasePermission"
ng-show="(namespace.isPublic && !namespace.isLinkedNamespace) || ng-show="(namespace.isPublic && !namespace.isLinkedNamespace) ||
((!namespace.isPublic || namespace.isLinkedNamespace) ((!namespace.isPublic || namespace.isLinkedNamespace)
&& (!namespace.branch.rules && (!namespace.branch.rules
|| !namespace.branch.rules.ruleItems || !namespace.branch.rules.ruleItems
|| !namespace.branch.rules.ruleItems.length))" || !namespace.branch.rules.ruleItems.length))"
ng-click="addRuleItem(namespace.branch)">新增规则 ng-click="addRuleItem(namespace.branch)">{{'Component.Namespace.Branch.GrayScaleRule.AddNewRule' | translate }}
</button> </button>
...@@ -340,16 +357,17 @@ ...@@ -340,16 +357,17 @@
<!--instances --> <!--instances -->
<div class="panel panel-default" ng-show="namespace.branch.viewType == 'instance'"> <div class="panel panel-default" ng-show="namespace.branch.viewType == 'instance'">
<div class="panel-heading text-right"> <div class="panel-heading text-right">
<button class="btn btn-default btn-sm" <button class="btn btn-default btn-sm" data-tooltip="tooltip" data-placement="bottom"
data-tooltip="tooltip" data-placement="bottom" title="刷新列表" title="{{'Component.Namespace.Branch.Instance.RefreshList' | translate }}"
ng-click="refreshInstancesInfo(namespace.branch)"> ng-click="refreshInstancesInfo(namespace.branch)">
<img src="../../img/refresh.png"/> <img src="../../img/refresh.png" />
</button> </button>
</div> </div>
<div class="panel-body"> <div class="panel-body">
<div class="panel-default" ng-if="namespace.branch.latestReleaseInstances.total > 0"> <div class="panel-default" ng-if="namespace.branch.latestReleaseInstances.total > 0">
<div class="panel-heading"> <div class="panel-heading">
<a target="_blank" data-tooltip="tooltip" data-placement="bottom" title="查看配置" <a target="_blank" data-tooltip="tooltip" data-placement="bottom"
title="{{'Component.Namespace.Branch.Instance.ItemToSee' | translate }}"
href="/config/history.html?#/appid={{appId}}&env={{env}}&clusterName={{namespace.baseInfo.clusterName}}&namespaceName={{namespace.baseInfo.namespaceName}}&releaseId={{namespace.branch.latestRelease.id}}"> href="/config/history.html?#/appid={{appId}}&env={{env}}&clusterName={{namespace.baseInfo.clusterName}}&namespaceName={{namespace.baseInfo.namespaceName}}&releaseId={{namespace.branch.latestRelease.id}}">
{{namespace.branch.latestRelease.name}} {{namespace.branch.latestRelease.name}}
</a> </a>
...@@ -357,11 +375,11 @@ ...@@ -357,11 +375,11 @@
<table class="table table-bordered table-striped"> <table class="table table-bordered table-striped">
<thead> <thead>
<tr> <tr>
<td>App ID</td> <td>{{'Component.Namespace.Branch.Instance.InstanceAppId' | translate }}</td>
<td>Cluster Name</td> <td>{{'Component.Namespace.Branch.Instance.InstanceClusterName' | translate }}</td>
<td>Data Center</td> <td>{{'Component.Namespace.Branch.Instance.InstanceDataCenter' | translate }}</td>
<td>IP</td> <td>{{'Component.Namespace.Branch.Instance.InstanceIp' | translate }}</td>
<td>配置获取时间</td> <td>{{'Component.Namespace.Branch.Instance.InstanceGetItemTime' | translate }}</td>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
...@@ -378,12 +396,13 @@ ...@@ -378,12 +396,13 @@
</table> </table>
<div class="row text-center" <div class="row text-center"
ng-show="namespace.branch.latestReleaseInstances.content.length < namespace.branch.latestReleaseInstances.total"> ng-show="namespace.branch.latestReleaseInstances.content.length < namespace.branch.latestReleaseInstances.total">
<button class="btn btn-default" ng-click="loadInstanceInfo(namespace.branch)">加载更多</button> <button class="btn btn-default"
ng-click="loadInstanceInfo(namespace.branch)">{{'Component.Namespace.Branch.Instance.LoadingMore' | translate }}</button>
</div> </div>
</div> </div>
<div class="text-center" ng-if="namespace.branch.latestReleaseInstances.total == 0"> <div class="text-center" ng-if="namespace.branch.latestReleaseInstances.total == 0">
无实例信息 {{'Component.Namespace.Branch.Instance.NoInstance' | translate }}
</div> </div>
</div> </div>
...@@ -391,13 +410,12 @@ ...@@ -391,13 +410,12 @@
</div> </div>
<!--history view--> <!--history view-->
<div class="J_historyview history-view" ng-show="namespace.branch.viewType == 'history'"> <div class="J_historyview history-view" ng-show="namespace.branch.viewType == 'history'">
<div class="media" <div class="media" ng-show="namespace.branch.commits && namespace.branch.commits.length"
ng-show="namespace.branch.commits && namespace.branch.commits.length"
ng-repeat="commits in namespace.branch.commits"> ng-repeat="commits in namespace.branch.commits">
<div class="media-body"> <div class="media-body">
<div class="row"> <div class="row">
<div class="col-md-6 col-sm-6 "><h3 class="media-heading" <div class="col-md-6 col-sm-6 ">
ng-bind="commits.dataChangeCreatedBy"></h3> <h3 class="media-heading" ng-bind="commits.dataChangeCreatedBy"></h3>
</div> </div>
<div class="col-md-6 col-sm-6 text-right"> <div class="col-md-6 col-sm-6 text-right">
<h5 class="media-heading" <h5 class="media-heading"
...@@ -408,24 +426,23 @@ ...@@ -408,24 +426,23 @@
<!--properties format--> <!--properties format-->
<table class="table table-bordered table-striped text-center table-hover" <table class="table table-bordered table-striped text-center table-hover"
style="margin-top: 5px;" style="margin-top: 5px;" ng-if="namespace.isPropertiesFormat">
ng-if="namespace.isPropertiesFormat">
<thead> <thead>
<tr> <tr>
<th> <th>
Type {{'Component.Namespace.Branch.History.ItemType' | translate }}
</th> </th>
<th> <th>
Key {{'Component.Namespace.Branch.History.ItemKey' | translate }}
</th> </th>
<th> <th>
Old Value {{'Component.Namespace.Branch.History.ItemOldValue' | translate }}
</th> </th>
<th> <th>
New Value {{'Component.Namespace.Branch.History.ItemNewValue' | translate }}
</th> </th>
<th> <th>
Comment {{'Component.Namespace.Branch.History.ItemComment' | translate }}
</th> </th>
</tr> </tr>
</thead> </thead>
...@@ -434,7 +451,7 @@ ...@@ -434,7 +451,7 @@
<!--兼容老数据,不显示item类型为空行和注释的item--> <!--兼容老数据,不显示item类型为空行和注释的item-->
<tr ng-repeat="item in commits.changeSets.createItems" ng-show="item.key"> <tr ng-repeat="item in commits.changeSets.createItems" ng-show="item.key">
<td width="2%"> <td width="2%">
新增 {{'Component.Namespace.Branch.History.NewAdded' | translate }}
</td> </td>
<td width="20%" title="{{item.key}}"> <td width="20%" title="{{item.key}}">
...@@ -455,7 +472,7 @@ ...@@ -455,7 +472,7 @@
</tr> </tr>
<tr ng-repeat="item in commits.changeSets.updateItems"> <tr ng-repeat="item in commits.changeSets.updateItems">
<td width="2%"> <td width="2%">
更新 {{'Component.Namespace.Branch.History.Modifed' | translate }}
</td> </td>
<td width="20%" title="{{item.newItem.key}}"> <td width="20%" title="{{item.newItem.key}}">
<span ng-bind="item.newItem.key | limitTo: 250"></span> <span ng-bind="item.newItem.key | limitTo: 250"></span>
...@@ -479,7 +496,7 @@ ...@@ -479,7 +496,7 @@
<tr ng-repeat="item in commits.changeSets.deleteItems" <tr ng-repeat="item in commits.changeSets.deleteItems"
ng-show="item.key || item.comment"> ng-show="item.key || item.comment">
<td width="2%"> <td width="2%">
删除 {{'Component.Namespace.Branch.History.Deleted' | translate }}
</td> </td>
<td width="20%" title="{{item.key}}"> <td width="20%" title="{{item.key}}">
<span ng-bind="item.key | limitTo: 250"></span> <span ng-bind="item.key | limitTo: 250"></span>
...@@ -502,14 +519,14 @@ ...@@ -502,14 +519,14 @@
<!--not properties format--> <!--not properties format-->
<div ng-if="!namespace.isPropertiesFormat"> <div ng-if="!namespace.isPropertiesFormat">
<div ng-repeat="item in commits.changeSets.createItems"> <div ng-repeat="item in commits.changeSets.createItems">
<textarea class="form-control no-radius" rows="20" <textarea class="form-control no-radius" rows="20" ng-disabled="true"
ng-disabled="true" ng-bind="item.value"> ng-bind="item.value">
</textarea> </textarea>
</div> </div>
<div ng-repeat="item in commits.changeSets.updateItems"> <div ng-repeat="item in commits.changeSets.updateItems">
<textarea class="form-control no-radius" rows="20" <textarea class="form-control no-radius" rows="20" ng-disabled="true"
ng-disabled="true" ng-bind="item.newItem.value"> ng-bind="item.newItem.value">
</textarea> </textarea>
</div> </div>
</div> </div>
...@@ -520,12 +537,12 @@ ...@@ -520,12 +537,12 @@
</div> </div>
<div class="text-center"> <div class="text-center">
<button type="button" class="btn btn-default" ng-show="!namespace.branch.hasLoadAllCommit" <button type="button" class="btn btn-default" ng-show="!namespace.branch.hasLoadAllCommit"
ng-click="loadCommitHistory(namespace.branch)">加载更多 ng-click="loadCommitHistory(namespace.branch)">{{'Component.Namespace.Branch.History.LoadingMore' | translate }}
<span class="glyphicon glyphicon-menu-down"></span></button> <span class="glyphicon glyphicon-menu-down"></span></button>
</div> </div>
<div class="empty-container text-center" <div class="empty-container text-center"
ng-show="!namespace.branch.commits || !namespace.branch.commits.length"> ng-show="!namespace.branch.commits || !namespace.branch.commits.length">
无更改历史 {{'Component.Namespace.Branch.History.NoHistory' | translate }}
</div> </div>
</div> </div>
</section> </section>
......
...@@ -3,17 +3,17 @@ ...@@ -3,17 +3,17 @@
<div class="col-md-6" style="padding-bottom:5px;"> <div class="col-md-6" style="padding-bottom:5px;">
<span class="text-center namespace-attribute-public label label-primary no-radius"> <span class="text-center namespace-attribute-public label label-primary no-radius">
<span data-tooltip="tooltip" data-placement="bottom" <span data-tooltip="tooltip" data-placement="bottom"
title="私有namespace({{namespace.baseInfo.namespaceName}})的配置只能被AppId为{{appId}}的客户端读取到" title="{{'Component.Namespace.Header.Title.PrivateTips' | translate:this }}"
ng-show="!namespace.isPublic">私有</span> ng-show="!namespace.isPublic">{{'Component.Namespace.Header.Title.Private' | translate }}</span>
<span data-tooltip="tooltip" data-placement="top" <span data-tooltip="tooltip" data-placement="top"
title="namespace({{namespace.baseInfo.namespaceName}})的配置能被任何客户端读取到" title="{{'Component.Namespace.Header.Title.PublicTips' | translate:this }}"
ng-show="namespace.isPublic && namespace.parentAppId == namespace.baseInfo.appId">公共</span> ng-show="namespace.isPublic && namespace.parentAppId == namespace.baseInfo.appId">{{'Component.Namespace.Header.Title.Public' | translate }}</span>
<span data-tooltip="tooltip" data-placement="top" <span data-tooltip="tooltip" data-placement="top"
title="namespace({{namespace.baseInfo.namespaceName}})的配置将会覆盖公共namespace的配置, 且合并之后的配置只能被AppId为{{appId}}的客户端读取到" title="{{'Component.Namespace.Header.Title.ExtendTips' | translate:this }}"
ng-show="namespace.isPublic && namespace.isLinkedNamespace" ng-show="namespace.isPublic && namespace.isLinkedNamespace"
ng-click="goToParentAppConfigPage(namespace)">关联</span> ng-click="goToParentAppConfigPage(namespace)">{{'Component.Namespace.Header.Title.Extend' | translate }}</span>
</span> </span>
<span class="text-center namespace-attribute-public label label-info no-radius"> <span class="text-center namespace-attribute-public label label-info no-radius">
<span ng-bind="namespace.format" style="width:30px;"></span> <span ng-bind="namespace.format" style="width:30px;"></span>
...@@ -21,11 +21,10 @@ ...@@ -21,11 +21,10 @@
</div> </div>
<div class="col-md-6 text-right" style="padding-right:23px;"> <div class="col-md-6 text-right" style="padding-right:23px;">
<span data-toggle="collapse" data-target="#BODY{{namespace.branch.id}}" aria-expanded="false"> <span data-toggle="collapse" data-target="#BODY{{namespace.branch.id}}" aria-expanded="false">
<span class="label no-radius cursor-pointer" <span class="label no-radius cursor-pointer" data-toggle="collapse" data-target="#BODY{{namespace.id}}"
data-toggle="collapse" data-target="#BODY{{namespace.id}}" aria-expanded="false" aria-expanded="false" ng-click="showNamespaceBody = !showNamespaceBody"
ng-click="showNamespaceBody = !showNamespaceBody"
ng-show="namespace.initialized"> ng-show="namespace.initialized">
<a>[展开/收缩]</a> <a>{{'Component.Namespace.Header.Title.ExpandAndCollapse' | translate }}</a>
</span> </span>
</span> </span>
</div> </div>
...@@ -41,14 +40,14 @@ ...@@ -41,14 +40,14 @@
<a ng-class="{'node_active': namespace.displayControl.currentOperateBranch == 'master'}" <a ng-class="{'node_active': namespace.displayControl.currentOperateBranch == 'master'}"
ng-click="switchBranch('master', true)"> ng-click="switchBranch('master', true)">
<img src="img/branch.png"> <img src="img/branch.png">
主版本 {{'Component.Namespace.Header.Title.Master' | translate }}
</a> </a>
</li> </li>
<li role="presentation"> <li role="presentation">
<a ng-class="{'node_active': namespace.displayControl.currentOperateBranch != 'master'}" <a ng-class="{'node_active': namespace.displayControl.currentOperateBranch != 'master'}"
ng-click="switchBranch(namespace.branchName, true)"> ng-click="switchBranch(namespace.branchName, true)">
<img src="img/branch.png"> <img src="img/branch.png">
灰度版本 {{'Component.Namespace.Header.Title.Grayscale' | translate }}
</a> </a>
</li> </li>
......
...@@ -9,11 +9,11 @@ ...@@ -9,11 +9,11 @@
<div class="col-md-6 col-sm-6 text-right header-buttons"> <div class="col-md-6 col-sm-6 text-right header-buttons">
<button type="button" class="btn btn-default btn-sm" <button type="button" class="btn btn-default btn-sm" data-tooltip="tooltip" data-placement="bottom"
data-tooltip="tooltip" data-placement="bottom" title="加载Namespace" title="{{'Component.Namespace.Master.LoadNamespaceTips' | translate }}"
ng-click="refreshNamespace()"> ng-click="refreshNamespace()">
<img src="img/more.png"> <img src="img/more.png">
加载Namespace {{'Component.Namespace.Master.LoadNamespace' | translate }}
</button> </button>
</div> </div>
</div> </div>
...@@ -21,8 +21,7 @@ ...@@ -21,8 +21,7 @@
</section> </section>
<!--master panel body--> <!--master panel body-->
<section class="master-panel-body" <section class="master-panel-body" ng-if="namespace.initialized &&
ng-if="namespace.initialized &&
(namespace.hasBranch && namespace.displayControl.currentOperateBranch == 'master' || !namespace.hasBranch)"> (namespace.hasBranch && namespace.displayControl.currentOperateBranch == 'master' || !namespace.hasBranch)">
<!--main header--> <!--main header-->
<header class="panel-heading"> <header class="panel-heading">
...@@ -31,70 +30,69 @@ ...@@ -31,70 +30,69 @@
<b class="namespace-name" ng-bind="namespace.viewName"></b> <b class="namespace-name" ng-bind="namespace.viewName"></b>
<span class="label label-warning no-radius namespace-label modify-tip" <span class="label label-warning no-radius namespace-label modify-tip"
ng-show="namespace.itemModifiedCnt > 0"> ng-show="namespace.itemModifiedCnt > 0">
有修改 {{'Component.Namespace.Master.Items.Changed' | translate }}
<span class="badge label badge-white namespace-label" ng-bind="namespace.itemModifiedCnt"></span> <span class="badge label badge-white namespace-label" ng-bind="namespace.itemModifiedCnt"></span>
</span> </span>
<span class="label label-primary no-radius namespace-label" <span class="label label-primary no-radius namespace-label"
ng-show="namespace.lockOwner">当前修改者:{{namespace.lockOwner}}</span> ng-show="namespace.lockOwner">{{'Component.Namespace.Master.Items.ChangedUser' | translate }}:{{namespace.lockOwner}}</span>
</div> </div>
<div class="col-md-6 col-sm-6 text-right header-buttons"> <div class="col-md-6 col-sm-6 text-right header-buttons">
<button type="button" class="btn btn-success btn-sm" <button type="button" class="btn btn-success btn-sm" data-tooltip="tooltip" data-placement="bottom"
data-tooltip="tooltip" data-placement="bottom" title="发布配置" title="{{'Component.Namespace.Master.Items.PubishTips' | translate }}"
ng-show="(namespace.hasReleasePermission || namespace.hasModifyPermission)" ng-show="(namespace.hasReleasePermission || namespace.hasModifyPermission)"
ng-disabled="namespace.isTextEditing" ng-disabled="namespace.isTextEditing" ng-click="publish(namespace)">
ng-click="publish(namespace)">
<img src="img/release.png"> <img src="img/release.png">
发布 {{'Component.Namespace.Master.Items.Pubish' | translate }}
</button> </button>
<button type="button" class="btn btn-default btn-sm" <button type="button" class="btn btn-default btn-sm" data-tooltip="tooltip" data-placement="bottom"
data-tooltip="tooltip" data-placement="bottom" title="回滚已发布配置" title="{{'Component.Namespace.Master.Items.RollbackTips' | translate }}"
ng-show="namespace.hasReleasePermission" ng-show="namespace.hasReleasePermission" ng-click="rollback(namespace)">
ng-click="rollback(namespace)">
<img src="img/rollback.png"> <img src="img/rollback.png">
回滚 {{'Component.Namespace.Master.Items.Rollback' | translate }}
</button> </button>
<a type="button" class="btn btn-default btn-sm" <a type="button" class="btn btn-default btn-sm" data-tooltip="tooltip" data-placement="bottom"
data-tooltip="tooltip" data-placement="bottom" title="查看发布历史" title="{{'Component.Namespace.Master.Items.PubishHistoryTips' | translate }}"
href="/config/history.html?#/appid={{appId}}&env={{env}}&clusterName={{cluster}}&namespaceName={{namespace.baseInfo.namespaceName}}"> href="/config/history.html?#/appid={{appId}}&env={{env}}&clusterName={{cluster}}&namespaceName={{namespace.baseInfo.namespaceName}}">
<img src="img/release-history.png"> <img src="img/release-history.png">
发布历史 {{'Component.Namespace.Master.Items.PubishHistory' | translate }}
</a> </a>
<a type="button" class="btn btn-default btn-sm" <a type="button" class="btn btn-default btn-sm" data-tooltip="tooltip" data-placement="bottom"
data-tooltip="tooltip" data-placement="bottom" title="配置修改、发布权限" title="{{'Component.Namespace.Master.Items.GrantTips' | translate }}"
href="/namespace/role.html?#/appid={{appId}}&namespaceName={{namespace.baseInfo.namespaceName}}" href="/namespace/role.html?#/appid={{appId}}&namespaceName={{namespace.baseInfo.namespaceName}}"
ng-show="hasAssignUserPermission"> ng-show="hasAssignUserPermission">
<img src="img/assign.png"> <img src="img/assign.png">
授权 {{'Component.Namespace.Master.Items.Grant' | translate }}
</a> </a>
<a type="button" class="btn btn-default btn-sm" <a type="button" class="btn btn-default btn-sm" data-tooltip="tooltip" data-placement="bottom"
data-tooltip="tooltip" data-placement="bottom" title="创建测试版本" title="{{'Component.Namespace.Master.Items.GrayscaleTips' | translate }}"
ng-show="!namespace.hasBranch && namespace.isPropertiesFormat && namespace.hasModifyPermission" ng-show="!namespace.hasBranch && namespace.isPropertiesFormat && namespace.hasModifyPermission"
ng-click="preCreateBranch(namespace)"> ng-click="preCreateBranch(namespace)">
<img src="img/test.png"> <img src="img/test.png">
灰度 {{'Component.Namespace.Master.Items.Grayscale' | translate }}
</a> </a>
<a type="button" class="btn btn-default btn-sm J_tableview_btn" <a type="button" class="btn btn-default btn-sm J_tableview_btn" data-tooltip="tooltip"
data-tooltip="tooltip" data-placement="bottom" title="您没有任何配置权限,请申请" data-placement="bottom"
title="{{'Component.Namespace.Master.Items.RequestPermissionTips' | translate }}"
ng-click="showNoModifyPermissionDialog()" ng-click="showNoModifyPermissionDialog()"
ng-show="!namespace.hasModifyPermission && !namespace.hasReleasePermission"> ng-show="!namespace.hasModifyPermission && !namespace.hasReleasePermission">
申请配置权限 {{'Component.Namespace.Master.Items.RequestPermission' | translate }}
</a> </a>
<div class="btn-group" <div class="btn-group"
ng-show="namespace.hasModifyPermission || namespace.hasReleasePermission || hasAssignUserPermission"> ng-show="namespace.hasModifyPermission || namespace.hasReleasePermission || hasAssignUserPermission">
<button type="button" class="btn btn-default btn-sm dropdown-toggle" <button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown"
data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false"> aria-haspopup="true" aria-expanded="false">
<img src="img/operate.png"> <span class="caret"></span> <img src="img/operate.png"> <span class="caret"></span>
</button> </button>
<ul class="dropdown-menu" style="right: 0; left: -160px;"> <ul class="dropdown-menu" style="right: 0; left: -160px;">
<li ng-click="deleteNamespace(namespace)"> <li ng-click="deleteNamespace(namespace)">
<a style="color: red"> <a style="color: red">
<img src="img/delete.png"> 删除Namespace</a> <img src="img/delete.png">
{{'Component.Namespace.Master.Items.DeleteNamespace' | translate }}</a>
</li> </li>
</ul> </ul>
</div> </div>
...@@ -105,9 +103,8 @@ ...@@ -105,9 +103,8 @@
<div id="BODY{{namespace.id}}" ng-class="{'collapse in': showNamespaceBody, 'collapse' : !showNamespaceBody}"> <div id="BODY{{namespace.id}}" ng-class="{'collapse in': showNamespaceBody, 'collapse' : !showNamespaceBody}">
<div class="J_namespace-release-tip well well-sm no-radius text-center" <div class="J_namespace-release-tip well well-sm no-radius text-center" ng-show="namespace.isConfigHidden">
ng-show="namespace.isConfigHidden"> <span style="color: red">{{'Component.Namespace.Master.Items.NoPermissionTips' | translate }}</span>
<span style="color: red">您不是该项目的管理员,也没有该Namespace的编辑或发布权限,无法查看配置信息。</span>
</div> </div>
<!--second header--> <!--second header-->
...@@ -120,26 +117,25 @@ ...@@ -120,26 +117,25 @@
ng-show="namespace.isPropertiesFormat"> ng-show="namespace.isPropertiesFormat">
<a ng-class="{node_active:namespace.viewType == 'table'}"> <a ng-class="{node_active:namespace.viewType == 'table'}">
<img src="img/table.png"> <img src="img/table.png">
表格 {{'Component.Namespace.Master.Items.ItemList' | translate }}
</a> </a>
</li> </li>
<li role="presentation" <li role="presentation" ng-click="switchView(namespace, 'text')">
ng-click="switchView(namespace, 'text')">
<a ng-class="{node_active:namespace.viewType == 'text'}"> <a ng-class="{node_active:namespace.viewType == 'text'}">
<img src="img/text.png"> <img src="img/text.png">
文本 {{'Component.Namespace.Master.Items.ItemListByText' | translate }}
</a> </a>
</li> </li>
<li role="presentation" ng-click="switchView(namespace, 'history')"> <li role="presentation" ng-click="switchView(namespace, 'history')">
<a ng-class="{node_active:namespace.viewType == 'history'}"> <a ng-class="{node_active:namespace.viewType == 'history'}">
<img src="img/change.png"> <img src="img/change.png">
更改历史 {{'Component.Namespace.Master.Items.ItemHistory' | translate }}
</a> </a>
</li> </li>
<li role="presentation" ng-click="switchView(namespace, 'instance')"> <li role="presentation" ng-click="switchView(namespace, 'instance')">
<a ng-class="{node_active:namespace.viewType == 'instance'}"> <a ng-class="{node_active:namespace.viewType == 'instance'}">
<img src="img/machine.png"> <img src="img/machine.png">
实例列表 {{'Component.Namespace.Master.Items.ItemInstance' | translate }}
<span class="badge badge-grey" ng-bind="namespace.instancesCount"></span> <span class="badge badge-grey" ng-bind="namespace.instancesCount"></span>
</a> </a>
</li> </li>
...@@ -147,65 +143,60 @@ ...@@ -147,65 +143,60 @@
</div> </div>
<div class="col-md-6 col-sm-6 text-right"> <div class="col-md-6 col-sm-6 text-right">
<img src="img/copy.png" class="ns_btn clipboard cursor-pointer" <img src="img/copy.png" class="ns_btn clipboard cursor-pointer"
data-clipboard-text="{{namespace.text}}" data-clipboard-text="{{namespace.text}}" data-tooltip="tooltip" data-placement="bottom"
data-tooltip="tooltip" data-placement="bottom" title="复制文本" title="{{'Component.Namespace.Master.Items.CopyText' | translate }}"
ng-show="!namespace.isTextEditing && namespace.viewType == 'text' && namespace.hasModifyPermission"> ng-show="!namespace.isTextEditing && namespace.viewType == 'text' && namespace.hasModifyPermission">
<img src="img/syntax.png" class="ns_btn cursor-pointer" <img src="img/syntax.png" class="ns_btn cursor-pointer" data-tooltip="tooltip"
data-tooltip="tooltip" data-placement="bottom" title="语法检查" data-placement="bottom" title="{{'Component.Namespace.Master.Items.GrammarCheck' | translate }}"
ng-show="namespace.isTextEditing && namespace.viewType == 'text' && namespace.isSyntaxCheckable" ng-show="namespace.isTextEditing && namespace.viewType == 'text' && namespace.isSyntaxCheckable"
ng-click="syntaxCheck(namespace)"> ng-click="syntaxCheck(namespace)">
&nbsp; &nbsp;
<img src="img/cancel.png" class="ns_btn cursor-pointer" <img src="img/cancel.png" class="ns_btn cursor-pointer" data-tooltip="tooltip"
data-tooltip="tooltip" data-placement="bottom" title="取消修改" data-placement="bottom"
title="{{'Component.Namespace.Master.Items.CancelChanged' | translate }}"
ng-show="namespace.isTextEditing && namespace.viewType == 'text'" ng-show="namespace.isTextEditing && namespace.viewType == 'text'"
ng-click="toggleTextEditStatus(namespace)"> ng-click="toggleTextEditStatus(namespace)">
<img src="img/edit.png" class="ns_btn cursor-pointer" <img src="img/edit.png" class="ns_btn cursor-pointer" data-tooltip="tooltip" data-placement="bottom"
data-tooltip="tooltip" data-placement="bottom" title="修改配置" title="{{'Component.Namespace.Master.Items.Change' | translate }}"
ng-show="!namespace.isTextEditing && namespace.viewType == 'text' && namespace.hasModifyPermission" ng-show="!namespace.isTextEditing && namespace.viewType == 'text' && namespace.hasModifyPermission"
ng-click="toggleTextEditStatus(namespace)"> ng-click="toggleTextEditStatus(namespace)">
&nbsp; &nbsp;
<img src="img/submit.png" class="ns_btn cursor-pointer" <img src="img/submit.png" class="ns_btn cursor-pointer" data-tooltip="tooltip"
data-tooltip="tooltip" data-placement="bottom" title="提交修改" data-placement="bottom"
data-toggle="modal" data-target="#commitModal" title="{{'Component.Namespace.Master.Items.SummitChanged' | translate }}" data-toggle="modal"
ng-show="namespace.isTextEditing && namespace.viewType == 'text'" data-target="#commitModal" ng-show="namespace.isTextEditing && namespace.viewType == 'text'"
ng-click="modifyByText(namespace)"> ng-click="modifyByText(namespace)">
<button type="button" class="btn btn-default btn-sm" <button type="button" class="btn btn-default btn-sm" data-tooltip="tooltip" data-placement="bottom"
data-tooltip="tooltip" data-placement="bottom" title="按Key过滤配置" title="{{'Component.Namespace.Master.Items.SortByKey' | translate }}" ng-show="namespace.viewType == 'table' && namespace.displayControl.currentOperateBranch == 'master'
ng-show="namespace.viewType == 'table' && namespace.displayControl.currentOperateBranch == 'master' && !namespace.isLinkedNamespace" ng-click="toggleItemSearchInput(namespace)">
&& !namespace.isLinkedNamespace"
ng-click="toggleItemSearchInput(namespace)">
<span class="glyphicon glyphicon-filter"></span> <span class="glyphicon glyphicon-filter"></span>
过滤配置 {{'Component.Namespace.Master.Items.FilterItem' | translate }}
</button> </button>
<button type="button" class="btn btn-default btn-sm J_tableview_btn" <button type="button" class="btn btn-default btn-sm J_tableview_btn" data-tooltip="tooltip"
data-tooltip="tooltip" data-placement="bottom" title="同步各环境间配置" data-placement="bottom" title="{{'Component.Namespace.Master.Items.SyncItemTips' | translate }}"
ng-click="goToSyncPage(namespace)" ng-click="goToSyncPage(namespace)" ng-show="namespace.viewType == 'table' && namespace.displayControl.currentOperateBranch == 'master'
ng-show="namespace.viewType == 'table' && namespace.displayControl.currentOperateBranch == 'master'
&& namespace.hasModifyPermission && namespace.isPropertiesFormat"> && namespace.hasModifyPermission && namespace.isPropertiesFormat">
<img src="img/sync.png"> <img src="img/sync.png">
同步配置 {{'Component.Namespace.Master.Items.SyncItem' | translate }}
</button> </button>
<button type="button" class="btn btn-default btn-sm J_tableview_btn" <button type="button" class="btn btn-default btn-sm J_tableview_btn" data-tooltip="tooltip"
data-tooltip="tooltip" data-placement="bottom" title="比较各环境间配置" data-placement="bottom" title="{{'Component.Namespace.Master.Items.DiffItemTips' | translate }}"
ng-click="goToDiffPage(namespace)" ng-click="goToDiffPage(namespace)" ng-show="namespace.viewType == 'table' && namespace.displayControl.currentOperateBranch == 'master'
ng-show="namespace.viewType == 'table' && namespace.displayControl.currentOperateBranch == 'master'
&& namespace.isPropertiesFormat"> && namespace.isPropertiesFormat">
<img src="img/diff.png"> <img src="img/diff.png">
比较配置 {{'Component.Namespace.Master.Items.DiffItem' | translate }}
</button> </button>
<button type="button" class="btn btn-primary btn-sm" <button type="button" class="btn btn-primary btn-sm" ng-show="!namespace.isLinkedNamespace
ng-show="!namespace.isLinkedNamespace
&& namespace.viewType == 'table' && namespace.viewType == 'table'
&& namespace.displayControl.currentOperateBranch == 'master' && namespace.displayControl.currentOperateBranch == 'master'
&& namespace.hasModifyPermission" && namespace.hasModifyPermission" ng-click="createItem(namespace)">
ng-click="createItem(namespace)">
<img src="img/plus.png"> <img src="img/plus.png">
新增配置 {{'Component.Namespace.Master.Items.AddItem' | translate }}
</button> </button>
</div> </div>
</div> </div>
...@@ -218,76 +209,87 @@ ...@@ -218,76 +209,87 @@
<div class="J_namespace-release-tip well well-sm no-radius text-center" <div class="J_namespace-release-tip well well-sm no-radius text-center"
ng-show="namespace.isLatestReleaseLoaded && !namespace.isLinkedNamespace && !namespace.latestRelease"> ng-show="namespace.isLatestReleaseLoaded && !namespace.isLinkedNamespace && !namespace.latestRelease">
<span style="color: red"> Tips: 此namespace从来没有发布过,Apollo客户端将获取不到配置并记录404日志信息,请及时发布。</span> <span style="color: red">
{{'Component.Namespace.Master.Items.Body.ItemsNoPublishedTips' | translate }}</span>
</div> </div>
<!--not link namespace--> <!--not link namespace-->
<div ng-if="!namespace.isLinkedNamespace"> <div ng-if="!namespace.isLinkedNamespace">
<div class="search-input" ng-show="namespace.displayControl.showSearchInput"> <div class="search-input" ng-show="namespace.displayControl.showSearchInput">
<input type="text" class="form-control" placeholder="输入key过滤" <input type="text" class="form-control"
ng-model="namespace.searchKey" placeholder="{{'Component.Namespace.Master.Items.Body.FilterByKey' | translate }}"
ng-change="searchItems(namespace)"> ng-model="namespace.searchKey" ng-change="searchItems(namespace)">
</div> </div>
<table class="table table-bordered table-striped table-hover"> <table class="table table-bordered table-striped table-hover">
<thead> <thead>
<tr> <tr>
<th>发布状态</th> <th>{{'Component.Namespace.Master.Items.Body.PublishState' | translate }}</th>
<th class="hover" title="排序" <th class="hover" title="{{'Component.Namespace.Master.Items.Body.Sort' | translate }}"
ng-click="col='item.key';desc=!desc;"> ng-click="col='item.key';desc=!desc;">
Key&nbsp; {{'Component.Namespace.Master.Items.Body.ItemKey' | translate }}&nbsp;
<span class="glyphicon glyphicon-sort"></span> <span class="glyphicon glyphicon-sort"></span>
</th> </th>
<th> <th>
Value {{'Component.Namespace.Master.Items.Body.ItemValue' | translate }}
</th> </th>
<th> <th>
备注 {{'Component.Namespace.Master.Items.Body.ItemComment' | translate }}
</th> </th>
<th class="hover" title="排序" <th class="hover" title="{{'Component.Namespace.Master.Items.Body.Sort' | translate }}"
ng-click="col='item.dataChangeLastModifiedBy';desc=!desc;"> ng-click="col='item.dataChangeLastModifiedBy';desc=!desc;">
最后修改人 {{'Component.Namespace.Master.Items.Body.ItemLastModify' | translate }}
<span class="glyphicon glyphicon-sort"></span> <span class="glyphicon glyphicon-sort"></span>
</th> </th>
<th class="hover" title="排序" <th class="hover" title="{{'Component.Namespace.Master.Items.Body.Sort' | translate }}"
ng-click="col='item.dataChangeLastModifiedTime';desc=!desc;"> ng-click="col='item.dataChangeLastModifiedTime';desc=!desc;">
最后修改时间 {{'Component.Namespace.Master.Items.Body.ItemLastModifyTime' | translate }}
<span class="glyphicon glyphicon-sort"></span> <span class="glyphicon glyphicon-sort"></span>
</th> </th>
<th> <th>
操作 {{'Component.Namespace.Master.Items.Body.ItemOperator' | translate }}
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr ng-repeat="config in namespace.viewItems |orderBy:col:desc" <tr ng-repeat="config in namespace.viewItems |orderBy:col:desc" ng-if="config.item.key"
ng-if="config.item.key"
ng-class="{'warning': !config.item.value}"> ng-class="{'warning': !config.item.value}">
<td width="8%" class="text-center"> <td width="8%" class="text-center">
<span class="label label-warning no-radius cursor-pointer" ng-if="config.isModified" <span class="label label-warning no-radius cursor-pointer" ng-if="config.isModified"
data-tooltip="tooltip" data-placement="bottom" title="点击查看已发布的值" data-tooltip="tooltip" data-placement="bottom"
ng-click="showText(config.oldValue?config.oldValue:'新增的配置,无发布的值')">未发布</span> title="{{'Component.Namespace.Master.Items.Body.NoPublishTitle' | translate }}"
<span class="label label-default-light no-radius" ng-click="showText(config.oldValue?config.oldValue:('Component.Namespace.Master.Items.Body.NoPublishTips' | translate))">{{'Component.Namespace.Master.Items.Body.NoPublish' | translate }}</span>
data-tooltip="tooltip" data-placement="bottom" title="已生效的配置" <span class="label label-default-light no-radius" data-tooltip="tooltip"
ng-if="!config.isModified">已发布</span> data-placement="bottom"
</td> title="{{'Component.Namespace.Master.Items.Body.PublishedTitle' | translate }}"
<td width="15%" class="cursor-pointer" title="点击查看" ng-click="showText(config.item.key)"> ng-if="!config.isModified">{{'Component.Namespace.Master.Items.Body.Published' | translate }}</span>
</td>
<td width="15%" class="cursor-pointer"
title="{{'Component.Namespace.Master.Items.Body.ClickToSee' | translate }}"
ng-click="showText(config.item.key)">
<span ng-bind="config.item.key | limitTo: 250"></span> <span ng-bind="config.item.key | limitTo: 250"></span>
<span ng-bind="config.item.key.length > 250 ? '...' :''"></span> <span ng-bind="config.item.key.length > 250 ? '...' :''"></span>
<span class="label label-default cursor-pointer" ng-if="config.hasBranchValue" <span class="label label-default cursor-pointer" ng-if="config.hasBranchValue"
data-tooltip="tooltip" data-placement="bottom" title="该配置有灰度配置,点击查看灰度的值" data-tooltip="tooltip" data-placement="bottom"
ng-click="namespace.displayControl.currentOperateBranch=namespace.branchName;namespace.branch.viewType='table'"></span> title="{{'Component.Namespace.Master.Items.Body.HaveGrayscale' | translate }}"
ng-click="namespace.displayControl.currentOperateBranch=namespace.branchName;namespace.branch.viewType='table'">{{'Component.Namespace.Master.Items.Body.Grayscale' | translate }}</span>
<span class="label label-success" ng-if="config.isModified && !config.oldValue" <span class="label label-success" ng-if="config.isModified && !config.oldValue"
data-tooltip="tooltip" data-placement="bottom" title="新增的配置"></span> data-tooltip="tooltip" data-placement="bottom"
title="{{'Component.Namespace.Master.Items.Body.NewAddedTips' | translate }}">{{'Component.Namespace.Master.Items.Body.NewAdded' | translate }}</span>
<span class="label label-info" <span class="label label-info"
ng-if="config.isModified && config.oldValue && !config.isDeleted" ng-if="config.isModified && config.oldValue && !config.isDeleted"
data-tooltip="tooltip" data-placement="bottom" title="修改的配置"></span> data-tooltip="tooltip" data-placement="bottom"
<span class="label label-danger" ng-if="config.isDeleted" title="{{'Component.Namespace.Master.Items.Body.ModifedTips' | translate }}">{{'Component.Namespace.Master.Items.Body.Modifed' | translate }}</span>
data-tooltip="tooltip" data-placement="bottom" title="删除的配置"></span> <span class="label label-danger" ng-if="config.isDeleted" data-tooltip="tooltip"
</td> data-placement="bottom"
<td width="30%" class="cursor-pointer" title="点击查看" ng-click="showText(config.item.value)"> title="{{'Component.Namespace.Master.Items.Body.DeletedTips' | translate }}">{{'Component.Namespace.Master.Items.Body.Deleted' | translate }}</span>
</td>
<td width="30%" class="cursor-pointer"
title="{{'Component.Namespace.Master.Items.Body.ClickToSee' | translate }}"
ng-click="showText(config.item.value)">
<span ng-bind="config.item.value | limitTo: 250"></span> <span ng-bind="config.item.value | limitTo: 250"></span>
<span ng-bind="config.item.value.length > 250 ? '...': ''"></span> <span ng-bind="config.item.value.length > 250 ? '...': ''"></span>
</td> </td>
...@@ -302,11 +304,13 @@ ...@@ -302,11 +304,13 @@
</td> </td>
<td width="8%" class="text-center" ng-if="!config.isDeleted"> <td width="8%" class="text-center" ng-if="!config.isDeleted">
<img src="img/edit.png" data-tooltip="tooltip" data-placement="bottom" title="修改" <img src="img/edit.png" data-tooltip="tooltip" data-placement="bottom"
title="{{'Component.Namespace.Master.Items.Body.ModifyTips' | translate }}"
ng-click="editItem(namespace, config.item)" ng-click="editItem(namespace, config.item)"
ng-show="namespace.hasModifyPermission"> ng-show="namespace.hasModifyPermission">
<img style="margin-left: 5px;" src="img/cancel.png" <img style="margin-left: 5px;" src="img/cancel.png" data-tooltip="tooltip"
data-tooltip="tooltip" data-placement="bottom" title="删除" data-placement="bottom"
title="{{'Component.Namespace.Master.Items.Body.DeleteTips' | translate }}"
ng-click="preDeleteItem(namespace, config.item)" ng-click="preDeleteItem(namespace, config.item)"
ng-show="namespace.hasModifyPermission"> ng-show="namespace.hasModifyPermission">
</td> </td>
...@@ -323,15 +327,13 @@ ...@@ -323,15 +327,13 @@
<div class="panel-heading"> <div class="panel-heading">
<div class="row"> <div class="row">
<div class="padding-top-5 col-md-4 col-sm-4"> <div class="padding-top-5 col-md-4 col-sm-4">
覆盖的配置 {{'Component.Namespace.Master.Items.Body.Link.Title' | translate }}
</div> </div>
<div class="col-md-8 col-sm-8"> <div class="col-md-8 col-sm-8">
<input type="text" class="form-control pull-right" placeholder="filter by key ..." <input type="text" class="form-control pull-right" placeholder="filter by key ..."
ng-class="{'search-onblur': namespace.searchStatus == 'OFF' || !namespace.searchStatus, ng-class="{'search-onblur': namespace.searchStatus == 'OFF' || !namespace.searchStatus,
'search-focus': namespace.searchStatus == 'ON'}" 'search-focus': namespace.searchStatus == 'ON'}" ng-model="namespace.searchKey"
ng-model="namespace.searchKey" ng-change="searchItems(namespace)" ng-focus="namespace.searchStatus='ON'"
ng-change="searchItems(namespace)"
ng-focus="namespace.searchStatus='ON'"
ng-blur="namespace.searchStatus='OFF'"> ng-blur="namespace.searchStatus='OFF'">
</div> </div>
</div> </div>
...@@ -341,62 +343,71 @@ ...@@ -341,62 +343,71 @@
ng-if="namespace.viewItems && namespace.viewItems.length"> ng-if="namespace.viewItems && namespace.viewItems.length">
<thead> <thead>
<tr> <tr>
<th>发布状态</th> <th>{{'Component.Namespace.Master.Items.Body.PublishState' | translate }}</th>
<th class="hover" title="排序" <th class="hover" title="{{'Component.Namespace.Master.Items.Body.Sort' | translate }}"
ng-click="col='item.key';desc=!desc;"> ng-click="col='item.key';desc=!desc;">
Key&nbsp; {{'Component.Namespace.Master.Items.Body.ItemKey' | translate }}&nbsp;
<span class="glyphicon glyphicon-sort"></span> <span class="glyphicon glyphicon-sort"></span>
</th> </th>
<th> <th>
Value {{'Component.Namespace.Master.Items.Body.ItemValue' | translate }}
</th> </th>
<th> <th>
备注 {{'Component.Namespace.Master.Items.Body.ItemComment' | translate }}
</th> </th>
<th class="hover" title="排序" <th class="hover" title="{{'Component.Namespace.Master.Items.Body.Sort' | translate }}"
ng-click="col='item.dataChangeLastModifiedBy';desc=!desc;"> ng-click="col='item.dataChangeLastModifiedBy';desc=!desc;">
最后修改人 {{'Component.Namespace.Master.Items.Body.ItemLastModify' | translate }}
<span class="glyphicon glyphicon-sort"></span> <span class="glyphicon glyphicon-sort"></span>
</th> </th>
<th class="hover" title="排序" <th class="hover" title="{{'Component.Namespace.Master.Items.Body.Sort' | translate }}"
ng-click="col='item.dataChangeLastModifiedTime';desc=!desc;"> ng-click="col='item.dataChangeLastModifiedTime';desc=!desc;">
最后修改时间 {{'Component.Namespace.Master.Items.Body.ItemLastModifyTime' | translate }}
<span class="glyphicon glyphicon-sort"></span> <span class="glyphicon glyphicon-sort"></span>
</th> </th>
<th> <th>
操作 {{'Component.Namespace.Master.Items.Body.ItemOperator' | translate }}
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr ng-repeat="config in namespace.viewItems |orderBy:col:desc" <tr ng-repeat="config in namespace.viewItems |orderBy:col:desc" ng-if="config.item.key">
ng-if="config.item.key">
<td width="8%" class="text-center"> <td width="8%" class="text-center">
<span class="label label-warning no-radius cursor-pointer" ng-if="config.isModified" <span class="label label-warning no-radius cursor-pointer" ng-if="config.isModified"
data-tooltip="tooltip" data-placement="bottom" title="点击查看已发布的值" data-tooltip="tooltip" data-placement="bottom"
ng-click="showText(config.oldValue?config.oldValue:'新增的配置,无发布的值')">未发布</span> title="{{'Component.Namespace.Master.Items.Body.NoPublishTitle' | translate }}"
<span class="label label-default-light no-radius" ng-click="showText(config.oldValue?config.oldValue:('Component.Namespace.Master.Items.Body.NoPublishTips' | translate))">{{'Component.Namespace.Master.Items.Body.NoPublish' | translate }}</span>
data-tooltip="tooltip" data-placement="bottom" title="已生效的配置" <span class="label label-default-light no-radius" data-tooltip="tooltip"
ng-if="!config.isModified">已发布</span> data-placement="bottom"
</td> title="{{'Component.Namespace.Master.Items.Body.PublishedTitle' | translate }}"
<td width="15%" class="cursor-pointer" title="点击查看" ng-click="showText(config.item.key)"> ng-if="!config.isModified">{{'Component.Namespace.Master.Items.Body.Published' | translate }}</span>
</td>
<td width="15%" class="cursor-pointer"
title="{{'Component.Namespace.Master.Items.Body.ClickToSee' | translate }}"
ng-click="showText(config.item.key)">
<span ng-bind="config.item.key | limitTo: 250"></span> <span ng-bind="config.item.key | limitTo: 250"></span>
<span ng-bind="config.item.key.length > 250 ? '...' :''"></span> <span ng-bind="config.item.key.length > 250 ? '...' :''"></span>
<span class="label label-default cursor-pointer" ng-if="config.hasBranchValue" <span class="label label-default cursor-pointer" ng-if="config.hasBranchValue"
data-tooltip="tooltip" data-placement="bottom" title="该配置有灰度配置,点击查看灰度的值" data-tooltip="tooltip" data-placement="bottom"
ng-click="namespace.displayControl.currentOperateBranch=namespace.branchName;namespace.branch.viewType='table'"></span> title="{{'Component.Namespace.Master.Items.Body.HaveGrayscale' | translate }}"
ng-click="namespace.displayControl.currentOperateBranch=namespace.branchName;namespace.branch.viewType='table'">{{'Component.Namespace.Master.Items.Body.Grayscale' | translate }}</span>
<span class="label label-success" ng-if="config.isModified && !config.oldValue" <span class="label label-success" ng-if="config.isModified && !config.oldValue"
data-tooltip="tooltip" data-placement="bottom" title="新增的配置"></span> data-tooltip="tooltip" data-placement="bottom"
title="{{'Component.Namespace.Master.Items.Body.NewAddedTips' | translate }}">{{'Component.Namespace.Master.Items.Body.NewAdded' | translate }}</span>
<span class="label label-info" <span class="label label-info"
ng-if="config.isModified && config.oldValue && !config.isDeleted" ng-if="config.isModified && config.oldValue && !config.isDeleted"
data-tooltip="tooltip" data-placement="bottom" title="修改的配置"></span> data-tooltip="tooltip" data-placement="bottom"
<span class="label label-danger" ng-if="config.isDeleted" title="{{'Component.Namespace.Master.Items.Body.ModifedTips' | translate }}">{{'Component.Namespace.Master.Items.Body.Modifed' | translate }}</span>
data-tooltip="tooltip" data-placement="bottom" title="删除的配置"></span> <span class="label label-danger" ng-if="config.isDeleted" data-tooltip="tooltip"
</td> data-placement="bottom"
<td width="30%" class="cursor-pointer" title="点击查看" ng-click="showText(config.item.value)"> title="{{'Component.Namespace.Master.Items.Body.DeletedTips' | translate }}">{{'Component.Namespace.Master.Items.Body.Deleted' | translate }}</span>
</td>
<td width="30%" class="cursor-pointer"
title="{{'Component.Namespace.Master.Items.Body.ClickToSee' | translate }}"
ng-click="showText(config.item.value)">
<span ng-bind="config.item.value | limitTo: 250"></span> <span ng-bind="config.item.value | limitTo: 250"></span>
<span ng-bind="config.item.value.length > 250 ? '...': ''"></span> <span ng-bind="config.item.value.length > 250 ? '...': ''"></span>
</td> </td>
...@@ -411,11 +422,13 @@ ...@@ -411,11 +422,13 @@
</td> </td>
<td width="8%" class="text-center" ng-if="!config.isDeleted"> <td width="8%" class="text-center" ng-if="!config.isDeleted">
<img src="img/edit.png" data-tooltip="tooltip" data-placement="bottom" title="修改" <img src="img/edit.png" data-tooltip="tooltip" data-placement="bottom"
title="{{'Component.Namespace.Master.Items.Body.ModifyTips' | translate }}"
ng-click="editItem(namespace, config.item)" ng-click="editItem(namespace, config.item)"
ng-show="namespace.hasModifyPermission"> ng-show="namespace.hasModifyPermission">
<img style="margin-left: 5px;" src="img/cancel.png" <img style="margin-left: 5px;" src="img/cancel.png" data-tooltip="tooltip"
data-tooltip="tooltip" data-placement="bottom" title="删除" data-placement="bottom"
title="{{'Component.Namespace.Master.Items.Body.DeleteTips' | translate }}"
ng-click="preDeleteItem(namespace, config.item)" ng-click="preDeleteItem(namespace, config.item)"
ng-show="namespace.hasModifyPermission"> ng-show="namespace.hasModifyPermission">
</td> </td>
...@@ -428,7 +441,7 @@ ...@@ -428,7 +441,7 @@
<div class="text-center no-config-panel" <div class="text-center no-config-panel"
ng-if="!namespace.viewItems || !namespace.viewItems.length"> ng-if="!namespace.viewItems || !namespace.viewItems.length">
<h5>无覆盖的配置</h5> <h5>{{'Component.Namespace.Master.Items.Body.Link.NoCoverLinkItem' | translate }}</h5>
</div> </div>
</div> </div>
...@@ -438,12 +451,12 @@ ...@@ -438,12 +451,12 @@
<div class="panel-heading"> <div class="panel-heading">
<div class="row"> <div class="row">
<div class="padding-top-5 col-md-4 col-sm-4"> <div class="padding-top-5 col-md-4 col-sm-4">
公共的配置 {{'Component.Namespace.Master.Items.Body.Public.Title' | translate }}
<a href="/config.html?#/appid={{namespace.publicNamespace.baseInfo.appId}}&env={{env}}&cluster={{namespace.publicNamespace.baseInfo.clusterName}}" <a href="/config.html?#/appid={{namespace.publicNamespace.baseInfo.appId}}&env={{env}}&cluster={{namespace.publicNamespace.baseInfo.clusterName}}"
target="_blank"> target="_blank">
<small> <small>
(AppId:{{namespace.publicNamespace.baseInfo.appId}}, ({{'Common.AppId' | translate }}:{{namespace.publicNamespace.baseInfo.appId}},
Cluster:{{namespace.publicNamespace.baseInfo.clusterName}}) {{'Common.Cluster' | translate }}:{{namespace.publicNamespace.baseInfo.clusterName}})
</small> </small>
</a> </a>
</div> </div>
...@@ -451,16 +464,15 @@ ...@@ -451,16 +464,15 @@
<div class="col-md-4 col-sm-4 text-center"> <div class="col-md-4 col-sm-4 text-center">
<div class="btn-group btn-group-sm" role="group" <div class="btn-group btn-group-sm" role="group"
ng-show="namespace.publicNamespace.isModified"> ng-show="namespace.publicNamespace.isModified">
<button type="button" class="btn btn-default" <button type="button" class="btn btn-default" ng-class="{'active':namespace.publicNamespaceViewType == 'RELEASE'
ng-class="{'active':namespace.publicNamespaceViewType == 'RELEASE'
|| !namespace.publicNamespaceViewType}" || !namespace.publicNamespaceViewType}"
ng-click="namespace.publicNamespaceViewType = 'RELEASE'"> ng-click="namespace.publicNamespaceViewType = 'RELEASE'">
已发布的配置 {{'Component.Namespace.Master.Items.Body.Public.Published' | translate }}
</button> </button>
<button type="button" class="btn btn-default" <button type="button" class="btn btn-default"
ng-class="{'active':namespace.publicNamespaceViewType == 'NOT_RELEASE'}" ng-class="{'active':namespace.publicNamespaceViewType == 'NOT_RELEASE'}"
ng-click="namespace.publicNamespaceViewType = 'NOT_RELEASE'"> ng-click="namespace.publicNamespaceViewType = 'NOT_RELEASE'">
未发布的配置 {{'Component.Namespace.Master.Items.Body.Public.NoPublish' | translate }}
</button> </button>
</div> </div>
</div> </div>
...@@ -473,56 +485,62 @@ ...@@ -473,56 +485,62 @@
ng-model="namespace.publicNamespace.searchKey" ng-model="namespace.publicNamespace.searchKey"
ng-change="searchItems(namespace.publicNamespace)" ng-change="searchItems(namespace.publicNamespace)"
ng-blur="namespace.publicNamespace.searchStatus='OFF'" ng-blur="namespace.publicNamespace.searchStatus='OFF'"
ng-focus="namespace.publicNamespace.searchStatus='ON'"/> ng-focus="namespace.publicNamespace.searchStatus='ON'" />
</div> </div>
</div> </div>
</div> </div>
<!--published items--> <!--published items-->
<div ng-show="!namespace.publicNamespaceViewType || namespace.publicNamespaceViewType == 'RELEASE'"> <div
ng-show="!namespace.publicNamespaceViewType || namespace.publicNamespaceViewType == 'RELEASE'">
<table class="table table-bordered table-striped table-hover" <table class="table table-bordered table-striped table-hover"
ng-show="namespace.publicNamespace.hasPublishedItem"> ng-show="namespace.publicNamespace.hasPublishedItem">
<thead> <thead>
<tr> <tr>
<th class="hover" title="排序" <th class="hover"
title="{{'Component.Namespace.Master.Items.Body.Sort' | translate }}"
ng-click="col='item.key';desc=!desc;"> ng-click="col='item.key';desc=!desc;">
Key&nbsp; {{'Component.Namespace.Master.Items.Body.ItemKey' | translate }}&nbsp;
<span class="glyphicon glyphicon-sort"></span> <span class="glyphicon glyphicon-sort"></span>
</th> </th>
<th> <th>
Value {{'Component.Namespace.Master.Items.Body.ItemValue' | translate }}
</th> </th>
<th> <th>
备注 {{'Component.Namespace.Master.Items.Body.ItemComment' | translate }}
</th> </th>
<th class="hover" title="排序" <th class="hover"
title="{{'Component.Namespace.Master.Items.Body.Sort' | translate }}"
ng-click="col='item.dataChangeLastModifiedBy';desc=!desc;"> ng-click="col='item.dataChangeLastModifiedBy';desc=!desc;">
最后修改人 {{'Component.Namespace.Master.Items.Body.ItemLastModify' | translate }}
<span class="glyphicon glyphicon-sort"></span> <span class="glyphicon glyphicon-sort"></span>
</th> </th>
<th class="hover" title="排序" <th class="hover"
title="{{'Component.Namespace.Master.Items.Body.Sort' | translate }}"
ng-click="col='item.dataChangeLastModifiedTime';desc=!desc;"> ng-click="col='item.dataChangeLastModifiedTime';desc=!desc;">
最后修改时间 {{'Component.Namespace.Master.Items.Body.ItemLastModifyTime' | translate }}
<span class="glyphicon glyphicon-sort"></span> <span class="glyphicon glyphicon-sort"></span>
</th> </th>
<th> <th>
操作 {{'Component.Namespace.Master.Items.Body.ItemOperator' | translate }}
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr ng-repeat="config in namespace.publicNamespace.viewItems |orderBy:col:desc" <tr ng-repeat="config in namespace.publicNamespace.viewItems |orderBy:col:desc"
ng-if="config.item.key && !config.isModified && !config.isDeleted"> ng-if="config.item.key && !config.isModified && !config.isDeleted">
<td width="15%" class="cursor-pointer" title="点击查看" <td width="15%" class="cursor-pointer"
title="{{'Component.Namespace.Master.Items.Body.ClickToSee' | translate }}"
ng-click="showText(config.item.key)"> ng-click="showText(config.item.key)">
<span ng-bind="config.item.key | limitTo: 250"></span> <span ng-bind="config.item.key | limitTo: 250"></span>
<span ng-bind="config.item.key.length > 250 ? '...' :''"></span> <span ng-bind="config.item.key.length > 250 ? '...' :''"></span>
</td> </td>
<td width="35%" class="cursor-pointer" title="点击查看" <td width="35%" class="cursor-pointer"
title="{{'Component.Namespace.Master.Items.Body.ClickToSee' | translate }}"
ng-click="showText(config.item.value)"> ng-click="showText(config.item.value)">
<span ng-bind="config.item.value | limitTo: 250"></span> <span ng-bind="config.item.value | limitTo: 250"></span>
<span ng-bind="config.item.value.length > 250 ? '...': ''"></span> <span ng-bind="config.item.value.length > 250 ? '...': ''"></span>
...@@ -539,7 +557,7 @@ ...@@ -539,7 +557,7 @@
<td width="10%" class="text-center" ng-if="!config.isDeleted"> <td width="10%" class="text-center" ng-if="!config.isDeleted">
<img src="img/gray.png" data-tooltip="tooltip" data-placement="bottom" <img src="img/gray.png" data-tooltip="tooltip" data-placement="bottom"
title="覆盖此配置" title="{{'Component.Namespace.Master.Items.Body.Public.PubishedAndCover' | translate }}"
ng-click="editItem(namespace, config.item)" ng-click="editItem(namespace, config.item)"
ng-show="namespace.hasModifyPermission && !config.covered"> ng-show="namespace.hasModifyPermission && !config.covered">
</td> </td>
...@@ -550,11 +568,10 @@ ...@@ -550,11 +568,10 @@
</tbody> </tbody>
</table> </table>
<div class="text-center no-config-panel" <div class="text-center no-config-panel" ng-if="namespace.publicNamespace.viewItems
ng-if="namespace.publicNamespace.viewItems
&& namespace.publicNamespace.viewItems.length && namespace.publicNamespace.viewItems.length
&& !namespace.publicNamespace.hasPublishedItem"> && !namespace.publicNamespace.hasPublishedItem">
<h5>无发布的配置</h5> <h5>{{'Component.Namespace.Master.Items.Body.Public.NoPublished' | translate }}</h5>
</div> </div>
</div> </div>
...@@ -563,53 +580,61 @@ ...@@ -563,53 +580,61 @@
ng-show="namespace.publicNamespaceViewType == 'NOT_RELEASE'"> ng-show="namespace.publicNamespaceViewType == 'NOT_RELEASE'">
<thead> <thead>
<tr> <tr>
<th class="hover" title="排序" <th class="hover"
title="{{'Component.Namespace.Master.Items.Body.Sort' | translate }}"
ng-click="col='item.key';desc=!desc;"> ng-click="col='item.key';desc=!desc;">
Key&nbsp; {{'Component.Namespace.Master.Items.Body.ItemKey' | translate }}&nbsp;
<span class="glyphicon glyphicon-sort"></span> <span class="glyphicon glyphicon-sort"></span>
</th> </th>
<th> <th>
已发布的值 {{'Component.Namespace.Master.Items.Body.ItemComment' | translate }}
</th> </th>
<th> <th>
未发布的值 {{'Component.Namespace.Master.Items.Body.NoPublished.PublishedValue' | translate }}
</th> </th>
<th> <th>
备注 {{'Component.Namespace.Master.Items.Body.NoPublished.NoPublishedValue' | translate }}
</th> </th>
<th class="hover" title="排序" <th class="hover"
title="{{'Component.Namespace.Master.Items.Body.Sort' | translate }}"
ng-click="col='item.dataChangeLastModifiedTime';desc=!desc;"> ng-click="col='item.dataChangeLastModifiedTime';desc=!desc;">
最后修改时间 {{'Component.Namespace.Master.Items.Body.ItemLastModifyTime' | translate }}
<span class="glyphicon glyphicon-sort"></span> <span class="glyphicon glyphicon-sort"></span>
</th> </th>
<th> <th>
操作 {{'Component.Namespace.Master.Items.Body.ItemOperator' | translate }}
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr ng-repeat="config in namespace.publicNamespace.viewItems |orderBy:col:desc" <tr ng-repeat="config in namespace.publicNamespace.viewItems |orderBy:col:desc"
ng-if="config.item.key && (config.isModified || config.isDeleted)"> ng-if="config.item.key && (config.isModified || config.isDeleted)">
<td width="20%" class="cursor-pointer" title="点击查看" <td width="20%" class="cursor-pointer"
title="{{'Component.Namespace.Master.Items.Body.ClickToSee' | translate }}"
ng-click="showText(config.item.key)"> ng-click="showText(config.item.key)">
<span ng-bind="config.item.key | limitTo: 250"></span> <span ng-bind="config.item.key | limitTo: 250"></span>
<span ng-bind="config.item.key.length > 250 ? '...' :''"></span> <span ng-bind="config.item.key.length > 250 ? '...' :''"></span>
<span class="label label-success" ng-if="config.isModified && !config.oldValue" <span class="label label-success" ng-if="config.isModified && !config.oldValue"
data-tooltip="tooltip" data-placement="bottom" title="新增的配置"></span> data-tooltip="tooltip" data-placement="bottom"
title="{{'Component.Namespace.Master.Items.Body.NewAddedTips' | translate }}">{{'Component.Namespace.Master.Items.Body.NewAdded' | translate }}</span>
<span class="label label-info" <span class="label label-info"
ng-if="config.isModified && config.oldValue && !config.isDeleted" ng-if="config.isModified && config.oldValue && !config.isDeleted"
data-tooltip="tooltip" data-placement="bottom" title="修改的配置"></span> data-tooltip="tooltip" data-placement="bottom"
<span class="label label-danger" ng-if="config.isDeleted" title="{{'Component.Namespace.Master.Items.Body.ModifedTips' | translate }}">{{'Component.Namespace.Master.Items.Body.Modifed' | translate }}</span>
data-tooltip="tooltip" data-placement="bottom" title="删除的配置"></span> <span class="label label-danger" ng-if="config.isDeleted" data-tooltip="tooltip"
</td> data-placement="bottom"
<td width="25%" class="cursor-pointer" title="点击查看" title="{{'Component.Namespace.Master.Items.Body.DeletedTips' | translate }}">{{'Component.Namespace.Master.Items.Body.Deleted' | translate }}</span>
</td>
<td width="25%" class="cursor-pointer"
title="{{'Component.Namespace.Master.Items.Body.ClickToSee' | translate }}"
ng-click="showText(config.oldValue)"> ng-click="showText(config.oldValue)">
<span ng-bind="config.oldValue | limitTo: 250"></span> <span ng-bind="config.oldValue | limitTo: 250"></span>
<span ng-bind="config.oldValue.length > 250 ? '...': ''"></span> <span ng-bind="config.oldValue.length > 250 ? '...': ''"></span>
</td> </td>
<td width="25%" class="cursor-pointer" title="点击查看" <td width="25%" class="cursor-pointer"
title="{{'Component.Namespace.Master.Items.Body.ClickToSee' | translate }}"
ng-click="showText(config.item.value)"> ng-click="showText(config.item.value)">
<span ng-bind="config.item.value | limitTo: 250"></span> <span ng-bind="config.item.value | limitTo: 250"></span>
<span ng-bind="config.item.value.length > 250 ? '...': ''"></span> <span ng-bind="config.item.value.length > 250 ? '...': ''"></span>
...@@ -623,7 +648,8 @@ ...@@ -623,7 +648,8 @@
</td> </td>
<td width="5%" class="text-center" ng-if="!config.isDeleted"> <td width="5%" class="text-center" ng-if="!config.isDeleted">
<img src="img/gray.png" data-tooltip="tooltip" data-placement="bottom" title="覆盖此配置" <img src="img/gray.png" data-tooltip="tooltip" data-placement="bottom"
title="{{'Component.Namespace.Master.Items.Body.Public.PubishedAndCover' | translate }}"
ng-click="editItem(namespace, config.item)" ng-click="editItem(namespace, config.item)"
ng-show="namespace.hasModifyPermission && !config.covered"> ng-show="namespace.hasModifyPermission && !config.covered">
</td> </td>
...@@ -633,17 +659,18 @@ ...@@ -633,17 +659,18 @@
</table> </table>
<div class="text-center no-config-panel" <div class="text-center no-config-panel"
ng-if="!namespace.publicNamespace.viewItems || !namespace.publicNamespace.viewItems.length"> ng-if="!namespace.publicNamespace.viewItems || !namespace.publicNamespace.viewItems.length">
<h5>无公共的配置</h5> <h5>{{'Component.Namespace.Master.Items.Body.NoPublished.Title' | translate }}</h5>
</div> </div>
</div> </div>
<div class="panel panel-default" ng-if="!namespace.publicNamespace"> <div class="panel panel-default" ng-if="!namespace.publicNamespace">
<div class="panel-heading"> <div class="panel-heading">
公共的配置 {{'Component.Namespace.Master.Items.Body.Public.Title' | translate }}
</div> </div>
<div class="panel-body text-center"> <div class="panel-body text-center">
当前公共namespace的所有者 {{'Component.Namespace.Master.Items.Body.Public.NoPublicNamespaceTips1' | translate }}
<a href="/config.html?#/appid={{namespace.parentAppId}}" target="_blank">{{namespace.parentAppId}}</a> <a href="/config.html?#/appid={{namespace.parentAppId}}"
没有关联此namespace,请联系{{namespace.parentAppId}}的所有者在{{namespace.parentAppId}}项目里关联此namespace target="_blank">{{namespace.parentAppId}}</a>
{{'Component.Namespace.Master.Items.Body.Public.NoPublicNamespaceTips2' | translate:this }}
</div> </div>
</div> </div>
</div> </div>
...@@ -652,31 +679,28 @@ ...@@ -652,31 +679,28 @@
<!--text view--> <!--text view-->
<!--只读模式下的文本内容,不替换换行符--> <!--只读模式下的文本内容,不替换换行符-->
<div ui-ace="aceConfig" readonly="true" <div ui-ace="aceConfig" readonly="true" class="form-control no-radius"
class="form-control no-radius"
rows="{{namespace.itemCnt < 10 ? 10: namespace.itemCnt>20 ? 20:namespace.itemCnt}}" rows="{{namespace.itemCnt < 10 ? 10: namespace.itemCnt>20 ? 20:namespace.itemCnt}}"
ng-show="namespace.viewType == 'text' && !namespace.isTextEditing" ng-show="namespace.viewType == 'text' && !namespace.isTextEditing" ng-model="namespace.text">
ng-model="namespace.text">
</div> </div>
<!--编辑状态下的文本内容,会过滤掉换行符--> <!--编辑状态下的文本内容,会过滤掉换行符-->
<div ui-ace="aceConfig" <div ui-ace="aceConfig" class="form-control no-radius"
class="form-control no-radius"
rows="{{namespace.itemCnt < 10 ? 10: namespace.itemCnt>20 ? 20:namespace.itemCnt}}" rows="{{namespace.itemCnt < 10 ? 10: namespace.itemCnt>20 ? 20:namespace.itemCnt}}"
ng-show="namespace.viewType == 'text' && namespace.isTextEditing" ng-show="namespace.viewType == 'text' && namespace.isTextEditing" ng-disabled="!namespace.isTextEditing"
ng-disabled="!namespace.isTextEditing" ng-model="namespace.editText"> ng-model="namespace.editText">
</div> </div>
<!--history view--> <!--history view-->
<div class="J_historyview history-view" ng-show="namespace.viewType == 'history'"> <div class="J_historyview history-view" ng-show="namespace.viewType == 'history'">
<div class="media" <div class="media" ng-show="namespace.commits && namespace.commits.length"
ng-show="namespace.commits && namespace.commits.length"
ng-repeat="commits in namespace.commits"> ng-repeat="commits in namespace.commits">
<div class="media-body"> <div class="media-body">
<div class="row"> <div class="row">
<div class="col-md-6 col-sm-6"><h3 class="media-heading" <div class="col-md-6 col-sm-6">
ng-bind="commits.dataChangeCreatedBy"></h3> <h3 class="media-heading" ng-bind="commits.dataChangeCreatedBy"></h3>
</div> </div>
<div class="col-md-6 col-sm-6 text-right"><h5 class="media-heading" <div class="col-md-6 col-sm-6 text-right">
<h5 class="media-heading"
ng-bind="commits.dataChangeCreatedTime | date: 'yyyy-MM-dd HH:mm:ss'"></h5> ng-bind="commits.dataChangeCreatedTime | date: 'yyyy-MM-dd HH:mm:ss'"></h5>
</div> </div>
</div> </div>
...@@ -684,24 +708,23 @@ ...@@ -684,24 +708,23 @@
<!--properties format--> <!--properties format-->
<table class="table table-bordered table-striped text-center table-hover" <table class="table table-bordered table-striped text-center table-hover"
style="margin-top: 5px;" style="margin-top: 5px;" ng-if="namespace.isPropertiesFormat">
ng-if="namespace.isPropertiesFormat">
<thead> <thead>
<tr> <tr>
<th> <th>
Type {{'Component.Namespace.Master.Items.Body.HistoryView.ItemType | translate }}
</th> </th>
<th> <th>
Key {{'Component.Namespace.Master.Items.Body.HistoryView.ItemKey | translate }}
</th> </th>
<th> <th>
Old Value {{'Component.Namespace.Master.Items.Body.HistoryView.ItemOldValue | translate }}
</th> </th>
<th> <th>
New Value {{'Component.Namespace.Master.Items.Body.HistoryView.ItemNewValue | translate }}
</th> </th>
<th> <th>
Comment {{'Component.Namespace.Master.Items.Body.HistoryView.ItemComment | translate }}
</th> </th>
</tr> </tr>
</thead> </thead>
...@@ -710,7 +733,7 @@ ...@@ -710,7 +733,7 @@
<!--兼容老数据,不显示item类型为空行和注释的item--> <!--兼容老数据,不显示item类型为空行和注释的item-->
<tr ng-repeat="item in commits.changeSets.createItems" ng-show="item.key"> <tr ng-repeat="item in commits.changeSets.createItems" ng-show="item.key">
<td width="2%"> <td width="2%">
新增 {{'Component.Namespace.Master.Items.Body.HistoryView.NewAdded | translate }}
</td> </td>
<td width="20%" title="{{item.key}}"> <td width="20%" title="{{item.key}}">
...@@ -731,7 +754,7 @@ ...@@ -731,7 +754,7 @@
</tr> </tr>
<tr ng-repeat="item in commits.changeSets.updateItems"> <tr ng-repeat="item in commits.changeSets.updateItems">
<td width="2%"> <td width="2%">
更新 {{'Component.Namespace.Master.Items.Body.HistoryView.Updated | translate }}
</td> </td>
<td width="20%" title="{{item.newItem.key}}"> <td width="20%" title="{{item.newItem.key}}">
<span ng-bind="item.newItem.key | limitTo: 250"></span> <span ng-bind="item.newItem.key | limitTo: 250"></span>
...@@ -755,7 +778,7 @@ ...@@ -755,7 +778,7 @@
<tr ng-repeat="item in commits.changeSets.deleteItems" <tr ng-repeat="item in commits.changeSets.deleteItems"
ng-show="item.key || item.comment"> ng-show="item.key || item.comment">
<td width="2%"> <td width="2%">
删除 {{'Component.Namespace.Master.Items.Body.HistoryView.Deleted | translate }}
</td> </td>
<td width="20%" title="{{item.key}}"> <td width="20%" title="{{item.key}}">
<span ng-bind="item.key | limitTo: 250"></span> <span ng-bind="item.key | limitTo: 250"></span>
...@@ -778,14 +801,14 @@ ...@@ -778,14 +801,14 @@
<!--not properties format--> <!--not properties format-->
<div ng-if="!namespace.isPropertiesFormat"> <div ng-if="!namespace.isPropertiesFormat">
<div ng-repeat="item in commits.changeSets.createItems"> <div ng-repeat="item in commits.changeSets.createItems">
<textarea class="form-control no-radius" rows="20" <textarea class="form-control no-radius" rows="20" ng-disabled="true"
ng-disabled="true" ng-bind="item.value"> ng-bind="item.value">
</textarea> </textarea>
</div> </div>
<div ng-repeat="item in commits.changeSets.updateItems"> <div ng-repeat="item in commits.changeSets.updateItems">
<textarea class="form-control no-radius" rows="20" <textarea class="form-control no-radius" rows="20" ng-disabled="true"
ng-disabled="true" ng-bind="item.newItem.value"> ng-bind="item.newItem.value">
</textarea> </textarea>
</div> </div>
</div> </div>
...@@ -796,11 +819,11 @@ ...@@ -796,11 +819,11 @@
</div> </div>
<div class="text-center"> <div class="text-center">
<button type="button" class="btn btn-default" ng-show="!namespace.hasLoadAllCommit" <button type="button" class="btn btn-default" ng-show="!namespace.hasLoadAllCommit"
ng-click="loadCommitHistory(namespace)">加载更多 ng-click="loadCommitHistory(namespace)">{{'Component.Namespace.Master.Items.Body.HistoryView.LoadingMore' | translate }}
<span class="glyphicon glyphicon-menu-down"></span></button> <span class="glyphicon glyphicon-menu-down"></span></button>
</div> </div>
<div class="empty-container text-center" ng-show="!namespace.commits || !namespace.commits.length"> <div class="empty-container text-center" ng-show="!namespace.commits || !namespace.commits.length">
无更改历史 {{'Component.Namespace.Master.Items.Body.HistoryView.NoHistory' | translate }}
</div> </div>
</div> </div>
<!--instance view--> <!--instance view-->
...@@ -809,31 +832,32 @@ ...@@ -809,31 +832,32 @@
<div class="row"> <div class="row">
<div class="col-md-5 col-sm-5"> <div class="col-md-5 col-sm-5">
<small>实例说明:只展示最近一天访问过Apollo的实例</small> <small>{{'Component.Namespace.Master.Items.Body.Instance.Tips' | translate }}</small>
</div> </div>
<div class="col-md-7 col-sm-7 text-right"> <div class="col-md-7 col-sm-7 text-right">
<div class="btn-group btn-group-sm" role="group"> <div class="btn-group btn-group-sm" role="group">
<button type="button" class="btn btn-default" <button type="button" class="btn btn-default"
ng-class="{'btn-primary':namespace.instanceViewType == 'latest_release'}" ng-class="{'btn-primary':namespace.instanceViewType == 'latest_release'}"
ng-click="switchInstanceViewType(namespace, 'latest_release')"> 使用最新配置的实例 ng-click="switchInstanceViewType(namespace, 'latest_release')">
{{'Component.Namespace.Master.Items.Body.Instance.UsedNewItem' | translate }}
<span class="badge" ng-bind="namespace.latestReleaseInstances.total"></span> <span class="badge" ng-bind="namespace.latestReleaseInstances.total"></span>
</button> </button>
<button type="button" class="btn btn-default" <button type="button" class="btn btn-default"
ng-class="{'btn-primary':namespace.instanceViewType == 'not_latest_release'}" ng-class="{'btn-primary':namespace.instanceViewType == 'not_latest_release'}"
ng-click="switchInstanceViewType(namespace, 'not_latest_release')">使用非最新配置的实例 ng-click="switchInstanceViewType(namespace, 'not_latest_release')">{{'Component.Namespace.Master.Items.Body.Instance.NoUsedNewItem' | translate }}
<span class="badge" <span class="badge"
ng-bind="namespace.instancesCount - namespace.latestReleaseInstances.total"></span> ng-bind="namespace.instancesCount - namespace.latestReleaseInstances.total"></span>
</button> </button>
<button type="button" class="btn btn-default" <button type="button" class="btn btn-default"
ng-class="{'btn-primary':namespace.instanceViewType == 'all'}" ng-class="{'btn-primary':namespace.instanceViewType == 'all'}"
ng-click="switchInstanceViewType(namespace, 'all')">所有实例 ng-click="switchInstanceViewType(namespace, 'all')">{{'Component.Namespace.Master.Items.Body.Instance.AllInstance' | translate }}
<span class="badge" ng-bind="namespace.instancesCount"></span> <span class="badge" ng-bind="namespace.instancesCount"></span>
</button> </button>
</div> </div>
<button class="btn btn-default btn-sm" <button class="btn btn-default btn-sm" data-tooltip="tooltip" data-placement="bottom"
data-tooltip="tooltip" data-placement="bottom" title="刷新列表" title="{{'Component.Namespace.Master.Items.Body.Instance.RefreshList' | translate }}"
ng-click="refreshInstancesInfo(namespace)"> ng-click="refreshInstancesInfo(namespace)">
<img src="../../img/refresh.png"/> <img src="../../img/refresh.png" />
</button> </button>
</div> </div>
...@@ -845,7 +869,8 @@ ...@@ -845,7 +869,8 @@
<div class="panel-default" ng-if="namespace.latestReleaseInstances.total > 0"> <div class="panel-default" ng-if="namespace.latestReleaseInstances.total > 0">
<div class="panel-heading"> <div class="panel-heading">
<a target="_blank" data-tooltip="tooltip" data-placement="bottom" title="查看配置" <a target="_blank" data-tooltip="tooltip" data-placement="bottom"
title="{{'Component.Namespace.Master.Items.Body.Instance.ToSeeItem' | translate }}"
href="/config/history.html?#/appid={{appId}}&env={{env}}&clusterName={{cluster}}&namespaceName={{namespace.baseInfo.namespaceName}}&releaseId={{namespace.latestRelease.id}}"> href="/config/history.html?#/appid={{appId}}&env={{env}}&clusterName={{cluster}}&namespaceName={{namespace.baseInfo.namespaceName}}&releaseId={{namespace.latestRelease.id}}">
{{namespace.latestRelease.name}} {{namespace.latestRelease.name}}
</a> </a>
...@@ -853,11 +878,14 @@ ...@@ -853,11 +878,14 @@
<table class="table table-bordered table-striped"> <table class="table table-bordered table-striped">
<thead> <thead>
<tr> <tr>
<td>App ID</td> <td>{{'Component.Namespace.Master.Items.Body.Instance.ItemAppId' | translate }}</td>
<td>Cluster Name</td> <td>{{'Component.Namespace.Master.Items.Body.Instance.ItemCluster' | translate }}
<td>Data Center</td> </td>
<td>IP</td> <td>{{'Component.Namespace.Master.Items.Body.Instance.ItemDataCenter' | translate }}
<td>配置获取时间</td> </td>
<td>{{'Component.Namespace.Master.Items.Body.Instance.ItemIp' | translate }}</td>
<td>{{'Component.Namespace.Master.Items.Body.Instance.ItemGetTime' | translate }}
</td>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
...@@ -874,13 +902,14 @@ ...@@ -874,13 +902,14 @@
</table> </table>
<div class="row text-center" <div class="row text-center"
ng-show="namespace.latestReleaseInstances.content.length < namespace.latestReleaseInstances.total"> ng-show="namespace.latestReleaseInstances.content.length < namespace.latestReleaseInstances.total">
<button class="btn btn-default" ng-click="loadInstanceInfo(namespace)">加载更多</button> <button class="btn btn-default"
ng-click="loadInstanceInfo(namespace)">{{'Component.Namespace.Master.Items.Body.Instance.LoadingMore' | translate }}</button>
</div> </div>
</div> </div>
<div class="text-center" ng-if="namespace.latestReleaseInstances.total == 0"> <div class="text-center" ng-if="namespace.latestReleaseInstances.total == 0">
无实例信息 {{'Component.Namespace.Master.Items.Body.Instance.NoInstanceTips' | translate }}
</div> </div>
</div> </div>
...@@ -890,7 +919,8 @@ ...@@ -890,7 +919,8 @@
ng-if="namespace.instancesCount - namespace.latestReleaseInstances.total > 0" ng-if="namespace.instancesCount - namespace.latestReleaseInstances.total > 0"
ng-repeat="release in namespace.notLatestReleases"> ng-repeat="release in namespace.notLatestReleases">
<div class="panel-heading"> <div class="panel-heading">
<a target="_blank" data-tooltip="tooltip" data-placement="bottom" title="查看配置" <a target="_blank" data-tooltip="tooltip" data-placement="bottom"
title="{{'Component.Namespace.Master.Items.Body.Instance.ToSeeItem' | translate }}"
href="/config/history.html?#/appid={{appId}}&env={{env}}&clusterName={{cluster}}&namespaceName={{namespace.baseInfo.namespaceName}}&releaseId={{release.id}}"> href="/config/history.html?#/appid={{appId}}&env={{env}}&clusterName={{cluster}}&namespaceName={{namespace.baseInfo.namespaceName}}&releaseId={{release.id}}">
{{release.name}} {{release.name}}
</a> </a>
...@@ -899,11 +929,14 @@ ...@@ -899,11 +929,14 @@
<table class="table table-bordered table-striped"> <table class="table table-bordered table-striped">
<thead> <thead>
<tr> <tr>
<td>App ID</td> <td>{{'Component.Namespace.Master.Items.Body.Instance.ItemAppId' | translate }}</td>
<td>Cluster Name</td> <td>{{'Component.Namespace.Master.Items.Body.Instance.ItemCluster' | translate }}
<td>Data Center</td> </td>
<td>IP</td> <td>{{'Component.Namespace.Master.Items.Body.Instance.ItemDataCenter' | translate }}
<td>配置获取时间</td> </td>
<td>{{'Component.Namespace.Master.Items.Body.Instance.ItemIp' | translate }}</td>
<td>{{'Component.Namespace.Master.Items.Body.Instance.ItemGetTime' | translate }}
</td>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
...@@ -921,7 +954,7 @@ ...@@ -921,7 +954,7 @@
</div> </div>
<div class="text-center" <div class="text-center"
ng-if="namespace.instancesCount - namespace.latestReleaseInstances.total == 0"> ng-if="namespace.instancesCount - namespace.latestReleaseInstances.total == 0">
无实例信息 {{'Component.Namespace.Master.Items.Body.Instance.NoInstanceTips' | translate }}
</div> </div>
</div> </div>
...@@ -931,10 +964,12 @@ ...@@ -931,10 +964,12 @@
<table class="table table-bordered table-striped" ng-if="namespace.allInstances"> <table class="table table-bordered table-striped" ng-if="namespace.allInstances">
<thead> <thead>
<tr> <tr>
<td>App ID</td> <td>{{'Component.Namespace.Master.Items.Body.Instance.ItemAppId' | translate }}</td>
<td>Cluster Name</td> <td>{{'Component.Namespace.Master.Items.Body.Instance.ItemCluster' | translate }}
<td>Data Center</td> </td>
<td>IP</td> <td>{{'Component.Namespace.Master.Items.Body.Instance.ItemDataCenter' | translate }}
</td>
<td>{{'Component.Namespace.Master.Items.Body.Instance.ItemIp' | translate }}</td>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
...@@ -947,11 +982,12 @@ ...@@ -947,11 +982,12 @@
</tbody> </tbody>
</table> </table>
<div class="row text-center" ng-show="namespace.allInstances.length < namespace.instancesCount"> <div class="row text-center" ng-show="namespace.allInstances.length < namespace.instancesCount">
<button class="btn btn-default" ng-click="loadInstanceInfo(namespace)">加载更多</button> <button class="btn btn-default"
ng-click="loadInstanceInfo(namespace)">{{'Component.Namespace.Master.Items.Body.Instance.LoadingMore' | translate }}</button>
</div> </div>
</div> </div>
<div class="text-center" ng-if="namespace.instancesCount == 0"> <div class="text-center" ng-if="namespace.instancesCount == 0">
无实例信息 {{'Component.Namespace.Master.Items.Body.Instance.NoInstanceTips' | translate }}
</div> </div>
</div> </div>
</div> </div>
......
...@@ -4,23 +4,21 @@ ...@@ -4,23 +4,21 @@
<div class="modal-header panel-primary"> <div class="modal-header panel-primary">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"> <button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span></button> <span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">发布受限</h4> <h4 class="modal-title">{{'Component.PublishDeny.Title' | translate }}</h4>
</div> </div>
<div class="modal-body"> <div class="modal-body">{{'Component.PublishDeny.Tips1' | translate:this }}
您不能发布哟~{{env}}环境配置的编辑和发布必须为不同的人,请找另一个具有当前namespace发布权的人操作发布~
<span ng-if="toReleaseNamespace.isEmergencyPublishAllowed"> <span ng-if="toReleaseNamespace.isEmergencyPublishAllowed">
<br><br><small>(如果是非工作时间或者特殊情况,您可以通过点击<mark>紧急发布</mark>按钮进行发布)</small> <br><br><small>{{'Component.PublishDeny.Tips2' | translate }}</small>
</span> </span>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal" <button type="button" class="btn btn-danger" data-dismiss="modal"
ng-if="toReleaseNamespace.isEmergencyPublishAllowed" ng-if="toReleaseNamespace.isEmergencyPublishAllowed" ng-click="emergencyPublish()">
ng-click="emergencyPublish()"> {{'Component.PublishDeny.EmergencyPublish' | translate }}
紧急发布
</button> </button>
<button type="button" class="btn btn-primary" data-dismiss="modal"> <button type="button" class="btn btn-primary" data-dismiss="modal">
关闭 {{'Component.PublishDeny.Close' | translate }}
</button> </button>
</div> </div>
</div> </div>
......
...@@ -5,16 +5,17 @@ ...@@ -5,16 +5,17 @@
<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" ng-show="!toReleaseNamespace.isBranch">发布 <h4 class="modal-title" ng-show="!toReleaseNamespace.isBranch">
<small>(只有发布过的配置才会被客户端获取到,此次发布只会作用于当前环境:{{env}})</small> {{'Component.Publish.Title' | translate }}
<small>{{'Component.Publish.Tips' | translate:this }}</small>
</h4> </h4>
<h4 class="modal-title" ng-show="toReleaseNamespace.isBranch && !toReleaseNamespace.mergeAndPublish"> <h4 class="modal-title" ng-show="toReleaseNamespace.isBranch && !toReleaseNamespace.mergeAndPublish">
灰度发布 {{'Component.Publish.Grayscale' | translate }}
<small>(灰度发布的配置只会作用于在灰度规则中配置的实例)</small> <small>{{'Component.Publish.GrayscaleTips' | translate }}</small>
</h4> </h4>
<h4 class="modal-title" ng-show="toReleaseNamespace.isBranch && toReleaseNamespace.mergeAndPublish"> <h4 class="modal-title" ng-show="toReleaseNamespace.isBranch && toReleaseNamespace.mergeAndPublish">
全量发布 {{'Component.Publish.AllPublish' | translate }}
<small>(全量发布的配置会作用于全部的实例)</small> <small>{{'Component.Publish.AllPublishTips' | translate }}</small>
</h4> </h4>
</div> </div>
...@@ -27,16 +28,17 @@ ...@@ -27,16 +28,17 @@
<div class="btn-group btn-group-xs" style="padding-right: 10px" role="group"> <div class="btn-group btn-group-xs" style="padding-right: 10px" role="group">
<button type="button" class="btn btn-default" <button type="button" class="btn btn-default"
ng-class="{active:releaseChangeViewType=='change'}" ng-class="{active:releaseChangeViewType=='change'}"
ng-click="switchReleaseChangeViewType('change')">查看变更 ng-click="switchReleaseChangeViewType('change')">{{'Component.Publish.ToSeeChange' | translate }}
</button> </button>
<button type="button" class="btn btn-default" <button type="button" class="btn btn-default"
ng-class="{active:releaseChangeViewType=='release'}" ng-class="{active:releaseChangeViewType=='release'}"
ng-click="switchReleaseChangeViewType('release')">发布的值 ng-click="switchReleaseChangeViewType('release')">{{'Component.Publish.PublishedValue' | translate }}
</button> </button>
</div> </div>
</div> </div>
</div> </div>
<label class="col-sm-2 control-label" ng-if="toReleaseNamespace.isPropertiesFormat">Changes</label> <label class="col-sm-2 control-label"
ng-if="toReleaseNamespace.isPropertiesFormat">{{'Component.Publish.Changes' | translate }}</label>
<div class="col-sm-10" <div class="col-sm-10"
ng-if="(!toReleaseNamespace.isBranch && toReleaseNamespace.itemModifiedCnt) ng-if="(!toReleaseNamespace.isBranch && toReleaseNamespace.itemModifiedCnt)
...@@ -51,19 +53,19 @@ ...@@ -51,19 +53,19 @@
<thead> <thead>
<tr> <tr>
<th> <th>
Key {{'Component.Publish.Key' | translate }}
</th> </th>
<th> <th>
发布的值 {{'Component.Publish.PublishedValue' | translate }}
</th> </th>
<th> <th>
未发布的值 {{'Component.Publish.NoPublishedValue' | translate }}
</th> </th>
<th> <th>
修改人 {{'Component.Publish.ModifyUser' | translate }}
</th> </th>
<th> <th>
修改时间 {{'Component.Publish.ModifyTime' | translate }}
</th> </th>
</tr> </tr>
</thead> </thead>
...@@ -73,12 +75,15 @@ ...@@ -73,12 +75,15 @@
<td width="20%" title="{{config.item.key}}"> <td width="20%" title="{{config.item.key}}">
<span ng-bind="config.item.key"></span> <span ng-bind="config.item.key"></span>
<span class="label label-success" ng-if="config.isModified && !config.oldValue" <span class="label label-success" ng-if="config.isModified && !config.oldValue"
data-tooltip="tooltip" data-placement="bottom" title="新增的配置"></span> data-tooltip="tooltip" data-placement="bottom"
title="{{'Component.Publish.NewAddedTips' | translate }}">{{'Component.Publish.NewAdded' | translate }}</span>
<span class="label label-info" <span class="label label-info"
ng-if="config.isModified && config.oldValue && !config.isDeleted" ng-if="config.isModified && config.oldValue && !config.isDeleted"
data-tooltip="tooltip" data-placement="bottom" title="修改的配置"></span> data-tooltip="tooltip" data-placement="bottom"
<span class="label label-danger" ng-if="config.isDeleted" title="{{'Component.Publish.ModifedTips' | translate }}">{{'Component.Publish.Modifed' | translate }}</span>
data-tooltip="tooltip" data-placement="bottom" title="删除的配置"></span> <span class="label label-danger" ng-if="config.isDeleted" data-tooltip="tooltip"
data-placement="bottom"
title="{{'Component.Publish.DeletedTips' | translate }}">{{'Component.Publish.Deleted' | translate }}</span>
</td> </td>
<td width="25%" title="{{config.oldValue}}"> <td width="25%" title="{{config.oldValue}}">
<span ng-bind="config.oldValue"></span> <span ng-bind="config.oldValue"></span>
...@@ -96,28 +101,27 @@ ...@@ -96,28 +101,27 @@
</table> </table>
<!--branch gray release--> <!--branch gray release-->
<table class="table table-bordered table-striped text-center table-hover" <table class="table table-bordered table-striped text-center table-hover" ng-if="toReleaseNamespace.isPropertiesFormat &&
ng-if="toReleaseNamespace.isPropertiesFormat &&
toReleaseNamespace.isBranch && !toReleaseNamespace.mergeAndPublish"> toReleaseNamespace.isBranch && !toReleaseNamespace.mergeAndPublish">
<thead> <thead>
<tr> <tr>
<th> <th>
Key {{'Component.Publish.Key' | translate }}
</th> </th>
<th> <th>
主版本值 {{'Component.Publish.MasterValue' | translate }}
</th> </th>
<th> <th>
灰度版本发布的值 {{'Component.Publish.GrayPublishedValue' | translate }}
</th> </th>
<th> <th>
灰度版本未发布的值 {{'Component.Publish.GrayNoPublishedValue' | translate }}
</th> </th>
<th> <th>
修改人 {{'Component.Publish.ModifyUser' | translate }}
</th> </th>
<th> <th>
修改时间 {{'Component.Publish.ModifyTime' | translate }}
</th> </th>
</tr> </tr>
</thead> </thead>
...@@ -127,7 +131,7 @@ ...@@ -127,7 +131,7 @@
<td width="15%" title="{{config.item.key}}"> <td width="15%" title="{{config.item.key}}">
<span ng-bind="config.item.key"></span> <span ng-bind="config.item.key"></span>
<span class="label label-danger" <span class="label label-danger"
ng-show="config.isDeleted"></span> ng-show="config.isDeleted">{{'Component.Publish.Deleted' | translate }}</span>
</td> </td>
<td width="20%" title="{{config.masterReleaseValue}}"> <td width="20%" title="{{config.masterReleaseValue}}">
<span ng-bind="config.masterReleaseValue"></span> <span ng-bind="config.masterReleaseValue"></span>
...@@ -148,37 +152,35 @@ ...@@ -148,37 +152,35 @@
</table> </table>
<!--branch updateAndPublish and publish--> <!--branch updateAndPublish and publish-->
<table class="table table-bordered table-striped text-center table-hover" <table class="table table-bordered table-striped text-center table-hover" ng-if="toReleaseNamespace.isPropertiesFormat &&
ng-if="toReleaseNamespace.isPropertiesFormat &&
toReleaseNamespace.isBranch && toReleaseNamespace.mergeAndPublish"> toReleaseNamespace.isBranch && toReleaseNamespace.mergeAndPublish">
<thead> <thead>
<tr> <tr>
<th> <th>
Key {{'Component.Publish.Key' | translate }}
</th> </th>
<th ng-if="toReleaseNamespace.isBranch"> <th ng-if="toReleaseNamespace.isBranch">
主版本值 {{'Component.Publish.MasterValue' | translate }}
</th> </th>
<th ng-if="toReleaseNamespace.isBranch && toReleaseNamespace.mergeAndPublish"> <th ng-if="toReleaseNamespace.isBranch && toReleaseNamespace.mergeAndPublish">
灰度版本的值 {{'Component.Publish.GrayValue' | translate }}
</th> </th>
<th ng-if="!toReleaseNamespace.isBranch || !toReleaseNamespace.mergeAndPublish"> <th ng-if="!toReleaseNamespace.isBranch || !toReleaseNamespace.mergeAndPublish">
发布的值 {{'Component.Publish.PublishedValue' | translate }}
</th> </th>
<th ng-if="!toReleaseNamespace.isBranch || !toReleaseNamespace.mergeAndPublish"> <th ng-if="!toReleaseNamespace.isBranch || !toReleaseNamespace.mergeAndPublish">
未发布的值 {{'Component.Publish.NoPublishedValue' | translate }}
</th> </th>
<th> <th>
修改人 {{'Component.Publish.ModifyUser' | translate }}
</th> </th>
<th> <th>
修改时间 {{'Component.Publish.ModifyTime' | translate }}
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr ng-repeat="config in toReleaseNamespace.branchItems" <tr ng-repeat="config in toReleaseNamespace.branchItems" ng-if="!config.isDeleted">
ng-if="!config.isDeleted">
<td width="20%" title="{{config.item.key}}"> <td width="20%" title="{{config.item.key}}">
<span ng-bind="config.item.key"></span> <span ng-bind="config.item.key"></span>
</td> </td>
...@@ -198,17 +200,15 @@ ...@@ -198,17 +200,15 @@
</table> </table>
<!--file format --> <!--file format -->
<div ng-repeat="item in toReleaseNamespace.items" <div ng-repeat="item in toReleaseNamespace.items" ng-if="!toReleaseNamespace.isPropertiesFormat"
ng-if="!toReleaseNamespace.isPropertiesFormat"
ng-show="releaseChangeViewType=='change'"> ng-show="releaseChangeViewType=='change'">
<apollodiff old-str="item.oldValue" new-str="item.newValue" <apollodiff old-str="item.oldValue" new-str="item.newValue" apollo-id="'releaseStrDiff'">
apollo-id="'releaseStrDiff'"></apollodiff> </apollodiff>
</div> </div>
<div ng-repeat="item in toReleaseNamespace.items" <div ng-repeat="item in toReleaseNamespace.items" ng-if="!toReleaseNamespace.isPropertiesFormat"
ng-if="!toReleaseNamespace.isPropertiesFormat"
ng-show="releaseChangeViewType=='release'"> ng-show="releaseChangeViewType=='release'">
<textarea class="form-control no-radius" rows="20" <textarea class="form-control no-radius" rows="20" ng-disabled="true"
ng-disabled="true" ng-show="item.newValue" ng-bind="item.newValue"> ng-show="item.newValue" ng-bind="item.newValue">
</textarea> </textarea>
</div> </div>
...@@ -217,21 +217,21 @@ ...@@ -217,21 +217,21 @@
ng-show="(!toReleaseNamespace.isBranch && !toReleaseNamespace.itemModifiedCnt)" ng-show="(!toReleaseNamespace.isBranch && !toReleaseNamespace.itemModifiedCnt)"
valdr-form-group> valdr-form-group>
<label class="form-control-static"> <label class="form-control-static">
配置没有变化 {{'Component.Publish.ItemNoChange' | translate }}
</label> </label>
</div> </div>
<div class="col-sm-5" <div class="col-sm-5"
ng-show="(toReleaseNamespace.isBranch && !toReleaseNamespace.mergeAndPublish && !toReleaseNamespace.itemModifiedCnt)" ng-show="(toReleaseNamespace.isBranch && !toReleaseNamespace.mergeAndPublish && !toReleaseNamespace.itemModifiedCnt)"
valdr-form-group> valdr-form-group>
<label class="form-control-static"> <label class="form-control-static">
灰度配置没有变化 {{'Component.Publish.GrayItemNoChange' | translate }}
</label> </label>
</div> </div>
<div class="col-sm-5" <div class="col-sm-5"
ng-show="(toReleaseNamespace.isBranch && toReleaseNamespace.mergeAndPublish && toReleaseNamespace.branchItems.length == 0)" ng-show="(toReleaseNamespace.isBranch && toReleaseNamespace.mergeAndPublish && toReleaseNamespace.branchItems.length == 0)"
valdr-form-group> valdr-form-group>
<label class="form-control-static"> <label class="form-control-static">
没有灰度的配置项 {{'Component.Publish.NoGrayItems' | translate }}
</label> </label>
</div> </div>
...@@ -239,20 +239,18 @@ ...@@ -239,20 +239,18 @@
<div class="form-group"> <div class="form-group">
<label class="col-sm-2 control-label"> <label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield> <apollorequiredfield></apollorequiredfield>
Release Name</label> {{'Component.Publish.Release' | translate }}
</label>
<div class="col-sm-5" valdr-form-group> <div class="col-sm-5" valdr-form-group>
<input type="text" name="releaseName" class="form-control" <input type="text" name="releaseName" class="form-control" placeholder="input release name"
placeholder="input release name"
ng-model="toReleaseNamespace.releaseTitle" ng-required="true"> ng-model="toReleaseNamespace.releaseTitle" ng-required="true">
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-2 control-label">Comment</label> <label class="col-sm-2 control-label">{{'Component.Publish.ReleaseComment' | translate }}</label>
<div class="col-sm-10" valdr-form-group> <div class="col-sm-10" valdr-form-group>
<textarea rows="4" name="comment" class="form-control" <textarea rows="4" name="comment" class="form-control" style="margin-top: 15px;"
style="margin-top: 15px;" ng-model="releaseComment" placeholder="Add an optional extended description..."></textarea>
ng-model="releaseComment"
placeholder="Add an optional extended description..."></textarea>
</div> </div>
</div> </div>
...@@ -260,16 +258,14 @@ ...@@ -260,16 +258,14 @@
</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">{{'Common.Cancel' | translate }}</button>
<button type="submit" class="btn btn-primary" <button type="submit" class="btn btn-primary"
ng-disabled="releaseForm.$invalid || releaseBtnDisabled ng-disabled="releaseForm.$invalid || releaseBtnDisabled
|| (toReleaseNamespace.isBranch && toReleaseNamespace.mergeAndPublish && toReleaseNamespace.branchItems.length == 0)"> || (toReleaseNamespace.isBranch && toReleaseNamespace.mergeAndPublish && toReleaseNamespace.branchItems.length == 0)">
发布 {{'Component.Publish.OpPublish' | translate }}
</button> </button>
</div> </div>
</div> </div>
</div> </div>
</form> </form>
\ No newline at end of file
<form id="rollbackModal" class="modal fade form-horizontal" <form id="rollbackModal" class="modal fade form-horizontal" ng-submit="showRollbackAlertDialog()">
ng-submit="showRollbackAlertDialog()">
<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">
...@@ -7,13 +6,13 @@ ...@@ -7,13 +6,13 @@
aria-hidden="true">&times;</span></button> aria-hidden="true">&times;</span></button>
<div class="modal-title text-center"> <div class="modal-title text-center">
<span style="font-size: 18px;" ng-bind="toRollbackNamespace.firstRelease.name"></span> <span style="font-size: 18px;" ng-bind="toRollbackNamespace.firstRelease.name"></span>
<span style="font-size: 18px;"> &nbsp;回滚到&nbsp;</span> <span style="font-size: 18px;"> &nbsp;{{'Component.Rollback.Goto' | translate }}&nbsp;</span>
<span style="font-size: 18px;" ng-bind="toRollbackNamespace.secondRelease.name"></span> <span style="font-size: 18px;" ng-bind="toRollbackNamespace.secondRelease.name"></span>
</div> </div>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="alert alert-warning" role="alert"> <div class="alert alert-warning" role="alert">
此操作将会回滚到上一个发布版本,且当前版本作废,但不影响正在修改的配置。可在发布历史页面查看当前生效的版本 {{'Component.Rollback.Tips' | translate }}
<a target="_blank" <a target="_blank"
href="/config/history.html?#/appid={{appId}}&env={{env}}&clusterName={{toRollbackNamespace.baseInfo.clusterName}}&namespaceName={{toRollbackNamespace.baseInfo.namespaceName}}">点击查看</a> href="/config/history.html?#/appid={{appId}}&env={{env}}&clusterName={{toRollbackNamespace.baseInfo.clusterName}}&namespaceName={{toRollbackNamespace.baseInfo.namespaceName}}">点击查看</a>
</div> </div>
...@@ -27,16 +26,16 @@ ...@@ -27,16 +26,16 @@
<thead> <thead>
<tr> <tr>
<th> <th>
Type {{'Component.Rollback.ItemType' | translate }}
</th> </th>
<th> <th>
Key {{'Component.Rollback.ItemKey' | translate }}
</th> </th>
<th> <th>
回滚前 {{'Component.Rollback.RollbackBeforeValue' | translate }}
</th> </th>
<th> <th>
回滚后 {{'Component.Rollback.RollbackAfterValue' | translate }}
</th> </th>
</tr> </tr>
</thead> </thead>
...@@ -44,9 +43,12 @@ ...@@ -44,9 +43,12 @@
<tr ng-repeat="change in toRollbackNamespace.releaseCompareResult"> <tr ng-repeat="change in toRollbackNamespace.releaseCompareResult">
<td width="10%"> <td width="10%">
<span ng-show="change.type == 'ADDED'">新增</span> <span
<span ng-show="change.type == 'MODIFIED'">更新</span> ng-show="change.type == 'ADDED'">{{'Component.Rollback.Added' | translate }}</span>
<span ng-show="change.type == 'DELETED'">删除</span> <span
ng-show="change.type == 'MODIFIED'">{{'Component.Rollback.Modifed' | translate }}</span>
<span
ng-show="change.type == 'DELETED'">{{'Component.Rollback.Deleted' | translate }}</span>
</td> </td>
<td width="20%" ng-bind="change.entity.firstEntity.key"> <td width="20%" ng-bind="change.entity.firstEntity.key">
...@@ -65,21 +67,21 @@ ...@@ -65,21 +67,21 @@
ng-if="toRollbackNamespace.releaseCompareResult.length > 0 && !toRollbackNamespace.isPropertiesFormat"> ng-if="toRollbackNamespace.releaseCompareResult.length > 0 && !toRollbackNamespace.isPropertiesFormat">
<div ng-repeat="change in toRollbackNamespace.releaseCompareResult" <div ng-repeat="change in toRollbackNamespace.releaseCompareResult"
ng-if="!toRollbackNamespace.isPropertiesFormat"> ng-if="!toRollbackNamespace.isPropertiesFormat">
<h5>回滚前</h5> <h5>{{'Component.Rollback.RollbackBeforeValue' | translate }}</h5>
<textarea class="form-control no-radius" rows="20" <textarea class="form-control no-radius" rows="20" ng-disabled="true"
ng-disabled="true" ng-bind="change.entity.firstEntity.value"> ng-bind="change.entity.firstEntity.value">
</textarea> </textarea>
<hr> <hr>
<h5>回滚后</h5> <h5>{{'Component.Rollback.RollbackAfterValue' | translate }}</h5>
<textarea class="form-control no-radius" rows="20" <textarea class="form-control no-radius" rows="20" ng-disabled="true"
ng-disabled="true" ng-bind="change.entity.secondEntity.value"> ng-bind="change.entity.secondEntity.value">
</textarea> </textarea>
</div> </div>
</div> </div>
<div class="col-sm-12 text-center" ng-if="toRollbackNamespace.releaseCompareResult.length == 0"> <div class="col-sm-12 text-center" ng-if="toRollbackNamespace.releaseCompareResult.length == 0">
<h4> <h4>
配置没有变化 {{'Component.Rollback.NoChange' | translate }}
</h4> </h4>
</div> </div>
</div> </div>
...@@ -87,9 +89,10 @@ ...@@ -87,9 +89,10 @@
</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">{{'Common.Cancel' | translate }}</button>
<button type="submit" class="btn btn-danger" <button type="submit" class="btn btn-danger"
ng-disabled="toRollbackNamespace.rollbackBtnDisabled">回滚 ng-disabled="toRollbackNamespace.rollbackBtnDisabled">{{'Component.Rollback.OpRollback' | translate }}
</button> </button>
</div> </div>
</div> </div>
......
...@@ -5,13 +5,12 @@ ...@@ -5,13 +5,12 @@
<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">查看</h4> <h4 class="modal-title">{{'Component.ShowText.Title' | translate }}</h4>
</div> </div>
<pre class="modal-body no-radius" style="margin-bottom: 0" <pre class="modal-body no-radius" style="margin-bottom: 0" ng-show="!jsonObject" ng-bind="text">
ng-show="!jsonObject" ng-bind="text">
</pre> </pre>
<pre class="modal-body no-radius" style="margin-bottom: 0" <pre class="modal-body no-radius" style="margin-bottom: 0" ng-show="jsonObject"
ng-show="jsonObject" ng-bind="jsonObject | json:4"> ng-bind="jsonObject | json:4">
</pre> </pre>
</div> </div>
</div> </div>
......
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