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

add delete cluster and namespace rest api

上级 92a90e90
......@@ -88,7 +88,11 @@ public class ItemController {
Item beforeUpdateItem = BeanUtils.transfrom(Item.class, managedEntity);
BeanUtils.copyEntityProperties(entity, managedEntity);
//protect. only value,comment,lastModifiedBy can be modified
managedEntity.setValue(entity.getValue());
managedEntity.setComment(entity.getComment());
managedEntity.setDataChangeLastModifiedBy(entity.getDataChangeLastModifiedBy());
entity = itemService.update(managedEntity);
builder.updateItem(beforeUpdateItem, entity);
itemDTO = BeanUtils.transfrom(ItemDTO.class, entity);
......
......@@ -49,7 +49,8 @@ public class NamespaceController {
Namespace entity = namespaceService.findOne(appId, clusterName, namespaceName);
if (entity == null) throw new NotFoundException(
String.format("namespace not found for %s %s %s", appId, clusterName, namespaceName));
namespaceService.delete(entity.getId(), operator);
namespaceService.deleteNamespace(entity, operator);
}
@RequestMapping("/apps/{appId}/clusters/{clusterName}/namespaces")
......
......@@ -4,7 +4,9 @@
<property name="LOG_FILE"
value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}apollo-assembly.log}" />
<include resource="org/springframework/boot/logging/logback/file-appender.xml" />
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />
<root level="INFO">
<appender-ref ref="FILE" />
<appender-ref ref="CONSOLE" />
</root>
</configuration>
......@@ -10,8 +10,8 @@ import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name = "commit")
@SQLDelete(sql = "Update commit set isDeleted = 1 where id = ?")
@Table(name = "Commit")
@SQLDelete(sql = "Update Commit set isDeleted = 1 where id = ?")
@Where(clause = "isDeleted = 0")
public class Commit extends BaseEntity {
......
......@@ -3,6 +3,8 @@ package com.ctrip.framework.apollo.biz.repository;
import com.ctrip.framework.apollo.biz.entity.Commit;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import java.util.List;
......@@ -10,6 +12,10 @@ import java.util.List;
public interface CommitRepository extends PagingAndSortingRepository<Commit, Long> {
List<Commit> findByAppIdAndClusterNameAndNamespaceNameOrderByIdDesc(String appId, String clusterName,
String namespaceName, Pageable pageable);
String namespaceName, Pageable pageable);
@Modifying
@Query("update Commit set isdeleted=1,DataChange_LastModifiedBy = ?4 where appId=?1 and clusterName=?2 and namespaceName = ?3")
int batchDelete(String appId, String clusterName, String namespaceName, String operator);
}
......@@ -2,6 +2,8 @@ package com.ctrip.framework.apollo.biz.repository;
import java.util.List;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import com.ctrip.framework.apollo.biz.entity.Item;
......@@ -14,4 +16,8 @@ public interface ItemRepository extends PagingAndSortingRepository<Item, Long> {
Item findFirst1ByNamespaceIdOrderByLineNumDesc(Long namespaceId);
@Modifying
@Query("update Item set isdeleted=1,DataChange_LastModifiedBy = ?2 where namespaceId = ?1")
int deleteByNamespaceId(long namespaceId, String operator);
}
......@@ -2,6 +2,8 @@ package com.ctrip.framework.apollo.biz.repository;
import java.util.List;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import com.ctrip.framework.apollo.biz.entity.Namespace;
......@@ -11,4 +13,9 @@ public interface NamespaceRepository extends PagingAndSortingRepository<Namespac
List<Namespace> findByAppIdAndClusterNameOrderByIdAsc(String appId, String clusterName);
Namespace findByAppIdAndClusterNameAndNamespaceName(String appId, String clusterName, String namespaceName);
@Modifying
@Query("update Namespace set isdeleted=1,DataChange_LastModifiedBy = ?3 where appId=?1 and clusterName=?2")
int batchDelete(String appId, String clusterName, String operator);
}
......@@ -3,6 +3,8 @@ package com.ctrip.framework.apollo.biz.repository;
import java.util.List;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
......@@ -19,4 +21,8 @@ public interface ReleaseRepository extends PagingAndSortingRepository<Release, L
List<Release> findByAppIdAndClusterNameAndNamespaceNameOrderByIdDesc(String appId, String clusterName, String namespaceName, Pageable page);
List<Release> findByAppIdAndClusterNameAndNamespaceNameAndIsAbandonedFalseOrderByIdDesc(String appId, String clusterName, String namespaceName, Pageable page);
@Modifying
@Query("update Release set isdeleted=1,DataChange_LastModifiedBy = ?4 where appId=?1 and clusterName=?2 and namespaceName = ?3")
int batchDelete(String appId, String clusterName, String namespaceName, String operator);
}
......@@ -11,6 +11,7 @@ import org.springframework.transaction.annotation.Transactional;
import com.ctrip.framework.apollo.biz.entity.Audit;
import com.ctrip.framework.apollo.biz.entity.Cluster;
import com.ctrip.framework.apollo.biz.repository.ClusterRepository;
import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.common.utils.BeanUtils;
import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.common.exception.ServiceException;
......@@ -26,8 +27,6 @@ public class ClusterService {
private AuditService auditService;
@Autowired
private NamespaceService namespaceService;
@Autowired
private AppNamespaceService appNamespaceService;
public boolean isClusterNameUnique(String appId, String clusterName) {
......@@ -75,9 +74,12 @@ public class ClusterService {
public void delete(long id, String operator) {
Cluster cluster = clusterRepository.findOne(id);
if (cluster == null) {
return;
throw new BadRequestException("cluster not exist");
}
//delete linked namespaces
namespaceService.deleteByAppIdAndClusterName(cluster.getAppId(), cluster.getName(), operator);
cluster.setDeleted(true);
cluster.setDataChangeLastModifiedBy(operator);
clusterRepository.save(cluster);
......
......@@ -26,4 +26,9 @@ public class CommitService {
return commitRepository.findByAppIdAndClusterNameAndNamespaceNameOrderByIdDesc(appId, clusterName, namespaceName, page);
}
@Transactional
public int batchDelete(String appId, String clusterName, String namespaceName, String operator){
return commitRepository.batchDelete(appId, clusterName, namespaceName, operator);
}
}
......@@ -47,6 +47,12 @@ public class ItemService {
return deletedItem;
}
@Transactional
public int batchDelete(long namespaceId, String operator) {
return itemRepository.deleteByNamespaceId(namespaceId, operator);
}
public Item findOne(String appId, String clusterName, String namespaceName, String key) {
Namespace namespace = namespaceRepository.findByAppIdAndClusterNameAndNamespaceName(appId,
clusterName, namespaceName);
......
......@@ -13,7 +13,6 @@ import com.ctrip.framework.apollo.common.utils.BeanUtils;
import com.ctrip.framework.apollo.common.dto.ItemChangeSets;
import com.ctrip.framework.apollo.common.dto.ItemDTO;
import com.ctrip.framework.apollo.common.exception.NotFoundException;
import com.ctrip.framework.apollo.core.utils.StringUtils;
@Service
......@@ -50,14 +49,19 @@ public class ItemSetService {
for (ItemDTO item : changeSet.getUpdateItems()) {
Item entity = BeanUtils.transfrom(Item.class, item);
Item beforeUpdateItem = itemService.findOne(entity.getId());
if (beforeUpdateItem == null) {
Item managedItem = itemService.findOne(entity.getId());
if (managedItem == null) {
throw new NotFoundException(String.format("item not found.(key=%s)", entity.getKey()));
}
beforeUpdateItem = BeanUtils.transfrom(Item.class, beforeUpdateItem);
Item beforeUpdateItem = BeanUtils.transfrom(Item.class, managedItem);
//protect. only value,comment,lastModifiedBy,lineNum can be modified
managedItem.setValue(entity.getValue());
managedItem.setComment(entity.getComment());
managedItem.setLineNum(entity.getLineNum());
entity.setDataChangeLastModifiedBy(operator);
Item updatedItem = itemService.update(entity);
Item updatedItem = itemService.update(managedItem);
configChangeContentBuilder.updateItem(beforeUpdateItem, updatedItem);
}
......@@ -72,8 +76,7 @@ public class ItemSetService {
auditService.audit("ItemSet", null, Audit.OP.DELETE, operator);
}
String configChangeContent = configChangeContentBuilder.build();
if (!StringUtils.isEmpty(configChangeContent)) {
if (configChangeContentBuilder.hasContent()){
createCommit(appId, clusterName, namespaceName, configChangeContentBuilder.build(),
changeSet.getDataChangeLastModifiedBy());
}
......
......@@ -24,6 +24,13 @@ public class NamespaceService {
private AuditService auditService;
@Autowired
private AppNamespaceService appNamespaceService;
@Autowired
private ItemService itemService;
@Autowired
private CommitService commitService;
@Autowired
private ReleaseService releaseService;
public boolean isNamespaceUnique(String appId, String cluster, String namespace) {
Objects.requireNonNull(appId, "AppId must not be null");
......@@ -34,17 +41,32 @@ public class NamespaceService {
}
@Transactional
public void delete(long id, String operator) {
Namespace namespace = namespaceRepository.findOne(id);
if (namespace == null) {
return;
public void deleteByAppIdAndClusterName(String appId, String clusterName, String operator){
List<Namespace> toDeleteNamespaces = findNamespaces(appId, clusterName);
for (Namespace namespace: toDeleteNamespaces){
deleteNamespace(namespace, operator);
}
}
@Transactional
public Namespace deleteNamespace(Namespace namespace, String operator){
String appId = namespace.getAppId();
String clusterName = namespace.getClusterName();
itemService.batchDelete(namespace.getId(), operator);
commitService.batchDelete(appId, clusterName, namespace.getNamespaceName(), operator);
releaseService.batchDelete(appId, clusterName, namespace.getNamespaceName(), operator);
namespace.setDeleted(true);
namespace.setDataChangeLastModifiedBy(operator);
namespaceRepository.save(namespace);
auditService.audit(Namespace.class.getSimpleName(), id, Audit.OP.DELETE, operator);
auditService.audit(Namespace.class.getSimpleName(), namespace.getId(), Audit.OP.DELETE, operator);
return namespaceRepository.save(namespace);
}
public Namespace findOne(Long namespaceId) {
......
......@@ -142,4 +142,9 @@ public class ReleaseService {
return releaseRepository.save(release);
}
@Transactional
public int batchDelete(String appId, String clusterName, String namespaceName, String operator){
return releaseRepository.batchDelete(appId, clusterName, namespaceName, operator);
}
}
......@@ -4,7 +4,9 @@ import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.ctrip.framework.apollo.biz.entity.Item;
import com.ctrip.framework.apollo.core.utils.StringUtils;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
......@@ -20,7 +22,9 @@ public class ConfigChangeContentBuilder {
public ConfigChangeContentBuilder createItem(Item item) {
createItems.add(item);
if (!StringUtils.isEmpty(item.getKey())){
createItems.add(item);
}
return this;
}
......@@ -33,10 +37,16 @@ public class ConfigChangeContentBuilder {
}
public ConfigChangeContentBuilder deleteItem(Item item) {
deleteItems.add(item);
if (!StringUtils.isEmpty(item.getKey())) {
deleteItems.add(item);
}
return this;
}
public boolean hasContent(){
return !createItems.isEmpty() || !updateItems.isEmpty() || !deleteItems.isEmpty();
}
public String build() {
//因为事务第一段提交并没有更新时间,所以build时统一更新
for (Item item : createItems) {
......
......@@ -53,8 +53,8 @@ public class AdminServiceAPI {
public List<NamespaceDTO> findNamespaceByCluster(String appId, Env env, String clusterName) {
NamespaceDTO[] namespaceDTOs = restTemplate.get(env, "apps/{appId}/clusters/{clusterName}/namespaces",
NamespaceDTO[].class, appId,
clusterName);
NamespaceDTO[].class, appId,
clusterName);
return Arrays.asList(namespaceDTOs);
}
......@@ -62,7 +62,7 @@ public class AdminServiceAPI {
String namespaceName) {
NamespaceDTO dto =
restTemplate.get(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}",
NamespaceDTO.class, appId, clusterName, namespaceName);
NamespaceDTO.class, appId, clusterName, namespaceName);
return dto;
}
......@@ -70,7 +70,7 @@ public class AdminServiceAPI {
public NamespaceDTO createNamespace(Env env, NamespaceDTO namespace) {
return restTemplate
.post(env, "apps/{appId}/clusters/{clusterName}/namespaces", namespace, NamespaceDTO.class,
namespace.getAppId(), namespace.getClusterName());
namespace.getAppId(), namespace.getClusterName());
}
public AppNamespaceDTO createAppNamespace(Env env, AppNamespaceDTO appNamespace) {
......@@ -78,6 +78,11 @@ public class AdminServiceAPI {
.post(env, "apps/{appId}/appnamespaces", appNamespace, AppNamespaceDTO.class, appNamespace.getAppId());
}
public void deleteNamespace(Env env, String appId, String clusterName, String namespaceName, String operator) {
restTemplate.delete(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}?operator={operator}", appId, clusterName,
namespaceName, operator);
}
}
@Service
......@@ -86,7 +91,7 @@ public class AdminServiceAPI {
public List<ItemDTO> findItems(String appId, Env env, String clusterName, String namespaceName) {
ItemDTO[] itemDTOs =
restTemplate.get(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items",
ItemDTO[].class, appId, clusterName, namespaceName);
ItemDTO[].class, appId, clusterName, namespaceName);
return Arrays.asList(itemDTOs);
}
......@@ -98,18 +103,18 @@ public class AdminServiceAPI {
public void updateItemsByChangeSet(String appId, Env env, String clusterName, String namespace,
ItemChangeSets changeSets) {
restTemplate.post(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/itemset",
changeSets, Void.class, appId, clusterName, namespace);
changeSets, Void.class, appId, clusterName, namespace);
}
public void updateItem(String appId, Env env, String clusterName, String namespace, long itemId, ItemDTO item) {
restTemplate.put(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items/{itemId}",
item, appId, clusterName, namespace, itemId);
item, appId, clusterName, namespace, itemId);
}
public ItemDTO createItem(String appId, Env env, String clusterName, String namespace, ItemDTO item) {
return restTemplate.post(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items",
item, ItemDTO.class, appId, clusterName, namespace);
item, ItemDTO.class, appId, clusterName, namespace);
}
public void deleteItem(Env env, long itemId, String operator) {
......@@ -123,25 +128,29 @@ public class AdminServiceAPI {
public List<ClusterDTO> findClustersByApp(String appId, Env env) {
ClusterDTO[] clusterDTOs = restTemplate.get(env, "apps/{appId}/clusters", ClusterDTO[].class,
appId);
appId);
return Arrays.asList(clusterDTOs);
}
public ClusterDTO loadCluster(String appId, Env env, String clusterName) {
return restTemplate.get(env, "apps/{appId}/clusters/{clusterName}", ClusterDTO.class,
appId, clusterName);
appId, clusterName);
}
public boolean isClusterUnique(String appId, Env env, String clusterName) {
return restTemplate
.get(env, "apps/{appId}/cluster/{clusterName}/unique", Boolean.class,
appId, clusterName);
appId, clusterName);
}
public ClusterDTO create(Env env, ClusterDTO cluster) {
return restTemplate.post(env, "apps/{appId}/clusters", cluster, ClusterDTO.class,
cluster.getAppId());
cluster.getAppId());
}
public void delete(Env env, String appId, String clusterName, String operator) {
restTemplate.delete(env, "apps/{appId}/clusters/{clusterName}?operator={operator}", appId, clusterName, operator);
}
}
......@@ -175,7 +184,7 @@ public class AdminServiceAPI {
String namespace) {
ReleaseDTO releaseDTO = restTemplate
.get(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/releases/latest",
ReleaseDTO.class, appId, clusterName, namespace);
ReleaseDTO.class, appId, clusterName, namespace);
return releaseDTO;
}
......@@ -198,8 +207,8 @@ public class AdminServiceAPI {
public void rollback(Env env, long releaseId, String operator) {
restTemplate.put(env,
"releases/{releaseId}/rollback?operator={operator}",
null, releaseId, operator);
"releases/{releaseId}/rollback?operator={operator}",
null, releaseId, operator);
}
}
......@@ -209,9 +218,9 @@ public class AdminServiceAPI {
public List<CommitDTO> find(String appId, Env env, String clusterName, String namespaceName, int page, int size) {
CommitDTO[] commitDTOs = restTemplate.get(env,
"apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/commit?page={page}&size={size}",
CommitDTO[].class,
appId, clusterName, namespaceName, page, size);
"apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/commit?page={page}&size={size}",
CommitDTO[].class,
appId, clusterName, namespaceName, page, size);
return Arrays.asList(commitDTOs);
}
......@@ -222,8 +231,8 @@ public class AdminServiceAPI {
public NamespaceLockDTO getNamespaceLockOwner(String appId, Env env, String clusterName, String namespaceName) {
return restTemplate.get(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/lock",
NamespaceLockDTO.class,
appId, clusterName, namespaceName);
NamespaceLockDTO.class,
appId, clusterName, namespaceName);
}
}
......
......@@ -45,4 +45,12 @@ public class ClusterController {
return clusterService.createCluster(Env.valueOf(env), cluster);
}
@PreAuthorize(value = "@permissionValidator.isSuperAdmin()")
@RequestMapping(value = "apps/{appId}/envs/{env}/clusters/{clusterName:.+}", method = RequestMethod.DELETE)
public void deleteCluster(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName){
clusterService.deleteCluster(Env.valueOf(env), appId, clusterName);
}
}
......@@ -43,7 +43,6 @@ public class NamespaceController {
@Autowired
private AppService appService;
@Autowired
private ApplicationEventPublisher publisher;
@Autowired
......@@ -86,6 +85,14 @@ public class NamespaceController {
return ResponseEntity.ok().build();
}
@PreAuthorize(value = "@permissionValidator.isSuperAdmin()")
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName:.+}", method = RequestMethod.DELETE)
public ResponseEntity<Void> deleteNamespace(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName){
namespaceService.deleteNamespace(appId, Env.valueOf(env), clusterName, namespaceName);
return ResponseEntity.ok().build();
}
@PreAuthorize(value = "@permissionValidator.hasCreateAppNamespacePermission(#appId, #appNamespace)")
@RequestMapping(value = "/apps/{appId}/appnamespaces", method = RequestMethod.POST)
public AppNamespace createAppNamespace(@PathVariable String appId, @RequestBody AppNamespace appNamespace) {
......
......@@ -4,6 +4,7 @@ import com.ctrip.framework.apollo.common.dto.ClusterDTO;
import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.portal.api.AdminServiceAPI;
import com.ctrip.framework.apollo.portal.auth.UserInfoHolder;
import com.ctrip.framework.apollo.portal.constant.CatEventType;
import com.dianping.cat.Cat;
......@@ -15,6 +16,8 @@ import java.util.List;
@Service
public class ClusterService {
@Autowired
private UserInfoHolder userInfoHolder;
@Autowired
private AdminServiceAPI.ClusterAPI clusterAPI;
......@@ -33,4 +36,8 @@ public class ClusterService {
return clusterDTO;
}
public void deleteCluster(Env env, String appId, String clusterName){
clusterAPI.delete(env, appId, clusterName, userInfoHolder.getUser().getUserId());
}
}
package com.ctrip.framework.apollo.portal.service;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.ctrip.framework.apollo.common.dto.ItemDTO;
import com.ctrip.framework.apollo.common.dto.NamespaceDTO;
......@@ -22,6 +23,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
......@@ -32,6 +34,8 @@ public class NamespaceService {
private Logger logger = LoggerFactory.getLogger(NamespaceService.class);
private Gson gson = new Gson();
private static Type mapType = new TypeToken<Map<String, String>>() {
}.getType();
@Autowired
private UserInfoHolder userInfoHolder;
......@@ -58,6 +62,10 @@ public class NamespaceService {
return createdNamespace;
}
public void deleteNamespace(String appId, Env env, String clusterName, String namespaceName){
namespaceAPI.deleteNamespace(env, appId, clusterName, namespaceName, userInfoHolder.getUser().getUserId());
}
public NamespaceDTO loadNamespaceBaseInfo(String appId, Env env, String clusterName, String namespaceName) {
NamespaceDTO namespace = namespaceAPI.loadNamespace(appId, env, clusterName, namespaceName);
if (namespace == null) {
......@@ -101,7 +109,6 @@ public class NamespaceService {
return parseNamespace(appId, env, clusterName, namespace);
}
@SuppressWarnings("unchecked")
private NamespaceVO parseNamespace(String appId, Env env, String clusterName, NamespaceDTO namespace) {
NamespaceVO namespaceVO = new NamespaceVO();
namespaceVO.setBaseInfo(namespace);
......@@ -118,7 +125,7 @@ public class NamespaceService {
Map<String, String> releaseItems = new HashMap<>();
latestRelease = releaseService.loadLatestRelease(appId, env, clusterName, namespaceName);
if (latestRelease != null) {
releaseItems = gson.fromJson(latestRelease.getConfigurations(), Map.class);
releaseItems = gson.fromJson(latestRelease.getConfigurations(), mapType);
}
//not Release config items
......
......@@ -24,9 +24,6 @@
</header>
<div class="panel-body">
<div class="alert alert-info" role="alert">
apollo系统目前正在框架部门内测阶段,如非框架项目接入请先联系song_s@ctrip.com,zhanglea@ctrip.com
</div>
<form class="form-horizontal" name="appForm" ng-controller="CreateAppController" valdr-type="App"
ng-submit="create()">
<div class="form-group">
......
......@@ -118,8 +118,9 @@
apollo-show-cancel-btn="true" apollo-confirm="rollback"></apolloconfirmdialog>
<!--create createRelease modal-->
<form class="modal fade form-horizontal" name="releaseForm" valdr-type="Release" id="releaseModal" tabindex="-1" role="dialog"
<!--create release modal-->
<form class="modal fade form-horizontal" name="releaseForm" valdr-type="Release" id="releaseModal"
tabindex="-1" role="dialog"
ng-submit="release()">
<div class="modal-dialog" role="document" style="width: 960px">
<div class="modal-content">
......@@ -130,8 +131,19 @@
</div>
<div class="modal-body">
<div class="form-group">
<label class="col-sm-2 control-label">
Changes:</label>
<div class="col-sm-2 control-label" ng-if="!toReleaseNamespace.isPropertiesFormat">
<div class="row">
<div class="btn-group btn-group-xs" style="padding-right: 10px" role="group">
<button type="button" class="btn btn-default" ng-class="{active:releaseChangeViewType=='change'}"
ng-click="switchReleaseChangeViewType('change')">查看变更
</button>
<button type="button" class="btn btn-default" ng-class="{active:releaseChangeViewType=='release'}"
ng-click="switchReleaseChangeViewType('release')">发布的值
</button>
</div>
</div>
</div>
<label class="col-sm-2 control-label" ng-if="toReleaseNamespace.isPropertiesFormat">Changes</label>
<div class="col-sm-10" ng-if="toReleaseNamespace.itemModifiedCnt" valdr-form-group>
<!--properites format-->
......@@ -186,17 +198,15 @@
<!--file format -->
<div ng-repeat="item in toReleaseNamespace.items"
ng-if="!toReleaseNamespace.isPropertiesFormat">
<h3>new value</h3>
<textarea class="form-control" rows="20" style="border-radius: 0px"
ng-disabled="true" ng-show="item.newValue" ng-bind="item.newValue">
</textarea>
<hr>
<h3>old value</h3>
ng-if="!toReleaseNamespace.isPropertiesFormat" ng-show="releaseChangeViewType=='change'">
<apollodiff old-str="item.oldValue" new-str="item.newValue"
apollo-id="'releaseStrDiff'"></apollodiff>
</div>
<div ng-repeat="item in toReleaseNamespace.items"
ng-if="!toReleaseNamespace.isPropertiesFormat" ng-show="releaseChangeViewType=='release'">
<textarea class="form-control" rows="20" style="border-radius: 0px"
ng-disabled="true" ng-show="item.oldValue" ng-bind="item.oldValue">
</textarea>
<h4 ng-show="!item.oldValue"></h4>
ng-disabled="true" ng-show="item.newValue" ng-bind="item.newValue">
</textarea>
</div>
</div>
......@@ -205,21 +215,22 @@
配置没有变化
</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">
<apollorequiredfiled></apollorequiredfiled>
Release Name:</label>
<div class="col-sm-5" valdr-form-group>
<input type="text" name="releaseName" class="form-control" placeholder="input release name"
<input type="text" name="releaseName" class="form-control"
placeholder="input release name"
ng-model="releaseTitle" ng-required="true">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Comment:</label>
<div class="col-sm-10" valdr-form-group>
<textarea rows="4" name="comment" class="form-control" style="margin-top: 15px;"
<textarea rows="4" name="comment" class="form-control"
style="margin-top: 15px;"
ng-model="releaseComment"
placeholder="Add an optional extended description..."></textarea>
</div>
......@@ -229,7 +240,8 @@
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="submit" class="btn btn-primary" ng-disabled="releaseForm.$invalid || releaseBtnDisabled">发布
<button type="submit" class="btn btn-primary"
ng-disabled="releaseForm.$invalid || releaseBtnDisabled">发布
</button>
</div>
</div>
......@@ -237,15 +249,16 @@
</form>
<!--table mode item modal-->
<form class="modal fade form-horizontal" name="itemForm" valdr-type="Item" id="itemModal" role="dialog" ng-submit="doItem()">
<form class="modal fade form-horizontal" name="itemForm" valdr-type="Item" id="itemModal" role="dialog"
ng-submit="doItem()">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header panel-primary">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
<button type="button" class="close" data-dismiss="modal" aria-label="Close"
ng-click="cancelEdit()"><span
aria-hidden="true">&times;</span></button>
<h4 class="modal-title">
<span ng-show="tableViewOperType == 'create'"> 添加配置项</span>
<span ng-show="tableViewOperType == 'retrieve'"> 查看配置项</span>
<span ng-show="tableViewOperType == 'update'"> 修改配置项</span>
</h4>
</div>
......@@ -253,7 +266,7 @@
<div class="form-group">
<label class="col-sm-2 control-label">
<apollorequiredfiled
ng-show="tableViewOperType != 'retrieve'"></apollorequiredfiled>
ng-show="tableViewOperType == 'create'"></apollorequiredfiled>
Key
</label>
<div class="col-sm-10" valdr-form-group>
......@@ -263,19 +276,20 @@
</div>
<div class="form-group">
<label class="col-sm-2 control-label">
<apollorequiredfiled
ng-show="tableViewOperType != 'retrieve'"></apollorequiredfiled>
<apollorequiredfiled></apollorequiredfiled>
Value
</label>
<div class="col-sm-10" valdr-form-group>
<textarea type="text" name="value" class="form-control" rows="6" ng-model="item.value">
<textarea type="text" name="value" class="form-control" rows="6"
ng-model="item.value">
</textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Comment</label>
<div class="col-sm-10" valdr-form-group>
<textarea class="form-control" name="comment" ng-model="item.comment" rows="2">
<textarea class="form-control" name="comment" ng-model="item.comment"
rows="2">
</textarea>
</div>
</div>
......@@ -295,14 +309,13 @@
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" ng-click="switchToEdit()"
ng-show="tableViewOperType == 'retrieve' && hasModifyPermission">修改
</button>
<button type="button" class="btn btn-default" data-dismiss="modal">关闭
<button type="button" class="btn btn-default" data-dismiss="modal" ng-click="cancelEdit()">
关闭
</button>
<button type="submit" class="btn btn-primary"
ng-show="tableViewOperType != 'retrieve'"
ng-disabled="itemForm.$invalid || (addItemBtnDisabled && tableViewOperType == 'create')">提交
ng-disabled="itemForm.$invalid || (addItemBtnDisabled && tableViewOperType == 'create')">
提交
</button>
</div>
</div>
......@@ -438,6 +451,8 @@
<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>
<!--valdr-->
<script src="vendor/valdr/valdr.min.js" type="text/javascript"></script>
......@@ -462,6 +477,7 @@
<!--directive-->
<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/diff-directive.js"></script>
<!--controller-->
<script type="application/javascript" src="scripts/controller/config/ConfigNamespaceController.js"></script>
......
......@@ -17,6 +17,7 @@ $(document).ready(function () {
$('[data-tooltip="tooltip"]').tooltip();
$("textarea").niceScroll({styler: "fb", cursorcolor: "#fff"});
$("pre").niceScroll({styler: "fb", cursorcolor: "#fff"});
}, 2500);
});
......
......@@ -13,7 +13,6 @@ application_module.controller("ConfigNamespaceController",
};
var TABLE_VIEW_OPER_TYPE = {
RETRIEVE: 'retrieve',
CREATE: 'create',
UPDATE: 'update'
};
......@@ -25,6 +24,8 @@ application_module.controller("ConfigNamespaceController",
$scope.prepareReleaseNamespace = prepareReleaseNamespace;
$scope.release = release;
$scope.switchReleaseChangeViewType = switchReleaseChangeViewType;
$scope.showRollbackAlertDialog = showRollbackAlertDialog;
......@@ -32,13 +33,13 @@ application_module.controller("ConfigNamespaceController",
$scope.rollback = rollback;
$scope.retrieveItem = retrieveItem;
$scope.preDeleteItem = preDeleteItem;
$scope.deleteItem = deleteItem;
$scope.editItem = editItem;
$scope.cancelEdit = cancelEdit;
$scope.createItem = createItem;
......@@ -152,6 +153,11 @@ application_module.controller("ConfigNamespaceController",
}
);
}
$scope.releaseChangeViewType = 'change';
function switchReleaseChangeViewType(type) {
$scope.releaseChangeViewType = type;
}
function showRollbackAlertDialog() {
$("#rollbackModal").modal('hide');
......@@ -209,15 +215,6 @@ application_module.controller("ConfigNamespaceController",
$scope.tableViewOperType = '', $scope.item = {};
var toOperationNamespace;
//查看配置
function retrieveItem(namespace, item, oldValue) {
switchTableViewOperType(TABLE_VIEW_OPER_TYPE.RETRIEVE);
$scope.item = item;
$scope.item.oldValue = oldValue;
toOperationNamespace = namespace;
$scope.hasModifyPermission = namespace.hasModifyPermission;
}
var toDeleteItemId = 0;
function preDeleteItem(namespace, itemId) {
......@@ -245,6 +242,7 @@ application_module.controller("ConfigNamespaceController",
});
}
var backupItem = {};
//修改配置
function editItem(namespace, item) {
if (!lockCheck(namespace)) {
......@@ -252,10 +250,19 @@ application_module.controller("ConfigNamespaceController",
}
switchTableViewOperType(TABLE_VIEW_OPER_TYPE.UPDATE);
$scope.item = item;
backupItem.value = item.value;
backupItem.comment = item.comment;
toOperationNamespace = namespace;
$("#itemModal").modal("show");
}
function cancelEdit() {
if($scope.tableViewOperType = TABLE_VIEW_OPER_TYPE.UPDATE){
$scope.item.value = backupItem.value;
$scope.item.comment = backupItem.comment;
}
}
//新增配置
function createItem(namespace) {
......
directive_module.directive('apollodiff',
function ($compile, $window) {
return {
restrict: 'E',
templateUrl: '../../views/component/diff.html',
transclude: true,
replace: true,
scope: {
oldStr: '=',
newStr: '=',
apolloId: '='
},
link: function (scope, element, attrs) {
scope.$watch('oldStr', makeDiff);
scope.$watch('newStr', makeDiff);
function makeDiff() {
var displayArea = document.getElementById(scope.apolloId);
if (!displayArea){
return;
}
//clear
displayArea.innerHTML = '';
var color = '',
span = null,
pre = '';
var diff = JsDiff.diffLines(scope.oldStr, scope.newStr),
fragment = document.createDocumentFragment();
diff.forEach(function (part) {
// green for additions, red for deletions
// grey for common parts
color = part.added ? 'green' :
part.removed ? 'red' : 'grey';
span = document.createElement('span');
span.style.color = color;
pre = part.added ? '+' :
part.removed ? '-' : '';
span.appendChild(document.createTextNode(pre + part.value));
fragment.appendChild(span);
});
displayArea.appendChild(fragment);
}
}
}
});
......@@ -232,8 +232,8 @@
</thead>
<tbody>
<tr ng-repeat="item in commits.changeSets.createItems"
ng-show="item.key || item.comment">
<!--兼容老数据,不显示item类型为空行和注释的item-->
<tr ng-repeat="item in commits.changeSets.createItems" ng-show="item.key">
<td width="2%">
新增
</td>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册