提交 37451643 编写于 作者: L lepdou

add namespace publish info tips

上级 7e4f6bcc
......@@ -17,6 +17,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
@RestController
public class NamespaceController {
......@@ -89,4 +90,14 @@ public class NamespaceController {
return BeanUtils.transfrom(NamespaceDTO.class, namespace);
}
/**
* cluster -> cluster has not published namespaces?
*/
@RequestMapping("/apps/{appId}/namespaces/publish_info")
public Map<String, Boolean> namespacePublishInfo(@PathVariable String appId){
return namespaceService.namespacePublishInfo(appId);
}
}
......@@ -6,6 +6,7 @@ import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import java.util.Date;
import java.util.List;
public interface ItemRepository extends PagingAndSortingRepository<Item, Long> {
......@@ -14,6 +15,8 @@ public interface ItemRepository extends PagingAndSortingRepository<Item, Long> {
List<Item> findByNamespaceIdOrderByLineNumAsc(Long namespaceId);
List<Item> findByNamespaceIdAndDataChangeLastModifiedTimeGreaterThan(Long namespaceId, Date date);
Item findFirst1ByNamespaceIdOrderByLineNumDesc(Long namespaceId);
@Modifying
......
......@@ -12,13 +12,10 @@ public class AdminService {
@Autowired
private AppService appService;
@Autowired
private AppNamespaceService appNamespaceService;
@Autowired
private ClusterService clusterService;
@Autowired
private NamespaceService namespaceService;
......@@ -38,4 +35,5 @@ public class AdminService {
return app;
}
}
......@@ -23,6 +23,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
......@@ -168,6 +169,10 @@ public class ItemService implements InitializingBean {
}
}
public List<Item> findItemsModifiedAfterDate(long namespaceId, Date date) {
return itemRepository.findByNamespaceIdAndDataChangeLastModifiedTimeGreaterThan(namespaceId, date);
}
@Transactional
public Item save(Item entity) {
checkItemKeyLength(entity.getKey());
......
package com.ctrip.framework.apollo.biz.service;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.ctrip.framework.apollo.biz.entity.Audit;
import com.ctrip.framework.apollo.biz.entity.Cluster;
import com.ctrip.framework.apollo.biz.entity.Item;
import com.ctrip.framework.apollo.biz.entity.Namespace;
import com.ctrip.framework.apollo.biz.entity.Release;
import com.ctrip.framework.apollo.biz.repository.NamespaceRepository;
import com.ctrip.framework.apollo.common.constants.GsonType;
import com.ctrip.framework.apollo.common.constants.NamespaceBranchStatus;
import com.ctrip.framework.apollo.common.entity.AppNamespace;
import com.ctrip.framework.apollo.common.exception.BadRequestException;
......@@ -17,7 +23,9 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
......@@ -25,6 +33,8 @@ import java.util.stream.Collectors;
@Service
public class NamespaceService {
private Gson gson = new Gson();
@Autowired
private NamespaceRepository namespaceRepository;
@Autowired
......@@ -246,5 +256,59 @@ public class NamespaceService {
}
public Map<String, Boolean> namespacePublishInfo(String appId) {
List<Cluster> clusters = clusterService.findParentClusters(appId);
if (CollectionUtils.isEmpty(clusters)) {
throw new BadRequestException("app not exist");
}
Map<String, Boolean> clusterHasNotPublishedItems = Maps.newHashMap();
for (Cluster cluster : clusters) {
String clusterName = cluster.getName();
List<Namespace> namespaces = findNamespaces(appId, clusterName);
for (Namespace namespace: namespaces) {
boolean isNamespaceNotPublished = isNamespaceNotPublished(namespace);
if (isNamespaceNotPublished){
clusterHasNotPublishedItems.put(clusterName, true);
break;
}
}
clusterHasNotPublishedItems.putIfAbsent(clusterName, false);
}
return clusterHasNotPublishedItems;
}
private boolean isNamespaceNotPublished(Namespace namespace) {
Release latestRelease = releaseService.findLatestActiveRelease(namespace);
long namespaceId = namespace.getId();
if (latestRelease == null) {
Item lastItem = itemService.findLastOne(namespaceId);
return lastItem != null;
}
Date lastPublishTime = latestRelease.getDataChangeLastModifiedTime();
List<Item> itemsModifiedAfterLastPublish = itemService.findItemsModifiedAfterDate(namespaceId, lastPublishTime);
if (CollectionUtils.isEmpty(itemsModifiedAfterLastPublish)) {
return false;
}
Map<String, String> publishedConfiguration = gson.fromJson(latestRelease.getConfigurations(), GsonType.CONFIG);
for (Item item: itemsModifiedAfterLastPublish) {
if (!Objects.equals(item.getValue(), publishedConfiguration.get(item.getKey()))){
return true;
}
}
return false;
}
}
package com.ctrip.framework.apollo.biz.service;
import com.ctrip.framework.apollo.biz.AbstractUnitTest;
import com.ctrip.framework.apollo.biz.entity.Cluster;
import com.ctrip.framework.apollo.biz.entity.Item;
import com.ctrip.framework.apollo.biz.entity.Namespace;
import com.ctrip.framework.apollo.biz.entity.Release;
import com.ctrip.framework.apollo.biz.repository.NamespaceRepository;
import com.ctrip.framework.apollo.core.ConfigConsts;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import java.util.Collections;
import java.util.Map;
import java.util.Random;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.when;
public class NamespacePublishInfoTest extends AbstractUnitTest {
@Mock
private ClusterService clusterService;
@Mock
private ReleaseService releaseService;
@Mock
private ItemService itemService;
@Mock
private NamespaceRepository namespaceRepository;
@InjectMocks
private NamespaceService namespaceService;
private String testApp = "testApp";
@Test
public void testNamespaceNotEverPublishedButHasItems() {
Cluster cluster = createCluster(ConfigConsts.CLUSTER_NAME_DEFAULT);
Namespace namespace = createNamespace(ConfigConsts.CLUSTER_NAME_DEFAULT, ConfigConsts.NAMESPACE_APPLICATION);
Item item = createItem(namespace.getId(), "a", "b");
when(clusterService.findParentClusters(testApp)).thenReturn(Collections.singletonList(cluster));
when(namespaceRepository.findByAppIdAndClusterNameOrderByIdAsc(testApp, ConfigConsts.CLUSTER_NAME_DEFAULT))
.thenReturn(Collections.singletonList(namespace));
when(itemService.findLastOne(anyLong())).thenReturn(item);
Map<String, Boolean> result = namespaceService.namespacePublishInfo(testApp);
Assert.assertEquals(1, result.size());
Assert.assertTrue(result.get(ConfigConsts.CLUSTER_NAME_DEFAULT));
}
@Test
public void testNamespaceEverPublishedAndNotModifiedAfter() {
Cluster cluster = createCluster(ConfigConsts.CLUSTER_NAME_DEFAULT);
Namespace namespace = createNamespace(ConfigConsts.CLUSTER_NAME_DEFAULT, ConfigConsts.NAMESPACE_APPLICATION);
Item item = createItem(namespace.getId(), "a", "b");
Release release = createRelease("{\"a\":\"b\"}");
when(clusterService.findParentClusters(testApp)).thenReturn(Collections.singletonList(cluster));
when(namespaceRepository.findByAppIdAndClusterNameOrderByIdAsc(testApp, ConfigConsts.CLUSTER_NAME_DEFAULT))
.thenReturn(Collections.singletonList(namespace));
when(releaseService.findLatestActiveRelease(namespace)).thenReturn(release);
when(itemService.findItemsModifiedAfterDate(anyLong(), anyObject())).thenReturn(Collections.singletonList(item));
Map<String, Boolean> result = namespaceService.namespacePublishInfo(testApp);
Assert.assertEquals(1, result.size());
Assert.assertFalse(result.get(ConfigConsts.CLUSTER_NAME_DEFAULT));
}
@Test
public void testNamespaceEverPublishedAndModifiedAfter() {
Cluster cluster = createCluster(ConfigConsts.CLUSTER_NAME_DEFAULT);
Namespace namespace = createNamespace(ConfigConsts.CLUSTER_NAME_DEFAULT, ConfigConsts.NAMESPACE_APPLICATION);
Item item = createItem(namespace.getId(), "a", "b");
Release release = createRelease("{\"a\":\"c\"}");
when(clusterService.findParentClusters(testApp)).thenReturn(Collections.singletonList(cluster));
when(namespaceRepository.findByAppIdAndClusterNameOrderByIdAsc(testApp, ConfigConsts.CLUSTER_NAME_DEFAULT))
.thenReturn(Collections.singletonList(namespace));
when(releaseService.findLatestActiveRelease(namespace)).thenReturn(release);
when(itemService.findItemsModifiedAfterDate(anyLong(), anyObject())).thenReturn(Collections.singletonList(item));
Map<String, Boolean> result = namespaceService.namespacePublishInfo(testApp);
Assert.assertEquals(1, result.size());
Assert.assertTrue(result.get(ConfigConsts.CLUSTER_NAME_DEFAULT));
}
private Cluster createCluster(String clusterName) {
Cluster cluster = new Cluster();
cluster.setAppId(testApp);
cluster.setName(clusterName);
cluster.setParentClusterId(0);
return cluster;
}
private Namespace createNamespace(String clusterName, String namespaceName) {
Namespace namespace = new Namespace();
namespace.setAppId(testApp);
namespace.setClusterName(clusterName);
namespace.setNamespaceName(namespaceName);
namespace.setId(new Random().nextLong());
return namespace;
}
private Item createItem(long namespaceId, String key, String value) {
Item item = new Item();
item.setNamespaceId(namespaceId);
item.setKey(key);
item.setValue(value);
return item;
}
private Release createRelease(String configuration) {
Release release = new Release();
release.setConfigurations(configuration);
return release;
}
}
......@@ -32,6 +32,7 @@ import org.springframework.util.MultiValueMap;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
......@@ -62,6 +63,10 @@ public class AdminServiceAPI {
@Service
public static class NamespaceAPI extends API {
private ParameterizedTypeReference<Map<String, Boolean>>
typeReference = new ParameterizedTypeReference<Map<String, Boolean>>() {
};
public List<NamespaceDTO> findNamespaceByCluster(String appId, Env env, String clusterName) {
NamespaceDTO[] namespaceDTOs = restTemplate.get(env, "apps/{appId}/clusters/{clusterName}/namespaces",
NamespaceDTO[].class, appId,
......@@ -100,6 +105,10 @@ public class AdminServiceAPI {
namespaceName, operator);
}
public Map<String, Boolean> getNamespacePublishInfo(Env env, String appId) {
return restTemplate.get(env, "apps/{appId}/namespaces/publish_info", typeReference, appId).getBody();
}
}
@Service
......
......@@ -35,10 +35,10 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
import static com.ctrip.framework.apollo.common.utils.RequestPrecondition.checkModel;
......@@ -169,4 +169,18 @@ public class NamespaceController {
return createdAppNamespace;
}
/**
* env -> cluster -> cluster has not published namespace?
* Example:
* dev ->
* default -> true (default cluster has not published namespace)
* customCluster -> false (customCluster cluster's all namespaces had published)
*
*/
@RequestMapping("/apps/{appId}/namespaces/publish_info")
public Map<String, Map<String, Boolean>> getNamespacesPublishInfo(@PathVariable String appId) {
return namespaceService.getNamespacesPublishInfo(appId);
}
}
package com.ctrip.framework.apollo.portal.service;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.ctrip.framework.apollo.common.constants.GsonType;
......@@ -14,6 +15,7 @@ import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.core.utils.StringUtils;
import com.ctrip.framework.apollo.portal.api.AdminServiceAPI;
import com.ctrip.framework.apollo.portal.components.PortalSettings;
import com.ctrip.framework.apollo.portal.constant.CatEventType;
import com.ctrip.framework.apollo.portal.entity.bo.ItemBO;
import com.ctrip.framework.apollo.portal.entity.bo.NamespaceBO;
......@@ -39,6 +41,8 @@ public class NamespaceService {
private Logger logger = LoggerFactory.getLogger(NamespaceService.class);
private Gson gson = new Gson();
@Autowired
private PortalSettings portalSettings;
@Autowired
private UserInfoHolder userInfoHolder;
@Autowired
......@@ -100,10 +104,10 @@ public class NamespaceService {
List<NamespaceBO> namespaceBOs = new LinkedList<>();
for (NamespaceDTO namespace : namespaces) {
NamespaceBO namesapceBO = null;
NamespaceBO namespaceBO = null;
try {
namesapceBO = transformNamespace2BO(appId, env, clusterName, namespace);
namespaceBOs.add(namesapceBO);
namespaceBO = transformNamespace2BO(appId, env, clusterName, namespace);
namespaceBOs.add(namespaceBO);
} catch (Exception e) {
logger.error("parse namespace error. app id:{}, env:{}, clusterName:{}, namespace:{}",
appId, env, clusterName, namespace.getNamespaceName(), e);
......@@ -131,6 +135,17 @@ public class NamespaceService {
return transformNamespace2BO(appId, env, actualClusterName, namespace);
}
public Map<String, Map<String, Boolean>> getNamespacesPublishInfo(String appId) {
Map<String, Map<String, Boolean>> result = Maps.newHashMap();
List<Env> envs = portalSettings.getActiveEnvs();
for (Env env: envs) {
result.put(env.toString(), namespaceAPI.getNamespacePublishInfo(env, appId));
}
return result;
}
private NamespaceBO transformNamespace2BO(String appId, Env env, String clusterName, NamespaceDTO namespace) {
NamespaceBO namespaceBO = new NamespaceBO();
namespaceBO.setBaseInfo(namespace);
......
......@@ -40,6 +40,7 @@
<strong>Tips:</strong>
<ul>
<li>通过添加集群,可以使同一份程序在不同的集群(如不同的数据中心)使用不同的配置</li>
<li>如果不同集群使用一样的配置,则没有必要创建集群</li>
<li>
Apollo默认会读取机器上/opt/settings/server.properties(linux)或C:\opt\settings\server.properties(windows)文件中的idc属性作为集群名字,
如SHAJQ(金桥数据中心)、SHAOY(欧阳数据中心)
......
......@@ -137,7 +137,7 @@
<!--namespaces-->
<div class="col-md-10 col-xs-10 col-sm-10 config-item-container hide"
ng-controller="ConfigNamespaceController">
<div class="alert alert-warning alert-dismissible" role="alert"
<div class="alert alert-info alert-dismissible" role="alert"
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;"
......@@ -146,7 +146,7 @@
<!--default cluster tip -->
<div ng-show="pageContext.clusterName == 'default'">
<strong>注意:</strong>所有不属于
<strong>注意: </strong>所有不属于
<span ng-bind="envMapClusters[pageContext.env]"></span>
集群的实例会使用default集群(当前页面)的配置,属于
<span ng-bind="envMapClusters[pageContext.env]"></span>
......@@ -164,6 +164,11 @@
</div>
<div class="alert alert-info"
ng-if="hasNotPublishNamespace">
<p><b>注意:</b>以下环境/集群有未发布的配置,客户端获取不到未发布的配置,请及时发布。</p>
<p><mark ng-bind="namespacePublishInfo.join(',')"></mark></p>
</div>
<apollonspanel ng-repeat="namespace in namespaces"
namespace="namespace"
......@@ -336,6 +341,7 @@
<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/PermissionService.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/NamespaceLockService.js"></script>
<script type="application/javascript" src="scripts/services/InstanceService.js"></script>
......
......@@ -20,9 +20,11 @@ $(document).ready(function () {
}, 2500);
setTimeout(function () {
$("textarea").niceScroll({cursoropacitymax: 0});
$("pre").niceScroll({cursoropacitymax: 0});
$(".release-history-list").niceScroll({cursoropacitymax: 0});
}, 2500);
});
......
......@@ -119,6 +119,7 @@ function ConfigBaseInfoController($rootScope, $scope, $location, toastr, EventMa
}
function loadNavTree() {
AppService.load_nav_tree($rootScope.pageContext.appId).then(function (result) {
var navTree = [];
var nodes = AppUtil.collectData(result);
......@@ -140,6 +141,7 @@ function ConfigBaseInfoController($rootScope, $scope, $location, toastr, EventMa
}
var node = {};
node.text = env.env;
var clusterNodes = [];
//如果env下面只有一个default集群则不显示集群列表
......@@ -150,6 +152,7 @@ function ConfigBaseInfoController($rootScope, $scope, $location, toastr, EventMa
node.state.selected = true;
}
node.selectable = true;
} else {
node.selectable = false;
//cluster list
......@@ -169,6 +172,7 @@ function ConfigBaseInfoController($rootScope, $scope, $location, toastr, EventMa
clusterNode.tags = ['集群'];
clusterNode.parentNode = parentNode;
clusterNodes.push(clusterNode);
});
}
node.nodes = clusterNodes;
......@@ -229,6 +233,7 @@ function ConfigBaseInfoController($rootScope, $scope, $location, toastr, EventMa
}, function (result) {
toastr.error(AppUtil.errorMsg(result), "系统出错,请重试或联系系统负责人");
});
}
function handleFavorite() {
......
application_module.controller("ConfigNamespaceController",
['$rootScope', '$scope', 'toastr', 'AppUtil', 'EventManager', 'ConfigService',
'PermissionService', 'UserService', 'NamespaceBranchService',
'PermissionService', 'UserService', 'NamespaceBranchService', 'NamespaceService',
controller]);
function controller($rootScope, $scope, toastr, AppUtil, EventManager, ConfigService,
PermissionService, UserService, NamespaceBranchService) {
PermissionService, UserService, NamespaceBranchService, NamespaceService) {
$scope.rollback = rollback;
$scope.preDeleteItem = preDeleteItem;
......@@ -21,9 +21,15 @@ function controller($rootScope, $scope, toastr, AppUtil, EventManager, ConfigSer
$scope.lockCheck = lockCheck;
init();
function init() {
initRole();
initUser();
initPublishInfo();
}
function initRole() {
PermissionService.get_app_role_users($rootScope.pageContext.appId)
.then(function (result) {
var masterUsers = '';
......@@ -34,18 +40,56 @@ function controller($rootScope, $scope, toastr, AppUtil, EventManager, ConfigSer
}, function (result) {
});
}
function initUser() {
UserService.load_user().then(function (result) {
$scope.currentUser = result.userId;
});
}
function initPublishInfo() {
NamespaceService.getNamespacePublishInfo($rootScope.pageContext.appId)
.then(function (result) {
if (!result) {
return;
}
$scope.hasNotPublishNamespace = false;
var namespacePublishInfo = [];
Object.keys(result).forEach(function (env) {
if (env.indexOf("$") >= 0) {
return;
}
var envPublishInfo = result[env];
Object.keys(envPublishInfo).forEach(function (cluster) {
var clusterPublishInfo = envPublishInfo[cluster];
if (clusterPublishInfo) {
$scope.hasNotPublishNamespace = true;
if (Object.keys(envPublishInfo).length > 1) {
namespacePublishInfo.push("[" + env + ", " + cluster + "]");
} else {
namespacePublishInfo.push("[" + env + "]");
}
}
})
});
$scope.namespacePublishInfo = namespacePublishInfo;
});
}
EventManager.subscribe(EventManager.EventType.REFRESH_NAMESPACE,
function (context) {
if (context.namespace){
if (context.namespace) {
refreshSingleNamespace(context.namespace);
}else {
} else {
refreshAllNamespaces();
}
......@@ -57,20 +101,19 @@ function controller($rootScope, $scope, toastr, AppUtil, EventManager, ConfigSer
}
ConfigService.load_all_namespaces($rootScope.pageContext.appId,
$rootScope.pageContext.env,
$rootScope.pageContext.clusterName).then(
$rootScope.pageContext.env,
$rootScope.pageContext.clusterName).then(
function (result) {
$scope.namespaces = result;
$('.config-item-container').removeClass('hide');
initPublishInfo();
}, function (result) {
toastr.error(AppUtil.errorMsg(result), "加载配置信息出错");
});
}
function refreshSingleNamespace(namespace) {
if ($rootScope.pageContext.env == '') {
return;
......@@ -83,17 +126,18 @@ function controller($rootScope, $scope, toastr, AppUtil, EventManager, ConfigSer
function (result) {
$scope.namespaces.forEach(function (namespace, index) {
if (namespace.baseInfo.namespaceName == result.baseInfo.namespaceName){
if (namespace.baseInfo.namespaceName == result.baseInfo.namespaceName) {
$scope.namespaces[index] = result;
}
})
}
});
initPublishInfo();
}, function (result) {
toastr.error(AppUtil.errorMsg(result), "加载配置信息出错");
});
}
function rollback() {
EventManager.emit(EventManager.EventType.ROLLBACK_NAMESPACE);
}
......@@ -268,10 +312,6 @@ function controller($rootScope, $scope, toastr, AppUtil, EventManager, ConfigSer
}
new Clipboard('.clipboard');
}
......
......@@ -101,6 +101,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
initNamespaceInstancesCount(namespace);
initPermission(namespace);
initLinkedNamespace(namespace);
loadInstanceInfo(namespace);
function initNamespaceBranch(namespace) {
NamespaceBranchService.findNamespaceBranch(scope.appId, scope.env,
......@@ -237,12 +238,11 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
linkNamespaceItemKeys.push(key);
});
publicNamespace.viewItems = [];
publicNamespace.items.forEach(function (item) {
var key = item.item.key;
if (key){
if (key) {
publicNamespace.viewItems.push(item);
}
......@@ -250,7 +250,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
if (item.isModified || item.isDeleted) {
publicNamespace.isModified = true;
} else if (key){
} else if (key) {
publicNamespace.hasPublishedItem = true;
}
});
......@@ -410,28 +410,26 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
if (namespace_instance_view_type.LATEST_RELEASE == type) {
if (!namespace.latestRelease) {
ReleaseService.findActiveReleases(scope.appId,
scope.env,
namespace.baseInfo.clusterName,
namespace.baseInfo.namespaceName,
0, 1).then(function (result) {
var latestRelease = result[0];
if (!latestRelease) {
namespace.latestReleaseInstances = {};
namespace.latestReleaseInstances.total = 0;
return;
}
namespace.latestRelease = latestRelease;
InstanceService.findInstancesByRelease(scope.env,
latestRelease.id,
namespace.latestReleaseInstancesPage,
size)
.then(function (result) {
namespace.latestReleaseInstances = result;
namespace.latestReleaseInstancesPage++;
})
});
ReleaseService.findLatestActiveRelease(scope.appId,
scope.env,
namespace.baseInfo.clusterName,
namespace.baseInfo.namespaceName)
.then(function (result) {
if (!result) {
namespace.latestReleaseInstances = {};
namespace.latestReleaseInstances.total = 0;
return;
}
namespace.latestRelease = result;
InstanceService.findInstancesByRelease(scope.env,
namespace.latestRelease.id,
namespace.latestReleaseInstancesPage,
size)
.then(function (result) {
namespace.latestReleaseInstances = result;
namespace.latestReleaseInstancesPage++;
})
});
} else {
InstanceService.findInstancesByRelease(scope.env,
namespace.latestRelease.id,
......@@ -781,8 +779,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
setTimeout(function () {
scope.namespace.show = true;
}, 200);
}, 70);
}
}
}
......
......@@ -14,41 +14,65 @@ appService.service("NamespaceService", ['$resource', '$q', function ($resource,
method: 'POST',
url: '/apps/:appId/appnamespaces',
isArray: false
},
getNamespacePublishInfo: {
method: 'GET',
url: '/apps/:appId/namespaces/publish_info'
}
});
function find_public_namespaces() {
var d = $q.defer();
namespace_source.find_public_namespaces({}, function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
});
return d.promise;
}
function createNamespace(appId, namespaceCreationModel) {
var d = $q.defer();
namespace_source.createNamespace({
appId: appId
}, namespaceCreationModel, function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
});
return d.promise;
}
function createAppNamespace(appId, appnamespace) {
var d = $q.defer();
namespace_source.createAppNamespace({
appId: appId
}, appnamespace, function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
});
return d.promise;
}
function getNamespacePublishInfo(appId) {
var d = $q.defer();
namespace_source.getNamespacePublishInfo({
appId: appId
}, function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
})
return d.promise;
}
return {
find_public_namespaces: function () {
var d = $q.defer();
namespace_source.find_public_namespaces({}, function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
});
return d.promise;
},
createNamespace: function (appId, namespaceCreationModel) {
var d = $q.defer();
namespace_source.createNamespace({
appId: appId
}, namespaceCreationModel, function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
});
return d.promise;
},
createAppNamespace: function (appId, appnamespace) {
var d = $q.defer();
namespace_source.createAppNamespace({
appId: appId
}, appnamespace, function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
});
return d.promise;
}
find_public_namespaces: find_public_namespaces,
createNamespace: createNamespace,
createAppNamespace: createAppNamespace,
getNamespacePublishInfo: getNamespacePublishInfo
}
}]);
......@@ -10,7 +10,9 @@
<b class="namespace-name" ng-bind="namespace.viewName"
data-tooltip="tooltip" data-placement="bottom" title="{{namespace.comment}}"></b>
<span class="label label-info no-radius namespace-label" ng-bind="namespace.format"></span>
<span class="label label-warning no-radius namespace-label" ng-show="namespace.itemModifiedCnt > 0">有修改
<span class="label label-warning no-radius namespace-label modify-tip"
ng-show="namespace.itemModifiedCnt > 0">
有修改
<span class="badge label badge-white namespace-label" ng-bind="namespace.itemModifiedCnt"></span>
</span>
<span class="label label-primary no-radius namespace-label"
......@@ -67,7 +69,7 @@
<!--second header-->
<header class="panel-heading second-panel-heading">
<div class="row">
<div class="col-md-8 pull-left">
<div class="col-md-6 pull-left">
<!--master branch nav tabs-->
<ul class="nav nav-tabs">
<li role="presentation" ng-click="switchView(namespace, 'table')"
......@@ -99,7 +101,7 @@
</li>
</ul>
</div>
<div class="col-md-4 text-right">
<div class="col-md-6 text-right">
<a class="clipboard"
data-clipboard-text="{{namespace.text}}"
data-tooltip="tooltip" data-placement="bottom" title="复制文本"
......@@ -161,6 +163,9 @@
<!--table view-->
<div class="namespace-view-table" ng-show="namespace.viewType == 'table'">
<div class="well well-sm no-radius text-center" ng-show="!namespace.latestRelease">
<span style="color: red"> Tips: 此namespace从来没有发布过,Apollo客户端将获取不到配置并记录404日志信息,请及时发布。</span>
</div>
<!--not link namespace-->
<div ng-if="!namespace.isLinkedNamespace">
<div class="col-md-8 col-lg-offset-2 search-input" ng-show="namespace.showSearchInput">
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册