提交 6aaa2773 编写于 作者: L lepdou

table view cru

上级 0b3ace80
......@@ -36,7 +36,14 @@ public class ItemController {
BeanUtils.copyEntityProperties(entity, managedEntity);
entity = itemService.update(managedEntity);
} else {
Item lastItem = itemService.findLastOne(appId, clusterName, namespaceName);
int lineNum = 1;
if (lastItem != null){
lineNum = lastItem.getLineNum() + 1;
}
entity.setLineNum(lineNum);
entity.setDataChangeCreatedBy(user.getUsername());
entity.setDataChangeLastModifiedBy(user.getUsername());
entity = itemService.save(entity);
}
......
......@@ -12,4 +12,5 @@ public interface ItemRepository extends PagingAndSortingRepository<Item, Long> {
List<Item> findByNamespaceIdOrderByLineNumAsc(Long namespaceId);
Item findFirst1ByNamespaceIdOrderByLineNumDesc(Long namespaceId);
}
......@@ -45,6 +45,17 @@ public class ItemService {
return item;
}
public Item findLastOne(String appId, String clusterName, String namespaceName) {
Namespace namespace = namespaceRepository.findByAppIdAndClusterNameAndNamespaceName(appId,
clusterName, namespaceName);
if (namespace == null) {
throw new NotFoundException(
String.format("namespace not found for %s %s %s", appId, clusterName, namespaceName));
}
Item item = itemRepository.findFirst1ByNamespaceIdOrderByLineNumDesc(namespace.getId());
return item;
}
public Item findOne(long itemId) {
Item item = itemRepository.findOne(itemId);
return item;
......
......@@ -115,6 +115,12 @@ public class AdminServiceAPI {
.format("apps/%s/clusters/%s/namespaces/%s/itemset", appId, clusterName, namespace),
changeSets, Void.class);
}
public ItemDTO createOrUpdateItem(String appId, Env env, String clusterName, String namespace, ItemDTO item){
return restTemplate.postForEntity(getAdminServiceHost(env) + String
.format("apps/%s/clusters/%s/namespaces/%s/items", appId, clusterName, namespace),
item, ItemDTO.class).getBody();
}
}
@Service
......
......@@ -37,7 +37,7 @@ public class PortalConfigController {
@RequestBody NamespaceTextModel model) {
if (model == null) {
throw new BadRequestException("request payload shoud not be null");
throw new BadRequestException("request payload should not be null");
}
model.setAppId(appId);
model.setClusterName(clusterName);
......@@ -51,13 +51,39 @@ public class PortalConfigController {
configService.updateConfigItemByText(model);
}
@RequestMapping(value = "/apps/{appId}/env/{env}/clusters/{clusterName}/namespaces/{namespaceName}/item", method = RequestMethod.POST)
public ItemDTO createItem(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName,
@RequestBody ItemDTO item){
if (StringUtils.isContainEmpty(appId, env, clusterName, namespaceName)){
throw new BadRequestException("request payload should not be contain empty.");
}
if (!isValidItem(item) && item.getNamespaceId() <= 0){
throw new BadRequestException("request model is invalid");
}
return configService.createOrUpdateItem(appId, Env.valueOf(env), clusterName, namespaceName, item);
}
@RequestMapping(value = "/apps/{appId}/env/{env}/clusters/{clusterName}/namespaces/{namespaceName}/item", method = RequestMethod.PUT)
public ItemDTO updateItem(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName,
@RequestBody ItemDTO item){
if (StringUtils.isContainEmpty(appId, env, clusterName, namespaceName)){
throw new BadRequestException("request payload should not be contain empty.");
}
if (!isValidItem(item)){
throw new BadRequestException("request model is invalid");
}
return configService.createOrUpdateItem(appId, Env.valueOf(env), clusterName, namespaceName, item);
}
@RequestMapping(value = "/apps/{appId}/env/{env}/clusters/{clusterName}/namespaces/{namespaceName}/release", method = RequestMethod.POST, consumes = {
"application/json"})
public ReleaseDTO createRelease(@PathVariable String appId,
@PathVariable String env, @PathVariable String clusterName,
@PathVariable String namespaceName, @RequestBody NamespaceReleaseModel model) {
if (model == null) {
throw new BadRequestException("request payload shoud not be null");
throw new BadRequestException("request payload should not be null");
}
model.setAppId(appId);
model.setClusterName(clusterName);
......@@ -77,7 +103,7 @@ public class PortalConfigController {
@PathVariable String clusterName, @PathVariable String namespaceName){
if (StringUtils.isContainEmpty(appId, env, clusterName, namespaceName)){
throw new BadRequestException("appid,env,cluster name,namespace name can not be null");
throw new BadRequestException("appid,env,cluster name,namespace name can not be empty");
}
return configService.findItems(appId, Env.valueOf(env), clusterName, namespaceName);
......@@ -87,7 +113,7 @@ public class PortalConfigController {
"application/json"})
public List<ItemDiffs> diff(@RequestBody NamespaceSyncModel model){
if (model == null){
throw new BadRequestException("request payload shoud not be null");
throw new BadRequestException("request payload should not be null");
}
if (model.isInvalid()) {
throw new BadRequestException("request model is invalid");
......@@ -100,7 +126,7 @@ public class PortalConfigController {
"application/json"})
public ResponseEntity<Void> update(@RequestBody NamespaceSyncModel model){
if (model == null){
throw new BadRequestException("request payload shoud not be null");
throw new BadRequestException("request payload should not be null");
}
if (model.isInvalid()) {
throw new BadRequestException("request model is invalid");
......@@ -109,4 +135,8 @@ public class PortalConfigController {
return ResponseEntity.status(HttpStatus.OK).build();
}
private boolean isValidItem(ItemDTO item){
return item != null && !StringUtils.isContainEmpty(item.getKey(), item.getValue());
}
}
......@@ -71,6 +71,11 @@ public class PortalConfigService {
}
}
public ItemDTO createOrUpdateItem(String appId, Env env, String clusterName, String namespaceName, ItemDTO item){
return itemAPI.createOrUpdateItem(appId, env, clusterName, namespaceName, item);
}
/**
* createRelease config items
*/
......
......@@ -25,26 +25,26 @@
<div class="panel-body">
<form class="form-horizontal" ng-controller="CreateAppController" ng-submit="create()">
<div class="form-group">
<label class="col-sm-2 control-label"><font style="color: red">*</font> 应用ID</label>
<label class="col-sm-2 control-label"><apollorequiredfiled></apollorequiredfiled> 应用ID</label>
<div class="col-sm-3">
<input type="text" class="form-control" name="appAppId" ng-model="app.appId"
required>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"><font style="color: red">*</font> 应用名称</label>
<label class="col-sm-2 control-label"><apollorequiredfiled></apollorequiredfiled> 应用名称</label>
<div class="col-sm-5">
<input type="text" class="form-control" name="appName" ng-model="app.name" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"><font style="color: red">*</font>应用Owner</label>
<label class="col-sm-2 control-label"><apollorequiredfiled></apollorequiredfiled>应用Owner</label>
<div class="col-sm-3">
<input type="text" class="form-control" name="appOwner" ng-model="app.ownerName" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"><font style="color: red">*</font>邮箱地址</label>
<label class="col-sm-2 control-label"><apollorequiredfiled></apollorequiredfiled>邮箱地址</label>
<div class="col-sm-4">
<input type="email" class="form-control" ng-model="app.ownerEmail" required>
</div>
......
......@@ -60,7 +60,7 @@
<label class="control-label">需要同步的配置</label>
</div>
<div class="col-sm-10">
<table class="table table-bordered table-striped table-hover">
<table class="table table-bordered table-striped table-hover" >
<thead>
<tr>
<td><input type="checkbox" ng-click="toggleItemsCheckedStatus()"></td>
......
......@@ -5,42 +5,50 @@ application_module.controller("ConfigNamespaceController",
////// namespace //////
var namespace_view_type = {
TEXT:'text',
TEXT: 'text',
TABLE: 'table',
LOG: 'log'
};
$rootScope.refreshNamespaces = function (viewType) {
if ($rootScope.pageContext.env == ''){
if ($rootScope.pageContext.env == '') {
return;
}
ConfigService.load_all_namespaces($rootScope.pageContext.appId, $rootScope.pageContext.env,
$rootScope.pageContext.clusterName, viewType).then(
ConfigService.load_all_namespaces($rootScope.pageContext.appId,
$rootScope.pageContext.env,
$rootScope.pageContext.clusterName,
viewType).then(
function (result) {
$scope.namespaces = result;
//初始化视图
if ($scope.namespaces) {
$scope.namespaces.forEach(function (item) {
item.isModify = false;
$scope.namespaces.forEach(function (namespace) {
if (!viewType) {//default text view
$scope.switchView(item, namespace_view_type.TEXT);
$scope.switchView(namespace, namespace_view_type.TABLE);
} else if (viewType == namespace_view_type.TABLE) {
item.viewType = namespace_view_type.TABLE;
namespace.viewType = namespace_view_type.TABLE;
}
item.isTextEditing = false;
namespace.isTextEditing = false;
});
}
setInterval(function () {
$('[data-tooltip="tooltip"]').tooltip();
},2500);
$('.namespace-view-table').bind( 'mousewheel DOMMouseScroll', function ( e ) {
var e0 = e.originalEvent,
delta = e0.wheelDelta || -e0.detail;
this.scrollTop += ( delta < 0 ? 1 : -1 ) * 30;
e.preventDefault();
});
}, 2500);
}, function (result) {
toastr.error(AppUtil.errorMsg(result), "加载配置信息出错");
});
}
};
////// global view oper //////
......@@ -52,11 +60,11 @@ application_module.controller("ConfigNamespaceController",
}
namespace.viewType = viewType;
};
var MAX_ROW_SIZE = 30;
//把表格内容解析成文本
function parseModel2Text(namespace) {
if (!namespace.items) {
return "无配置信息";
}
......@@ -69,7 +77,7 @@ application_module.controller("ConfigNamespaceController",
} else {
result += item.item.comment + "\n";
}
itemCnt ++;
itemCnt++;
});
namespace.itemCnt = itemCnt > MAX_ROW_SIZE ? MAX_ROW_SIZE : itemCnt + 3;
......@@ -87,8 +95,10 @@ application_module.controller("ConfigNamespaceController",
$scope.commitComment = '';
//更新配置
$scope.commitChange = function () {
ConfigService.modify_items($scope.pageContext.appId, $scope.pageContext.env, $scope.pageContext.clusterName,
$scope.draft.namespace.namespaceName, $scope.draft.text,
ConfigService.modify_items($scope.pageContext.appId, $scope.pageContext.env,
$scope.pageContext.clusterName,
$scope.draft.namespace.namespaceName,
$scope.draft.text,
$scope.draft.namespace.id, $scope.commitComment).then(
function (result) {
toastr.success("更新成功");
......@@ -104,52 +114,132 @@ application_module.controller("ConfigNamespaceController",
);
};
//文本编辑框状态切换
$scope.toggleTextEditStatus = function (namespace) {
namespace.isTextEditing = !namespace.isTextEditing;
if (namespace.isTextEditing){//切换为编辑状态,保存一下原来值
if (namespace.isTextEditing) {//切换为编辑状态,保存一下原来值
$scope.draft.backupText = namespace.text;
}else {
if ($scope.draft.backupText){//取消编辑,则复原
} else {
if ($scope.draft.backupText) {//取消编辑,则复原
namespace.text = $scope.draft.backupText;
}
}
};
////// table view oper //////
$scope.watch = {};
//查看配置
$scope.watchItem = function (key, value, oldValue) {
$scope.watch.key = key;
$scope.watch.value = value;
$scope.watch.oldValue = oldValue;
};
/////// release ///////
var releaseModal = $('#releaseModal');
var releaseNamespace = {};
$scope.prepareReleaseNamespace = function (namespace) {
releaseNamespace = namespace;
releaseNamespace = namespace;
};
$scope.releaseComment = '';
$scope.releaseTitle = '';
$scope.release = function () {
ConfigService.release($rootScope.pageContext.appId, $rootScope.pageContext.env,
$rootScope.pageContext.clusterName,
releaseNamespace.namespace.namespaceName, $scope.releaseTitle,
releaseNamespace.namespace.namespaceName,
$scope.releaseTitle,
$scope.releaseComment).then(
function (result) {
releaseModal.modal('hide');
toastr.success("发布成功");
//refresh all namespace items
$rootScope.refreshNamespaces();
}, function (result) {
toastr.error(AppUtil.errorMsg(result), "发布失败");
toastr.error(AppUtil.errorMsg(result), "发布失败");
}
);
);
};
var TABLE_VIEW_OPER_TYPE = {
RETRIEVE: 'retrieve',
CREATE: 'create',
UPDATE: 'update'
};
$scope.tableViewOperType = '', $scope.item = {};
//查看配置
$scope.retrieveItem = function (item, oldValue) {
switchTableViewOperType(TABLE_VIEW_OPER_TYPE.RETRIEVE);
$scope.item = item;
$scope.item.oldValue = oldValue;
};
var toOperationNamespaceName = '';
//修改配置
$scope.editItem = function (namespace, item) {
switchTableViewOperType(TABLE_VIEW_OPER_TYPE.UPDATE);
$scope.item = item;
toOperationNamespaceName = namespace.namespace.namespaceName;
};
//新增配置
$scope.createItem = function (namespace) {
switchTableViewOperType(TABLE_VIEW_OPER_TYPE.CREATE);
$scope.item = {};
$scope.item.namespaceId = namespace.namespace.id;
toOperationNamespaceName = namespace.namespace.namespaceName;
};
$scope.switchToEdit = function () {
switchTableViewOperType(TABLE_VIEW_OPER_TYPE.UPDATE);
};
var selectedClusters = [];
$scope.collectSelectedClusters = function (data) {
selectedClusters = data;
};
function switchTableViewOperType(type) {
$scope.tableViewOperType = type;
}
var itemModal = $("#itemModal");
$scope.doItem = function () {
if (selectedClusters.length == 0) {
toastr.error("请选择集群");
} else {
selectedClusters.forEach(function (cluster) {
if ($scope.tableViewOperType == TABLE_VIEW_OPER_TYPE.CREATE) {
ConfigService.create_item($rootScope.pageContext.appId,
cluster.env,
cluster.name,
toOperationNamespaceName,
$scope.item).then(
function (result) {
toastr.success("[" + cluster.env + "," + cluster.name + "]",
"创建成功");
itemModal.modal('hide');
$rootScope.refreshNamespaces(namespace_view_type.TABLE);
}, function (result) {
AppUtil.errorMsg(result);
});
} else if ($scope.tableViewOperType == TABLE_VIEW_OPER_TYPE.UPDATE) {
ConfigService.update_item($rootScope.pageContext.appId,
cluster.env,
cluster.name,
toOperationNamespaceName,
$scope.item).then(
function (result) {
toastr.success("[" + cluster.env + "," + cluster.name + "]",
"更新成功");
itemModal.modal('hide');
$rootScope.refreshNamespaces(namespace_view_type.TABLE);
}, function (result) {
AppUtil.errorMsg(result);
});
}
});
}
};
$('.config-item-container').removeClass('hide');
......
/** navbar */
directive_module.directive('apollonav', function ($compile, $window, AppService, EnvService) {
return {
......@@ -10,7 +9,7 @@ directive_module.directive('apollonav', function ($compile, $window, AppService,
scope.sourceApps = [];
scope.copyedApps = [];
EnvService.find_all_envs().then(function (result) {
//default select first env
AppService.find_all_app(result[0]).then(function (result) {
......@@ -35,23 +34,23 @@ directive_module.directive('apollonav', function ($compile, $window, AppService,
scope.changeSearchKey = function () {
scope.copyedApps = [];
scope.sourceApps.forEach(function (app) {
if (app.name.indexOf(scope.searchKey) > -1 || app.appId.indexOf(scope.searchKey) > -1) {
scope.copyedApps.push(app);
}
});
scope.sourceApps.forEach(function (app) {
if (app.name.indexOf(scope.searchKey) > -1 || app.appId.indexOf(scope.searchKey) > -1) {
scope.copyedApps.push(app);
}
});
scope.shouldShowAppList = true;
};
scope.jumpToConfigPage = function () {
if (selectedApp.appId){
if (selectedApp.appId) {
var needReloadPage = false;
if ($window.location.href.indexOf("config.html") > -1){
if ($window.location.href.indexOf("config.html") > -1) {
needReloadPage = true;
}
$window.location.href = '/config.html?#appid=' + selectedApp.appId;
if (needReloadPage){
if (needReloadPage) {
$window.location.reload();
}
}
......@@ -72,10 +71,10 @@ directive_module.directive('apollonav', function ($compile, $window, AppService,
scope.copyedApps[--selectedAppIdx].selected = true;
}
} else if (event.keyCode == 13) {
if (scope.shouldShowAppList && selectedAppIdx > -1){
if (scope.shouldShowAppList && selectedAppIdx > -1) {
select(scope.copyedApps[selectedAppIdx]);
event.preventDefault();
}else {
} else {
scope.jumpToConfigPage();
}
......@@ -157,23 +156,39 @@ directive_module.directive('apolloclusterselector', function ($compile, $window,
scope.select(collectSelectedClusters());
};
scope.switchSelect = function (o) {
scope.switchSelect = function (o, $event) {
o.checked = !o.checked;
$event.stopPropagation();
scope.select(collectSelectedClusters());
};
scope.toggleClusterCheckedStatus = function (cluster) {
cluster.checked = !cluster.checked;
scope.select(collectSelectedClusters());
};
function collectSelectedClusters() {
var selectedClusters = [];
scope.clusters.forEach(function (cluster) {
if (cluster.checked){
if (cluster.checked) {
cluster.clusterName = cluster.name;
selectedClusters.push(cluster);
}
});
return selectedClusters;
}
}
}
});
directive_module.directive('apollorequiredfiled', function ($compile, $window) {
return {
restrict: 'E',
template: '<span style="color: red">*</span>',
transclude: true,
replace: true
}
});
......@@ -5,10 +5,10 @@ appService.service("ConfigService", ['$resource', '$q', function ($resource, $q)
isArray: true,
url: '/apps/:appId/env/:env/clusters/:clusterName/namespaces'
},
find_items:{
method:'GET',
find_items: {
method: 'GET',
isArray: true,
url:'/apps/:appId/env/:env/clusters/:clusterName/namespaces/:namespaceName/items'
url: '/apps/:appId/env/:env/clusters/:clusterName/namespaces/:namespaceName/items'
},
modify_items: {
method: 'PUT',
......@@ -16,7 +16,7 @@ appService.service("ConfigService", ['$resource', '$q', function ($resource, $q)
},
release: {
method: 'POST',
url:'/apps/:appId/env/:env/clusters/:clusterName/namespaces/:namespaceName/release'
url: '/apps/:appId/env/:env/clusters/:clusterName/namespaces/:namespaceName/release'
},
diff: {
method: 'POST',
......@@ -27,6 +27,14 @@ appService.service("ConfigService", ['$resource', '$q', function ($resource, $q)
method: 'PUT',
url: '/namespaces/:namespaceName/items',
isArray: false
},
create_item: {
method: 'POST',
url: '/apps/:appId/env/:env/clusters/:clusterName/namespaces/:namespaceName/item'
},
update_item: {
method: 'PUT',
url: '/apps/:appId/env/:env/clusters/:clusterName/namespaces/:namespaceName/item'
}
});
......@@ -34,10 +42,10 @@ appService.service("ConfigService", ['$resource', '$q', function ($resource, $q)
load_all_namespaces: function (appId, env, clusterName) {
var d = $q.defer();
config_source.load_all_namespaces({
appId: appId,
env: env,
clusterName: clusterName
}, function (result) {
appId: appId,
env: env,
clusterName: clusterName
}, function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
......@@ -52,9 +60,9 @@ appService.service("ConfigService", ['$resource', '$q', function ($resource, $q)
clusterName: clusterName,
namespaceName: namespaceName
}, function (result) {
d.resolve(result);
d.resolve(result);
}, function (result) {
d.reject(result);
d.reject(result);
});
return d.promise;
},
......@@ -70,16 +78,16 @@ appService.service("ConfigService", ['$resource', '$q', function ($resource, $q)
{
configText: configText,
namespaceId: namespaceId,
comment:comment
comment: comment
}, function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
});
});
return d.promise;
},
release: function (appId, env, clusterName, namespaceName, releaseBy, comment) {
var d = $q.defer();
config_source.release({
......@@ -113,8 +121,38 @@ appService.service("ConfigService", ['$resource', '$q', function ($resource, $q)
sync_items: function (namespaceName, sourceData) {
var d = $q.defer();
config_source.sync_item({
namespaceName: namespaceName
}, sourceData, function (result) {
namespaceName: namespaceName
}, sourceData, function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
});
return d.promise;
},
create_item: function (appId, env, clusterName, namespaceName, item) {
var d = $q.defer();
config_source.create_item({
appId: appId,
env: env,
clusterName: clusterName,
namespaceName: namespaceName
}, item, function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
});
return d.promise;
},
update_item: function (appId, env, clusterName, namespaceName, item) {
var d = $q.defer();
config_source.update_item({
appId: appId,
env: env,
clusterName: clusterName,
namespaceName: namespaceName
}, item, function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
......
......@@ -212,22 +212,21 @@ table th {
}
.namespace-view-table {
max-height: 700px;
}
.namespace-view-table table {
table-layout: fixed;
}
.namespace-view-table tr {
cursor: pointer;
.namespace-view-table table {
table-layout: inherit;
}
.namespace-view-table td {
word-wrap: break-word;
}
.namespace-view-table .glyphicon{
cursor: pointer;
}
.history-view {
padding: 50px 20px;
......
<table class="table table-hover">
<table class="table table-hover" style="width: 250px">
<thead>
<tr>
<td><input type="checkbox" ng-checked="envAllSelected" ng-click="toggleEnvsCheckedStatus()"></td>
......@@ -8,9 +8,9 @@
</tr>
</thead>
<tbody>
<tr ng-repeat="cluster in clusters">
<tr style="cursor: pointer" ng-repeat="cluster in clusters" ng-click="toggleClusterCheckedStatus(cluster)">
<td width="10%"><input type="checkbox" ng-checked="cluster.checked"
ng-click="switchSelect(cluster)"></td>
ng-click="switchSelect(cluster, $event)"></td>
<td width="30%" ng-bind="cluster.env"></td>
<td width="60%" ng-bind="cluster.name"></td>
</tr>
......
19575
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册