Skip to content

Commit 0b9d2aa

Browse files
kezhenxu94nobodyiam
authored andcommitted
[APOLLO-1966]: diff configurations among clusters. issue apolloconfig#1966 (apolloconfig#1996)
feature: diff configurations among clusters. issue apolloconfig#1966
1 parent dfa9f7a commit 0b9d2aa

File tree

6 files changed

+269
-0
lines changed

6 files changed

+269
-0
lines changed
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
<!doctype html>
2+
<html ng-app="diff_item">
3+
<head>
4+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5+
<link rel="icon" href="../img/config.png">
6+
<!-- styles -->
7+
<link rel="stylesheet" type="text/css" href="../vendor/bootstrap/css/bootstrap.min.css">
8+
<link rel="stylesheet" type="text/css" href="../vendor/angular/angular-toastr-1.4.1.min.css">
9+
<link rel="stylesheet" type="text/css" media='all' href="../vendor/angular/loading-bar.min.css">
10+
<link rel="stylesheet" type="text/css" href="../styles/common-style.css">
11+
<title>比较配置</title>
12+
<style>
13+
.comment-toggle {
14+
margin-left: 8px !important;
15+
}
16+
.diff-content {
17+
margin-top: 12px;
18+
}
19+
</style>
20+
</head>
21+
22+
<body>
23+
24+
<apollonav></apollonav>
25+
26+
<div class="container-fluid apollo-container" ng-controller="DiffItemController">
27+
<section class="panel col-md-offset-1 col-md-10">
28+
<header class="panel-heading">
29+
<div class="row">
30+
<div class="col-md-7">
31+
<h4 class="modal-title">比较配置
32+
<small ng-show="syncItemStep == 1">(第一步:选择比较信息)</small>
33+
<small ng-show="syncItemStep == 2">(第二步:查看差异配置)</small>
34+
</h4>
35+
</div>
36+
<div class="col-md-5 text-right">
37+
<button type="button" class="btn btn-primary" ng-show="syncItemStep > 1 && syncItemStep < 3"
38+
ng-click="syncItemNextStep(-1)">上一步
39+
</button>
40+
<button type="button" class="btn btn-primary" ng-show="syncItemStep < 2"
41+
ng-click="diff()">下一步
42+
</button>
43+
<button type="button" class="btn btn-info" data-dismiss="modal"
44+
ng-click="backToAppHomePage()">返回到项目首页
45+
</button>
46+
</div>
47+
</div>
48+
</header>
49+
<div class="panel-body">
50+
<div class="row" ng-show="syncItemStep == 1">
51+
<div class="alert-info alert no-radius">
52+
<strong>Tips:</strong>
53+
<ul>
54+
<li>通过比较配置功能,可以查看多个环境、集群间的配置差异</li>
55+
</ul>
56+
</div>
57+
<div class="form-horizontal">
58+
<div class="form-group">
59+
<label class="col-sm-2 control-label">要比较的集群</label>
60+
<div class="col-sm-6">
61+
<apolloclusterselector apollo-app-id="pageContext.appId" apollo-default-all-checked="false"
62+
apollo-select="collectSelectedClusters"
63+
apollo-default-checked-env="pageContext.env"
64+
apollo-default-checked-cluster="pageContext.clusterName"></apolloclusterselector>
65+
</div>
66+
</div>
67+
</div>
68+
<hr>
69+
</div>
70+
71+
<!--step 2-->
72+
<div class="row" ng-show="syncItemStep == 2">
73+
<div class="row" style="margin-top: 10px;">
74+
<div class="form-horizontal">
75+
<div class="col-sm-12">
76+
<label class="control-label">
77+
<input type="checkbox"
78+
class="comment-toggle"
79+
ng-checked="showCommentDiff"
80+
ng-click="showCommentDiff=!showCommentDiff">
81+
是否比较注释
82+
</label>
83+
</div>
84+
<div class="col-sm-12 diff-content">
85+
<table class="table table-bordered table-striped table-hover">
86+
<thead>
87+
<tr>
88+
<td>Key</td>
89+
<td ng-repeat="cluster in syncData.syncToNamespaces"
90+
ng-bind="cluster.env + ':' + cluster.clusterName + ':' + cluster.namespaceName + ':Value'"
91+
></td>
92+
<td ng-show="showCommentDiff"
93+
ng-repeat="cluster in syncData.syncToNamespaces"
94+
ng-bind="cluster.env + ':' + cluster.clusterName + ':' + cluster.namespaceName + ':Comment'"
95+
></td>
96+
</tr>
97+
</thead>
98+
<tbody>
99+
<tr ng-repeat="(key, itemsKeyedByCluster) in itemsKeyedByKey">
100+
<td width="15%" ng-bind="key"></td>
101+
<td ng-repeat="cluster in syncData.syncToNamespaces"
102+
ng-bind="(itemsKeyedByCluster[cluster.env + ':' + cluster.clusterName + ':' + cluster.namespaceName] || {}).value"></td>
103+
<td ng-show="showCommentDiff"
104+
ng-repeat="cluster in syncData.syncToNamespaces"
105+
ng-bind="(itemsKeyedByCluster[cluster.env + ':' + cluster.clusterName + ':' + cluster.namespaceName] || {}).comment"></td>
106+
</tr>
107+
</tbody>
108+
</table>
109+
</div>
110+
</div>
111+
</div>
112+
</div>
113+
</div>
114+
</section>
115+
116+
<showtextmodal text="text"/>
117+
</div>
118+
119+
120+
121+
<div ng-include="'../views/common/footer.html'"></div>
122+
123+
<!-- jquery.js -->
124+
<script src="../vendor/jquery.min.js" type="text/javascript"></script>
125+
126+
<!--angular-->
127+
<script src="../vendor/angular/angular.min.js"></script>
128+
<script src="../vendor/angular/angular-resource.min.js"></script>
129+
<script src="../vendor/angular/angular-toastr-1.4.1.tpls.min.js"></script>
130+
<script src="../vendor/angular/loading-bar.min.js"></script>
131+
132+
133+
<!-- bootstrap.js -->
134+
<script src="../vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
135+
136+
<script src="../vendor/clipboard.min.js" type="text/javascript"></script>
137+
<!--biz-->
138+
<script type="application/javascript" src="../scripts/app.js"></script>
139+
<script type="application/javascript" src="../scripts/services/AppService.js"></script>
140+
<script type="application/javascript" src="../scripts/services/EnvService.js"></script>
141+
<script type="application/javascript" src="../scripts/services/ConfigService.js"></script>
142+
<script type="application/javascript" src="../scripts/services/UserService.js"></script>
143+
<script type="application/javascript" src="../scripts/services/CommonService.js"></script>
144+
<script type="application/javascript" src="../scripts/services/PermissionService.js"></script>
145+
146+
<script type="application/javascript" src="../scripts/AppUtils.js"></script>
147+
<script type="application/javascript" src="../scripts/controller/config/DiffConfigController.js"></script>
148+
149+
<script type="application/javascript" src="../scripts/PageCommon.js"></script>
150+
<script type="application/javascript" src="../scripts/directive/directive.js"></script>
151+
<script type="application/javascript" src="../scripts/directive/show-text-modal-directive.js"></script>
152+
</body>
153+
</html>
Loading

apollo-portal/src/main/resources/static/scripts/app.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ var application_module = angular.module('application', ['app.service', 'apollo.d
1616
var app_module = angular.module('create_app', ['apollo.directive', 'toastr', 'app.service', 'app.util', 'angular-loading-bar', 'valdr']);
1717
//配置同步页面
1818
var sync_item_module = angular.module('sync_item', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar']);
19+
// 比较页面
20+
var diff_item_module = angular.module('diff_item', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar']);
1921
//namespace
2022
var namespace_module = angular.module('namespace', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar', 'valdr']);
2123
//server config
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
diff_item_module.controller("DiffItemController",
2+
['$scope', '$location', '$window', 'toastr', 'AppService', 'AppUtil', 'ConfigService',
3+
function ($scope, $location, $window, toastr, AppService, AppUtil, ConfigService) {
4+
5+
var params = AppUtil.parseParams($location.$$url);
6+
$scope.pageContext = {
7+
appId: params.appid,
8+
env: params.env,
9+
clusterName: params.clusterName,
10+
namespaceName: params.namespaceName
11+
};
12+
var sourceItems = [];
13+
14+
$scope.diff = diff;
15+
$scope.syncBtnDisabled = false;
16+
$scope.showCommentDiff = false;
17+
18+
$scope.collectSelectedClusters = collectSelectedClusters;
19+
20+
$scope.syncItemNextStep = syncItemNextStep;
21+
$scope.backToAppHomePage = backToAppHomePage;
22+
$scope.switchSelect = switchSelect;
23+
24+
$scope.showText = showText;
25+
26+
$scope.itemsKeyedByKey = {};
27+
28+
$scope.syncData = {
29+
syncToNamespaces: [],
30+
syncItems: []
31+
};
32+
33+
function diff() {
34+
$scope.syncData = parseSyncSourceData();
35+
if ($scope.syncData.syncToNamespaces.length < 2) {
36+
toastr.warning("请至少选择两个集群");
37+
return;
38+
}
39+
$scope.syncData.syncToNamespaces.forEach(function (namespace) {
40+
ConfigService.find_items(namespace.appId,
41+
namespace.env,
42+
namespace.clusterName,
43+
namespace.namespaceName).then(function (result) {
44+
result.forEach(function (item) {
45+
var itemsKeyedByClusterName = $scope.itemsKeyedByKey[item.key] || {};
46+
itemsKeyedByClusterName[namespace.env + ':' + namespace.clusterName + ':' + namespace.namespaceName] = item;
47+
$scope.itemsKeyedByKey[item.key] = itemsKeyedByClusterName;
48+
});
49+
});
50+
});
51+
$scope.syncItemNextStep(1);
52+
}
53+
54+
var selectedClusters = [];
55+
56+
function collectSelectedClusters(data) {
57+
selectedClusters = data;
58+
}
59+
60+
function parseSyncSourceData() {
61+
var syncData = {
62+
syncToNamespaces: [],
63+
syncItems: []
64+
};
65+
var namespaceName = $scope.pageContext.namespaceName;
66+
selectedClusters.forEach(function (cluster) {
67+
if (cluster.checked) {
68+
cluster.clusterName = cluster.name;
69+
cluster.namespaceName = namespaceName;
70+
syncData.syncToNamespaces.push(cluster);
71+
}
72+
});
73+
74+
return syncData;
75+
}
76+
77+
////// flow control ///////
78+
79+
$scope.syncItemStep = 1;
80+
function syncItemNextStep(offset) {
81+
$scope.syncItemStep += offset;
82+
}
83+
84+
function backToAppHomePage() {
85+
$window.location.href = '/config.html?#appid=' + $scope.pageContext.appId;
86+
}
87+
88+
function switchSelect(o) {
89+
o.checked = !o.checked;
90+
}
91+
92+
function showText(text) {
93+
$scope.text = text;
94+
AppUtil.showModal('#showTextModal');
95+
}
96+
}]);

apollo-portal/src/main/resources/static/scripts/directive/namespace-panel-directive.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
5151
scope.loadCommitHistory = loadCommitHistory;
5252
scope.toggleTextEditStatus = toggleTextEditStatus;
5353
scope.goToSyncPage = goToSyncPage;
54+
scope.goToDiffPage = goToDiffPage;
5455
scope.modifyByText = modifyByText;
5556
scope.syntaxCheck = syntaxCheck;
5657
scope.goToParentAppConfigPage = goToParentAppConfigPage;
@@ -701,6 +702,14 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
701702
+ "&namespaceName=" + namespace.baseInfo.namespaceName;
702703
}
703704

705+
function goToDiffPage(namespace) {
706+
$window.location.href =
707+
"config/diff.html?#/appid=" + scope.appId + "&env="
708+
+ scope.env + "&clusterName="
709+
+ scope.cluster
710+
+ "&namespaceName=" + namespace.baseInfo.namespaceName;
711+
}
712+
704713
function modifyByText(namespace) {
705714
var model = {
706715
configText: namespace.editText,

apollo-portal/src/main/resources/static/views/component/namespace-panel-master-tab.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,15 @@
189189
同步配置
190190
</button>
191191

192+
<button type="button" class="btn btn-default btn-sm J_tableview_btn"
193+
data-tooltip="tooltip" data-placement="bottom" title="比较各环境间配置"
194+
ng-click="goToDiffPage(namespace)"
195+
ng-show="namespace.viewType == 'table' && namespace.displayControl.currentOperateBranch == 'master'
196+
&& namespace.isPropertiesFormat">
197+
<img src="img/diff.png">
198+
比较配置
199+
</button>
200+
192201
<button type="button" class="btn btn-primary btn-sm"
193202
ng-show="!namespace.isLinkedNamespace
194203
&& namespace.viewType == 'table'

0 commit comments

Comments
 (0)