From 8a39cceae945c8b21ea9e1427df6f414669b8c93 Mon Sep 17 00:00:00 2001 From: lepdou Date: Tue, 14 Feb 2017 18:23:49 +0800 Subject: [PATCH] admin can modify app information --- .../controller/AppController.java | 12 +- .../apollo/biz/service/AppService.java | 20 +- .../apollo/portal/api/AdminServiceAPI.java | 4 + .../portal/component/PermissionValidator.java | 4 + .../portal/controller/AppController.java | 98 +++++---- .../portal/listener/AppInfoChangedEvent.java | 19 ++ .../listener/AppInfoChangedListener.java | 45 ++++ .../portal/listener/CreationListener.java | 8 +- .../apollo/portal/service/AppService.java | 52 +++-- .../src/main/resources/static/app.html | 106 +++++----- .../src/main/resources/static/app/role.html | 109 ---------- .../main/resources/static/app/setting.html | 200 ++++++++++++++++++ .../src/main/resources/static/config.html | 37 ++-- .../src/main/resources/static/img/add.png | Bin 0 -> 2651 bytes .../src/main/resources/static/img/clippy.svg | 3 - .../src/main/resources/static/img/manage.png | Bin 0 -> 3247 bytes .../main/resources/static/img/plus-orange.png | Bin 2104 -> 0 bytes .../main/resources/static/img/user_manage.png | Bin 4834 -> 0 bytes .../main/resources/static/scripts/AppUtils.js | 6 + .../src/main/resources/static/scripts/app.js | 2 + .../scripts/controller/AppController.js | 2 +- .../scripts/controller/SettingController.js | 191 +++++++++++++++++ .../controller/role/AppRoleController.js | 75 ------- .../static/scripts/directive/directive.js | 8 +- .../static/scripts/services/AppService.js | 17 +- .../main/resources/static/scripts/valdr.js | 7 +- .../resources/static/styles/common-style.css | 18 +- .../resources/static/views/common/nav.html | 6 +- .../static/views/component/user-selector.html | 2 +- .../apollo/portal/ServiceExceptionTest.java | 2 +- 30 files changed, 716 insertions(+), 337 deletions(-) create mode 100644 apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/listener/AppInfoChangedEvent.java create mode 100644 apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/listener/AppInfoChangedListener.java delete mode 100644 apollo-portal/src/main/resources/static/app/role.html create mode 100644 apollo-portal/src/main/resources/static/app/setting.html create mode 100644 apollo-portal/src/main/resources/static/img/add.png delete mode 100644 apollo-portal/src/main/resources/static/img/clippy.svg create mode 100644 apollo-portal/src/main/resources/static/img/manage.png delete mode 100644 apollo-portal/src/main/resources/static/img/plus-orange.png delete mode 100644 apollo-portal/src/main/resources/static/img/user_manage.png create mode 100644 apollo-portal/src/main/resources/static/scripts/controller/SettingController.js delete mode 100644 apollo-portal/src/main/resources/static/scripts/controller/role/AppRoleController.js diff --git a/apollo-adminservice/src/main/java/com/ctrip/framework/apollo/adminservice/controller/AppController.java b/apollo-adminservice/src/main/java/com/ctrip/framework/apollo/adminservice/controller/AppController.java index 5977863c8..1a6d24b99 100644 --- a/apollo-adminservice/src/main/java/com/ctrip/framework/apollo/adminservice/controller/AppController.java +++ b/apollo-adminservice/src/main/java/com/ctrip/framework/apollo/adminservice/controller/AppController.java @@ -20,6 +20,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.List; +import java.util.Objects; @RestController public class AppController { @@ -47,7 +48,7 @@ public class AppController { return dto; } - @RequestMapping(path = "/apps/{appId}", method = RequestMethod.DELETE) + @RequestMapping(value = "/apps/{appId}", method = RequestMethod.DELETE) public void delete(@PathVariable("appId") String appId, @RequestParam String operator) { App entity = appService.findOne(appId); if (entity == null) { @@ -56,6 +57,15 @@ public class AppController { appService.delete(entity.getId(), operator); } + @RequestMapping(value = "/apps/{appId}", method = RequestMethod.PUT) + public void update(@PathVariable String appId, @RequestBody App app) { + if (!Objects.equals(appId, app.getAppId())) { + throw new BadRequestException("The App Id of path variable and request body is different"); + } + + appService.update(app); + } + @RequestMapping(value = "/apps", method = RequestMethod.GET) public List find(@RequestParam(value = "name", required = false) String name, Pageable pageable) { diff --git a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/AppService.java b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/AppService.java index eb0f57b8a..5578121b9 100644 --- a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/AppService.java +++ b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/AppService.java @@ -3,6 +3,7 @@ package com.ctrip.framework.apollo.biz.service; import com.ctrip.framework.apollo.biz.entity.Audit; import com.ctrip.framework.apollo.biz.repository.AppRepository; import com.ctrip.framework.apollo.common.entity.App; +import com.ctrip.framework.apollo.common.exception.BadRequestException; import com.ctrip.framework.apollo.common.exception.ServiceException; import com.ctrip.framework.apollo.common.utils.BeanUtils; @@ -71,14 +72,25 @@ public class AppService { } @Transactional - public App update(App app) { - App managedApp = appRepository.findByAppId(app.getAppId()); - BeanUtils.copyEntityProperties(app, managedApp); + public void update(App app) { + String appId = app.getAppId(); + + App managedApp = appRepository.findByAppId(appId); + if (managedApp == null) { + throw new BadRequestException(String.format("App not exists. AppId = %s", appId)); + } + + managedApp.setName(app.getName()); + managedApp.setOrgId(app.getOrgId()); + managedApp.setOrgName(app.getOrgName()); + managedApp.setOwnerName(app.getOwnerName()); + managedApp.setOwnerEmail(app.getOwnerEmail()); + managedApp.setDataChangeLastModifiedBy(app.getDataChangeLastModifiedBy()); + managedApp = appRepository.save(managedApp); auditService.audit(App.class.getSimpleName(), managedApp.getId(), Audit.OP.UPDATE, managedApp.getDataChangeLastModifiedBy()); - return managedApp; } } diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/api/AdminServiceAPI.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/api/AdminServiceAPI.java index f0a2b399d..e92c5cca0 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/api/AdminServiceAPI.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/api/AdminServiceAPI.java @@ -58,6 +58,10 @@ public class AdminServiceAPI { public AppDTO createApp(Env env, AppDTO app) { return restTemplate.post(env, "apps", app, AppDTO.class); } + + public void updateApp(Env env, AppDTO app) { + restTemplate.put(env, "apps/{appId}", app, app.getAppId()); + } } diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/component/PermissionValidator.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/component/PermissionValidator.java index 3f2f36e47..86a0892f8 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/component/PermissionValidator.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/component/PermissionValidator.java @@ -65,6 +65,10 @@ public class PermissionValidator { } } + public boolean isAppAdmin(String appId) { + return isSuperAdmin() || hasAssignRolePermission(appId); + } + public boolean isSuperAdmin() { return rolePermissionService.isSuperAdmin(userInfoHolder.getUser().getUserId()); } diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/AppController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/AppController.java index 65873d9d5..aa37020a8 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/AppController.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/AppController.java @@ -14,6 +14,7 @@ import com.ctrip.framework.apollo.portal.component.PortalSettings; import com.ctrip.framework.apollo.portal.entity.model.AppModel; import com.ctrip.framework.apollo.portal.entity.vo.EnvClusterInfo; import com.ctrip.framework.apollo.portal.listener.AppCreationEvent; +import com.ctrip.framework.apollo.portal.listener.AppInfoChangedEvent; import com.ctrip.framework.apollo.portal.service.AppService; import com.ctrip.framework.apollo.portal.service.RolePermissionService; import com.ctrip.framework.apollo.portal.spi.UserInfoHolder; @@ -24,6 +25,7 @@ import org.springframework.context.ApplicationEventPublisher; import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.PathVariable; @@ -35,6 +37,7 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.HttpClientErrorException; import java.util.List; +import java.util.Objects; import java.util.Set; @@ -69,6 +72,38 @@ public class AppController { return appService.findByOwnerName(owner, page); } + @RequestMapping(value = "", method = RequestMethod.POST) + public App create(@RequestBody AppModel appModel) { + + App app = transformToApp(appModel); + + App createdApp = appService.createAppInLocal(app); + + publisher.publishEvent(new AppCreationEvent(createdApp)); + + Set admins = appModel.getAdmins(); + if (!CollectionUtils.isEmpty(admins)) { + rolePermissionService.assignRoleToUsers(RoleUtils.buildAppMasterRoleName(createdApp.getAppId()), + admins, userInfoHolder.getUser().getUserId()); + } + + return createdApp; + } + + @PreAuthorize(value = "@permissionValidator.isAppAdmin(#appId)") + @RequestMapping(value = "/{appId}", method = RequestMethod.PUT) + public void update(@PathVariable String appId, @RequestBody AppModel appModel) { + if (!Objects.equals(appId, appModel.getAppId())) { + throw new BadRequestException("The App Id of path variable and request body is different"); + } + + App app = transformToApp(appModel); + + App updatedApp = appService.updateAppInLocal(app); + + publisher.publishEvent(new AppInfoChangedEvent(updatedApp)); + } + @RequestMapping(value = "/{appId}/navtree", method = RequestMethod.GET) public MultiResponseEntity nav(@PathVariable String appId) { @@ -86,41 +121,6 @@ public class AppController { return response; } - @RequestMapping(value = "", method = RequestMethod.POST) - public App create(@RequestBody AppModel appModel) { - - String appId = appModel.getAppId(); - String appName = appModel.getName(); - String ownerName = appModel.getOwnerName(); - String orgId = appModel.getOrgId(); - String orgName = appModel.getOrgName(); - - RequestPrecondition.checkArgumentsNotEmpty(appId, appName, ownerName, orgId, orgName); - - if (!InputValidator.isValidClusterNamespace(appModel.getAppId())) { - throw new BadRequestException(String.format("AppId格式错误: %s", InputValidator.INVALID_CLUSTER_NAMESPACE_MESSAGE)); - } - - App app = new App(); - app.setAppId(appId); - app.setName(appName); - app.setOwnerName(ownerName); - app.setOrgId(orgId); - app.setOrgName(orgName); - - App createdApp = appService.create(app); - - publisher.publishEvent(new AppCreationEvent(createdApp)); - - Set admins = appModel.getAdmins(); - if (!CollectionUtils.isEmpty(admins)) { - rolePermissionService - .assignRoleToUsers(RoleUtils.buildAppMasterRoleName(appId), admins, userInfoHolder.getUser().getUserId()); - } - - return createdApp; - } - @RequestMapping(value = "/envs/{env}", method = RequestMethod.POST, consumes = { "application/json"}) public ResponseEntity create(@PathVariable String env, @RequestBody App app) { @@ -131,7 +131,7 @@ public class AppController { throw new BadRequestException(InputValidator.INVALID_CLUSTER_NAMESPACE_MESSAGE); } - appService.createApp(Env.valueOf(env), app); + appService.createAppInRemote(Env.valueOf(env), app); return ResponseEntity.ok().build(); } @@ -155,7 +155,8 @@ public class AppController { response.addResponseEntity(RichResponseEntity.ok(env)); } else { response.addResponseEntity(RichResponseEntity.error(HttpStatus.INTERNAL_SERVER_ERROR, - String.format("load appId:%s from env %s error.", appId,env) + String.format("load appId:%s from env %s error.", appId, + env) + e.getMessage())); } } @@ -164,4 +165,27 @@ public class AppController { return response; } + + private App transformToApp(AppModel appModel) { + String appId = appModel.getAppId(); + String appName = appModel.getName(); + String ownerName = appModel.getOwnerName(); + String orgId = appModel.getOrgId(); + String orgName = appModel.getOrgName(); + + RequestPrecondition.checkArgumentsNotEmpty(appId, appName, ownerName, orgId, orgName); + + if (!InputValidator.isValidClusterNamespace(appModel.getAppId())) { + throw new BadRequestException(String.format("AppId格式错误: %s", InputValidator.INVALID_CLUSTER_NAMESPACE_MESSAGE)); + } + + App app = new App(); + app.setAppId(appId); + app.setName(appName); + app.setOwnerName(ownerName); + app.setOrgId(orgId); + app.setOrgName(orgName); + + return app; + } } diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/listener/AppInfoChangedEvent.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/listener/AppInfoChangedEvent.java new file mode 100644 index 000000000..7a61141da --- /dev/null +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/listener/AppInfoChangedEvent.java @@ -0,0 +1,19 @@ +package com.ctrip.framework.apollo.portal.listener; + +import com.google.common.base.Preconditions; + +import com.ctrip.framework.apollo.common.entity.App; + +import org.springframework.context.ApplicationEvent; + +public class AppInfoChangedEvent extends ApplicationEvent{ + + public AppInfoChangedEvent(Object source) { + super(source); + } + + public App getApp() { + Preconditions.checkState(source != null); + return (App) this.source; + } +} diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/listener/AppInfoChangedListener.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/listener/AppInfoChangedListener.java new file mode 100644 index 000000000..c37ab28ec --- /dev/null +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/listener/AppInfoChangedListener.java @@ -0,0 +1,45 @@ +package com.ctrip.framework.apollo.portal.listener; + +import com.ctrip.framework.apollo.common.dto.AppDTO; +import com.ctrip.framework.apollo.common.utils.BeanUtils; +import com.ctrip.framework.apollo.core.enums.Env; +import com.ctrip.framework.apollo.portal.api.AdminServiceAPI; +import com.ctrip.framework.apollo.portal.component.PortalSettings; +import com.ctrip.framework.apollo.tracer.Tracer; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class AppInfoChangedListener { + private static final Logger logger = LoggerFactory.getLogger(AppInfoChangedListener.class); + + @Autowired + private AdminServiceAPI.AppAPI appAPI; + @Autowired + private PortalSettings portalSettings; + + + @EventListener + public void onAppInfoChange(AppInfoChangedEvent event) { + AppDTO appDTO = BeanUtils.transfrom(AppDTO.class, event.getApp()); + String appId = appDTO.getAppId(); + + List envs = portalSettings.getActiveEnvs(); + for (Env env : envs) { + try { + appAPI.updateApp(env, appDTO); + } catch (Throwable e) { + logger.error("Update app's info failed. Env = {}, AppId = {}", env, appId, e); + Tracer.logError(String.format("Update app's info failed. Env = {}, AppId = {}", env, appId), e); + } + } + + } + +} diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/listener/CreationListener.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/listener/CreationListener.java index 11115c3fc..a7e73b347 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/listener/CreationListener.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/listener/CreationListener.java @@ -36,8 +36,8 @@ public class CreationListener { try { appAPI.createApp(env, appDTO); } catch (Throwable e) { - logger.error("call appAPI.createApp error.(appId={appId}, env={env})", appDTO.getAppId(), env, e); - Tracer.logError(String.format("call appAPI.createApp error. (appId=%s, env=%s)", appDTO.getAppId(), env), e); + logger.error("Create app failed. appId = {}, env = {})", appDTO.getAppId(), env, e); + Tracer.logError(String.format("Create app failed. appId = %s, env = %s", appDTO.getAppId(), env), e); } } } @@ -50,8 +50,8 @@ public class CreationListener { try { namespaceAPI.createAppNamespace(env, appNamespace); } catch (Throwable e) { - logger.error("call appAPI.createApp error.(appId={appId}, env={env})", appNamespace.getAppId(), env, e); - Tracer.logError(String.format("call appAPI.createApp error. (appId=%s, env=%s)", appNamespace.getAppId(), env), e); + logger.error("Create appNamespace failed. appId = {}, env = {}", appNamespace.getAppId(), env, e); + Tracer.logError(String.format("Create appNamespace failed. appId = %s, env = %s", appNamespace.getAppId(), env), e); } } } diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/AppService.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/AppService.java index 280ab5e47..d0546910a 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/AppService.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/AppService.java @@ -6,7 +6,6 @@ import com.ctrip.framework.apollo.common.dto.AppDTO; import com.ctrip.framework.apollo.common.entity.App; import com.ctrip.framework.apollo.common.exception.BadRequestException; import com.ctrip.framework.apollo.common.utils.BeanUtils; -import com.ctrip.framework.apollo.common.utils.ExceptionUtils; import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.portal.api.AdminServiceAPI; import com.ctrip.framework.apollo.portal.constant.CatEventType; @@ -17,13 +16,10 @@ import com.ctrip.framework.apollo.portal.spi.UserInfoHolder; import com.ctrip.framework.apollo.portal.spi.UserService; import com.ctrip.framework.apollo.tracer.Tracer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.client.HttpStatusCodeException; import java.util.Collections; import java.util.List; @@ -32,8 +28,6 @@ import java.util.Set; @Service public class AppService { - private Logger logger = LoggerFactory.getLogger(AppService.class); - @Autowired private UserInfoHolder userInfoHolder; @Autowired @@ -78,26 +72,17 @@ public class AppService { return appAPI.loadApp(env, appId); } - public void createApp(Env env, App app) { - enrichUserInfo(app); - try { - AppDTO appDTO = BeanUtils.transfrom(AppDTO.class, app); - appAPI.createApp(env, appDTO); - } catch (HttpStatusCodeException e) { - logger.error(ExceptionUtils.toString(e)); - throw e; - } - } - - public void enrichUserInfo(App app) { + public void createAppInRemote(Env env, App app) { String username = userInfoHolder.getUser().getUserId(); app.setDataChangeCreatedBy(username); app.setDataChangeLastModifiedBy(username); - } + AppDTO appDTO = BeanUtils.transfrom(AppDTO.class, app); + appAPI.createApp(env, appDTO); + } @Transactional - public App create(App app) { + public App createAppInLocal(App app) { String appId = app.getAppId(); App managedApp = appRepository.findByAppId(appId); @@ -125,6 +110,33 @@ public class AppService { return createdApp; } + @Transactional + public App updateAppInLocal(App app) { + String appId = app.getAppId(); + + App managedApp = appRepository.findByAppId(appId); + if (managedApp == null) { + throw new BadRequestException(String.format("App not exists. AppId = %s", appId)); + } + + managedApp.setName(app.getName()); + managedApp.setOrgId(app.getOrgId()); + managedApp.setOrgName(app.getOrgName()); + + String ownerName = app.getOwnerName(); + UserInfo owner = userService.findByUserId(ownerName); + if (owner == null) { + throw new BadRequestException(String.format("App's owner not exists. owner = %s", ownerName)); + } + managedApp.setOwnerName(owner.getUserId()); + managedApp.setOwnerEmail(owner.getEmail()); + + String operator = userInfoHolder.getUser().getUserId(); + managedApp.setDataChangeLastModifiedBy(operator); + + return appRepository.save(managedApp); + } + public EnvClusterInfo createEnvNavNode(Env env, String appId) { EnvClusterInfo node = new EnvClusterInfo(env); node.setClusters(clusterService.findClusters(env, appId)); diff --git a/apollo-portal/src/main/resources/static/app.html b/apollo-portal/src/main/resources/static/app.html index 5b69ebbdd..221e85427 100644 --- a/apollo-portal/src/main/resources/static/app.html +++ b/apollo-portal/src/main/resources/static/app.html @@ -25,71 +25,71 @@ 创建项目 -
-
-
- -
- -
+ +
+ +
+
-
- -
- - (CMS上申请的App Id) -
+
+
+ +
+ + (CMS上申请的App Id)
-
- -
- - (建议格式 xx-yy-zz 例:apollo-server) -
+
+
+ +
+ + (建议格式 xx-yy-zz 例:apollo-server)
-
- -
- -
+
+
+ +
+
+
-
-
diff --git a/apollo-portal/src/main/resources/static/app/role.html b/apollo-portal/src/main/resources/static/app/role.html deleted file mode 100644 index fd1bc44a0..000000000 --- a/apollo-portal/src/main/resources/static/app/role.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - - - - - 权限管理 - - - - - - -
-
-
-
-
- -
- -
-
-
-
-
-
- -
-
-
- -
- -
- -
- -
- - -
-
- -
-
-
-
- - -
-
-

您没有权限哟!

-
- -
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apollo-portal/src/main/resources/static/app/setting.html b/apollo-portal/src/main/resources/static/app/setting.html new file mode 100644 index 000000000..040d7b15d --- /dev/null +++ b/apollo-portal/src/main/resources/static/app/setting.html @@ -0,0 +1,200 @@ + + + + + + + + + + + + 项目管理 + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apollo-portal/src/main/resources/static/config.html b/apollo-portal/src/main/resources/static/config.html index d76d4cbde..f786aee4a 100644 --- a/apollo-portal/src/main/resources/static/config.html +++ b/apollo-portal/src/main/resources/static/config.html @@ -34,7 +34,7 @@
-  环境列表 + 环境列表 @@ -47,16 +47,22 @@
- 项目信息 - - - - - - + 项目信息 + + + + + + + +
@@ -101,6 +107,9 @@
+ +

补缺环境

@@ -129,9 +138,7 @@
- +
@@ -169,14 +176,14 @@ 集群的实例只会使用 - 集群(当前页面)的配置,只有当对应namespace在当前集群没有发布过配置时,才会使用default集群的配置! + 集群(当前页面)的配置,只有当对应namespace在当前集群没有发布过配置时,才会使用default集群的配置。
-

注意:以下环境/集群有未发布的配置,客户端获取不到未发布的配置,请及时发布。

+

注意: 以下环境/集群有未发布的配置,客户端获取不到未发布的配置,请及时发布。

diff --git a/apollo-portal/src/main/resources/static/img/add.png b/apollo-portal/src/main/resources/static/img/add.png new file mode 100644 index 0000000000000000000000000000000000000000..36c9cf7945bcdec03111b4bdfa05c23d6d036b12 GIT binary patch literal 2651 zcmeHJSyYk<6h;M6OaXK0xZv;7f|`1YbOe_m6im}%%snl&lu9iW$t?>T(-vHEvQ)Hl z!m)CX$_y7Q*IX!UA>2}N%WyIqlaX|o$9ZeseYp2~xc8iU&OP7#?w5Vgo1_UdfPp|D zO%F1WqQLHdLrqnYs{?9EK_Hl!2NCakE>y}s5Nqgf;MPj&nTymp4mnf{e8z)lkyOYb zvlB*15I@k3FIB$>0;+0U<)H}Akv^Dp4w0|2+p6xNN)(5$Co^!{ezMo~V0J@vNIffa znHTmJ*P!)stIA>Y%0&=()DvhsaTXjD%y=JhJb5>zs=}zhU|KOOnXM zA6HC;D1ig{bi2(FbegT3IDo&xVD&kAn}x?EJYD~|&zP&#h0nbb9Gf;c;&DBpcA|c& zYidiWcj&MI94hF&93XR1R-=qRem%ONWmZ0<%PNWYMU|B{4-@kp7n}9=A=u-m2`Rh= zUG!S;>tB+*24riqb?Kfc-z6nAN*me@VqDY{;uY9i-vh2M&ADKj|RD)}0;6L(&ep86qk z%!(X;iXk|Bc8IrG}euR@LK|d)@zxrrA>{O88G4KLX4XvB~K`( z4`XIFU3666#DXukraQ0R1f<@7&SZ($OQ3e(OuxEhaqdHJ|Kgc1O`>iHK4>g~K`|fU zP2(irOaWwfUXDBTN52NM5B1!?Lcr;{WLjqdrnSTGX8dSg!jUTn(+bRDtb5i(s$h(= zqpK^sNj~F+SU?$g3VS^OpQY;CigC5)cG#i@WD5BiP?v;-jo`7(6JtT^nVZ1Cmvm+B zx_J^EI;UkW^ye#DY_wPAwS><5^J0~u%80#)8YQ)YZG2-6#!~NH9*Fs-p1vGX1Y#Dr zcRa^x@6E+N87TGKyf;^PFCc)V5S^}fAL6MBG|<(UCxh^xMA#IY10ekVyWz)-)d8|` zaFn22fmC1XDsv_9{fPO`jTj{``udgM=oS|M`f0Xv;kFAv`Jwtc78t={RdZ*A3jEJ- zer2KkX$CY;C>5gh2zOK!`!H!*u26O3cF5Eu-8oUrR9Q?zW6|KCtTUI%r)lpP6{M`i zjxHyDx1daDP=3v3q5?h*kRz$;5+k_#_@+=h;GQb@Lb@iTzD2u=6cMMk#- z7aidu)e3;zc)2}Q!fu^9R{_ijEZ8_hBsGVzd=u!+pFaT1jG32DsFcQ~4Xjq&NrS-hSB^0V`zdQL(a`6hqY;7SE(+ytJ+uo!gUstp84iN*ka+e82Z9# zPP7wkCWpxsvqNi+_7U7A)RsMe`>d}KGT$HF z!Sp>yOW~zxqtim$?!6?Hl*?u>i!jC5Q-pDGHgO^j~- z!;}n3Yk0CyQ}K3=3v)m0Jh3{N@dN*M-#iA6w>&u{waHgp4|X`t?@_auh0ldm#>IT^ zM0e;byv!+I)=EVFS5*Njew>FOD9nuP()7CpaaW~7CR*4J>k6gn&_dMTmtRFnC`A9T zSD(Hun}s{Lr6&LNO`csc*;aN#pEo)FQ6~SD+~N(w>m@krFmCwxxr(#94fF0cW`(Kf uGp=Sic{_F{J>0cLGu - - diff --git a/apollo-portal/src/main/resources/static/img/manage.png b/apollo-portal/src/main/resources/static/img/manage.png new file mode 100644 index 0000000000000000000000000000000000000000..8b10fff2f85f210e50df22b9e7ea97e55cc8b679 GIT binary patch literal 3247 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 literal 0 HcmV?d00001 diff --git a/apollo-portal/src/main/resources/static/img/plus-orange.png b/apollo-portal/src/main/resources/static/img/plus-orange.png deleted file mode 100644 index 644bdf1ec9aba887f2bc74700309168755b51a3d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2104 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST~P>f&IUyi(^Pd+}k-D3sXZySk`wq zoI7<-U<#u&m!d}V->wACMxO?r8$1P(Jar5qwOlefE1$)k_2Zp0%{IR;?)>XX%Xc5; zXHoc|)M$Offq_Y1*g;?)AIBai2FD*Z3JnT1%mNn52jV9f=h>LHFf{Q<&bn@++@O$t zry`4kkwwzTWPPO@gX6g!vbJBJ7X9CG?N`Z{583>8uRU*n{(AD>>4#bs4)#Cze)@0w z?I`=Y*2(tvG3(^_Ilcek#ll&~#39s@Yt^ctHo=RxNn^?`BMzZE%#KYPe3uIxVF_C4 zD9{=d&gR%ut>7WB?WIW53Tpvchh4awc}*vLs=${P0rnKESNZq@`~ar+8LVOTu`#^V`%D` zJxBbWVuOP9mJ@xzjQLpYd22cKwF)}^+i_?A|Kh)&=Ue@_$YFEu+OH+9+k@u6zgBgt zDyibf-KW1MH$CwEzs1qg;aNP>pZGQZ?_F?Se*?Gr)-PV2E=kHk? zFE?+!|F<|U@um-g4i7|`I1W8$WMp|L-EcsX@n6%N!pAEWSp-r}T-ftWl99#o@v&fM zVD6l-u=1=i6Gzdp-sNoq4igleKhH{M5qQ!g?avF$%Fb=iOwR*VNt(}-0@lNAJZH1# h2|8e{f*bcUSWNi(jrH#n9$<@r!PC{xWt~$(697Rs7qb8W diff --git a/apollo-portal/src/main/resources/static/img/user_manage.png b/apollo-portal/src/main/resources/static/img/user_manage.png deleted file mode 100644 index ae2350b85568f8b608678560b466cba2f5e2f811..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4834 zcmbVQp#bx4OWx`rrBWRosIU~~&8DIwh; z9RkLe&mZu6^Lz1}b6wB5ujjhYi|4+tb7BqkHEF5XsQ>@~trkk%_$v4Qcc2tkvDC8c z4FJGM&{9`14YK>0XYV`K&D^alOH3u#kuao>e-28FNXemu-G2r@lB2vTi zzgz|Yz6&%AV<(3~e}q%PU>AVvJ|-B&m|U+=cU~$OHkmbN(BA}uso(7Wq)`9>vcEM{{I07P8-AgFONMT%7vY6MYnYpZfQ5==QykpP%ca=K+qEW&^2{^UVJCB)h?K< zQ$x_L>Wwqo&;Vl#6Dx#FJv0&{*puxALs>E$Ye& zBPl3)Mns@mGD>&ZkrY%t?UGKB?vvMsK^J|GtGUSGYEh0|ezF3Tn1co2xzl0cp-YnE zFN4_0(bNJ9jyyuV(qkm?{j9Qybc*wz2C#>arR`xG$k-F~V&iDHUQ@ozrE5?dfxzCzAM{{N{=(k z)Rw%Qo9WcT=tqV4XiFT<`Vy8IdWTPk9cz?#QX%1?=c_+)r$(3ks`J&lw&(GuiAsb} z-$!To{b%xjzLM+RfR))zg$PDJV9w#A?nN0;TV>Tr30YL9Y4cM<*SWQ+y;0o&jpk>4 zATj9%n`R;Ix<$wG*443Vb@{KWMV$fOywttveacR)g~0D{G*kV@vP^{s$Tfb^lR>Bc z0P>hZnk8W^wj zF1LjVmZu-CQ%k0B*>`O{+&ycZf&n)Cswl;l61S7njyIk!+tNaQHYP3mHasX62LQiq zO4OU;!Z&oak^XYDi0i;_*=d*!e|8&TP=WZ96pRnIy6fy`(^;*_Ct1Ak5s6*=HcgX| z8RhT5$!iIYCa5eixPo5s-F*#Y5Ye#IrXO>6*4A^ak+K0&z=C*y40@>Ty+SL*R$QDW z>Wrk*#&Gu=v7@sSj_BpvQpoW+#RCwLmo@H(8zx7GGSn=n8?Yg@+X;8H*zk`9EVnSd zk~!WxISO-QoOV+)N>7mWj~=`FPzX+M@)1%g)Y)4HKAvdg1L(Q3RM$L1)2Mjqp$05l zw+EZ)^Ypg~DG^3Msr7ThldRe-?_gVZy@<}2K%cvk zUAHkw333B%WMUu`R1+DY3GBu2@NfbbS$Bjdqy~wyv7Dnf+B@@@4qJV$1cE3qB@%W- z^Go&>NhJ;oOSxpT^Qje%X$lm(F$i<79j`Jtw1};~-66WjcWMoi2L9QaN}CY`K8Q;h z!RoY6h%X3P5OZv%_vSTeV^G=Z-o{HOyy1)3{_-PtUk*jMPBQU`_i&K({IyT=hz&@_ zp`1bMCv6uDD`^Byb6+SK&9d~RCr0iw*z>^|x?GGl zg^PySBt>wvG+vPuBqY}Zq&gHZ=XKn@?=@Ipo*Z4m5w%8K7vDd>77Eu^fjA{7Rc(6^oLnZ7t?u`uj*U;lif+o_r$^roio?RFp~YLa>5 z(YXb`G@H*(p&P;ep(ZjksIB#IKls3IEC2Z|IGLXp_h5GJ>`4s;;hQ@d9Kn%4zjG9sTsc^BLO|pwqpl zUn-IqA?c$7FQd<#WOBGz${Rgcfm&d!@Wf^?rNZDW`W52Omj;i?@^9KJ2WK>wd~g<% zYpIMajbPPNAZ#i;>^I!JdE20;Yj5aPT~KAFV()L>mx+v;@yJ#NC8mYSQb&tiwD-gd zl#}R^#Z0(`Ey&nb0WsNCmIQNQTDW@(tFgd9S)C~#IQVBv(~!RxH8GjZ{wE=+TS+(@ zp-3qM5EgzFu0)xMx{pUQYXoK-WjAM2ZdkO+z z)LQAGId2uLWKV~{C%A!#<3>QW#uy-!0eV~V{EViZS-A~5L6Xk1vISeBa-?@;qW zgV?!zd{+5mtUp!n>bj>k?ZDOh?0N|eX?*R%SD(YTH-FL~-HL+P{xFg4eli?PLMdU~Id#MNe+LOCgvA*z6E zNgP(@*zpTNdb+!KuYV%&N8^y_cSavmq{gY11jmP9dCB|Bzvf+G@AOuUQ5?c+BJA+r zCo@|vTi(<|dUiz%B{#;6B-Lw6ttGCMJ(KqBqi%yKA}M8VEi(x-MwN$vb6VBzDe^{N zc}!v{{F8j$!zPyUD7iq!_mHa|qm!ePJp68+>^>v!WhH&z2I0_IZn?oeNCkw>bY1D> z=4!!~t%+q1Zcq;)P10;MY@EC~XNuT})(t0XpL6^e|KNn{V*@P3TJlvp&wDUAp6U^{ zPd2}i%2IQuj9Nx{$RK&qO#P9lk%PI5;L3|d=LX-nBYEZzvfSydDxG^oaP%!1xXq{e z9g>uYMF1dzi`4JRR^{=O5;u!%k^JgYn>fI+ul53Q^SHvTR$ISy*dXU4S8@z+pD?8bQ1jQh6b zdAksXyLQh*=L7AAhqXQpa>a#Y#Fbqtt`8*(nTn`YD0be)jK?g^c4!*su}FJtb9&Gj zN2Z7R5WZsPpW05Bj&`O_e8ZLfq{4BwPD^$zTfSg)qC4zc(d65=F45pM(Z|?t*3m)W z?3_CCwWWSBcJ(f(_4(#C{`Gyg@DdWOHLW%N!!x-_24MxYWg|~>8Rr1cGknE4Z+MY5 z$7s-=3bC;S3{wic{4=o|QS&xbO0z&E&LYsnaMn#ZhG zdUJ;G?{K{1B}?WsT0J}5C#d!Z=QK|kC+#n~-^{`nvYpyi90JERR2CMI@s#@`0i&bt z^dl;vh8#2MAr{+do@>{bUvKK|RhIb8nBBQQbA{<7XDr8Dy)$n5`ooXuGL#TbJ>}S8 zx6*DB1=&Ir70H-x`R9J&fOFb;X4;9rOQ;E4QT)<1u~_#$KiB3Jk9Bmx*tn+r7u&%O zZn#Y|v087rf`4Scrjm=qIVY9RoEi{dgt#=E11#>lHRee~9Rxq}f88T7*ZlreYM9dT z_$`8?(C(^8oU<+}dORje0nb4PorVNF^E_3riF_ROc{^B=UEd@KzZg~|{9LziS|th4 zdr1&NbJ*Tk)~pjp$}|yItDchU%q0S1h+MXR+apM4ADNI2*!lP06w*q4bwO3XlA&ln zCjm@nmQAqF2%;Je*FJ$zqT(^K?>+hiw#ng@^z2hsp4il5=u?S0xidtwRGf4>jM}EF zy{}9t;dN?_RoBu!@qydVdT9zc0NqHxbg&d#su4?~Z(mFY!B#gvk>pT*)PL|X2W0Q2 zDo*PDyPv*S#L$*~$pkX5FTf%)IQyMO!ATRx4(|9rZB9plHi=|9(4x66+!n zz>w)C+tK?6d_C0SIAAP;&6;q~@LaB*-hsNw2R8$)-DXc_pYwqhJ{?z=O?FCPd1|}y?aj#8R>PeLBk!j~(BNOC6A+e2gr;HFHIiKR)BV&tRue$l3Fo|Y&M>^c;Ymg`^ z-;3ZJsj)ei%gtGG_V^*p%_w8ju~&HGMjb`O5xqblmCIMDjx-{l5zhf2nkIzqYCt*_ zvCwBWB015b5^mT#|1i-mnxn4tG+p&Me3vVw(_sWZ075Xukd_kQ!G65+Hd#1|+kwwr zDB;6>rtDM&zXo}2$G2`P2SWivmBt!l@d72lMWE1Yc@JGCkMWKEl|8XB`wl`$Kp2e+ z+NR08$XnO^guMrl$j&6fxC0n|Ar=`LBhc?i8#CtSb@3xp@Yz4EI%RVWpx0v1orpNMmwbJC%=RVKuV?Ob$#Ugh(X$JGTRJ8n;k1dED- z77Dj+v@I5H@f<=wgC>cPsR^s>Uf0&PB@Sk`Q=)xlzFKjr@f#)cDrk@L9WLKnQc(B| z&OGB{#T%6H+Zr!Ynduy_h5OBMY*=~+ZZxEaKaQ_9o;1vjHUfTg6IHA8zK)!f?vQfg z^WA(+R9I=zqFoME&p&)cvZAMAEd8p3tbuENc9Z#JqcPiPhYQEbi3$Uvrq$XDL!07 zqe}_*7?jK=Oe5$1Dvr@zZlJMqR+dKh48mgLQc`pno&Hv4UGfWb^@{9lIz+GTd$*{` zwxsbPs%Tnj2x=Q26QC%LZU1909TYe*oFL?4ro>2jpkQv|B(IVCoF4}XYv!V5VTG78Ut22H+?!8t@KDl0qAeBu&@)>y$Prdw(cFef z#<$R4aiR4%fN0K8wxuc~IUUGhJ6TcJ8yJh`?p{}Hka`5yMisQFAkiE92s2}3L6lnm z9u=0j^I1Nwuw4ad(^UCk&y-=@6<}^rM7mlJco-}MQ1(*s`Zlh3$|UOBGGHO=f!kD z9{BV9j=70V_C5RdL>pr^LT>-T2>#LWk HK792*Ae{oz diff --git a/apollo-portal/src/main/resources/static/scripts/AppUtils.js b/apollo-portal/src/main/resources/static/scripts/AppUtils.js index a089de558..2def0cabc 100644 --- a/apollo-portal/src/main/resources/static/scripts/AppUtils.js +++ b/apollo-portal/src/main/resources/static/scripts/AppUtils.js @@ -28,6 +28,12 @@ appUtil.service('AppUtil', ['toastr', '$window', function (toastr, $window) { if (query.indexOf('/') == 0) { query = query.substring(1, query.length); } + + var anchorIndex = query.indexOf('#'); + if (anchorIndex >= 0) { + query = query.substring(0, anchorIndex); + } + var params = query.split("&"); var result = {}; params.forEach(function (param) { diff --git a/apollo-portal/src/main/resources/static/scripts/app.js b/apollo-portal/src/main/resources/static/scripts/app.js index 979a02d17..8a5f8a395 100644 --- a/apollo-portal/src/main/resources/static/scripts/app.js +++ b/apollo-portal/src/main/resources/static/scripts/app.js @@ -20,6 +20,8 @@ var sync_item_module = angular.module('sync_item', ['app.service', 'apollo.direc var namespace_module = angular.module('namespace', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar', 'valdr']); //server config var server_config_module = angular.module('server_config', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar']); +//setting +var setting_module = angular.module('setting', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar', 'valdr']); //role var role_module = angular.module('role', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar']); //cluster diff --git a/apollo-portal/src/main/resources/static/scripts/controller/AppController.js b/apollo-portal/src/main/resources/static/scripts/controller/AppController.js index 32fe9adfe..e09deba9e 100644 --- a/apollo-portal/src/main/resources/static/scripts/controller/AppController.js +++ b/apollo-portal/src/main/resources/static/scripts/controller/AppController.js @@ -51,7 +51,7 @@ function createAppController($scope, $window, toastr, AppService, AppUtil, Organ // owner var owner = $('.ownerSelector').select2('data')[0]; if (!owner) { - toastr.warning("请输入应用负责人"); + toastr.warning("请选择应用负责人"); return; } $scope.app.ownerName = owner.id; diff --git a/apollo-portal/src/main/resources/static/scripts/controller/SettingController.js b/apollo-portal/src/main/resources/static/scripts/controller/SettingController.js new file mode 100644 index 000000000..1c85e4b8d --- /dev/null +++ b/apollo-portal/src/main/resources/static/scripts/controller/SettingController.js @@ -0,0 +1,191 @@ +setting_module.controller('SettingController', + ['$scope', '$location', 'toastr', + 'AppService', 'AppUtil', 'PermissionService', + 'OrganizationService', + SettingController]); + +function SettingController($scope, $location, toastr, + AppService, AppUtil, PermissionService, + OrganizationService) { + + var params = AppUtil.parseParams($location.$$url); + var $orgWidget = $('#organization'); + + $scope.pageContext = { + appId: params.appid + }; + $scope.display = { + app: { + edit: false + } + }; + + $scope.submitBtnDisabled = false; + $scope.userSelectWidgetId = 'toAssignMasterRoleUser'; + + $scope.assignMasterRoleToUser = assignMasterRoleToUser; + $scope.removeMasterRoleFromUser = removeMasterRoleFromUser; + $scope.toggleEditStatus = toggleEditStatus; + $scope.updateAppInfo = updateAppInfo; + + init(); + + function init() { + initOrganization(); + initPermission(); + initAdmins(); + initApplication(); + + } + + function initOrganization() { + OrganizationService.find_organizations().then(function (result) { + var organizations = []; + result.forEach(function (item) { + var org = {}; + org.id = item.orgId; + org.text = item.orgName + '(' + item.orgId + ')'; + org.name = item.orgName; + organizations.push(org); + }); + $orgWidget.select2({ + placeholder: '请选择部门', + width: '100%', + data: organizations + }); + }, function (result) { + toastr.error(AppUtil.errorMsg(result), "load organizations error"); + }); + } + + function initPermission() { + PermissionService.has_assign_user_permission($scope.pageContext.appId) + .then(function (result) { + $scope.hasAssignUserPermission = result.hasPermission; + }); + } + + function initAdmins() { + PermissionService.get_app_role_users($scope.pageContext.appId) + .then(function (result) { + $scope.appRoleUsers = result; + $scope.admins = []; + $scope.appRoleUsers.masterUsers.forEach(function (user) { + $scope.admins.push(user.userId); + }); + + }); + } + + function initApplication() { + AppService.load($scope.pageContext.appId).then(function (app) { + $scope.app = app; + $scope.viewApp = _.clone(app); + initAppForm(app); + $('.project-setting .panel').removeClass('hidden'); + }) + + } + + function initAppForm(app) { + $orgWidget.val(app.orgId).trigger("change"); + + var $ownerSelector = $('.ownerSelector'); + var defaultSelectedDOM = ''; + $ownerSelector.append(defaultSelectedDOM); + $ownerSelector.trigger('change'); + } + + function assignMasterRoleToUser() { + var user = $('.' + $scope.userSelectWidgetId).select2('data')[0]; + if (!user) { + toastr.warning("请选择用户"); + return; + } + var toAssignMasterRoleUser = user.id; + $scope.submitBtnDisabled = true; + PermissionService.assign_master_role($scope.pageContext.appId, + toAssignMasterRoleUser) + .then(function (result) { + $scope.submitBtnDisabled = false; + toastr.success("添加成功"); + $scope.appRoleUsers.masterUsers.push({userId: toAssignMasterRoleUser}); + $('.' + $scope.userSelectWidgetId).select2("val", ""); + }, function (result) { + $scope.submitBtnDisabled = false; + toastr.error(AppUtil.errorMsg(result), "添加失败"); + }); + } + + function removeMasterRoleFromUser(user) { + if ($scope.appRoleUsers.masterUsers.length <= 1) { + $('#warning').modal('show'); + return; + } + PermissionService.remove_master_role($scope.pageContext.appId, user) + .then(function (result) { + toastr.success("删除成功"); + removeUserFromList($scope.appRoleUsers.masterUsers, user); + }, function (result) { + toastr.error(AppUtil.errorMsg(result), "删除失败"); + }); + } + + function removeUserFromList(list, user) { + var index = 0; + for (var i = 0; i < list.length; i++) { + if (list[i].userId == user) { + index = i; + break; + } + } + list.splice(index, 1); + } + + function toggleEditStatus() { + if ($scope.display.app.edit) {//cancel edit + $scope.viewApp = _.clone($scope.app); + initAppForm($scope.viewApp); + } else {//edit + + } + + $scope.display.app.edit = !$scope.display.app.edit; + + } + + function updateAppInfo() { + $scope.submitBtnDisabled = true; + var app = $scope.viewApp; + + var selectedOrg = $orgWidget.select2('data')[0]; + + if (!selectedOrg.id) { + toastr.warning("请选择部门"); + return; + } + + app.orgId = selectedOrg.id; + app.orgName = selectedOrg.name; + + // owner + var owner = $('.ownerSelector').select2('data')[0]; + if (!owner) { + toastr.warning("请选择应用负责人"); + return; + } + app.ownerName = owner.id; + + AppService.update(app).then(function (app) { + toastr.success("修改成功"); + initApplication(); + $scope.display.app.edit = false; + $scope.submitBtnDisabled = false; + }, function (result) { + AppUtil.showErrorMsg(result); + $scope.submitBtnDisabled = false; + }) + + } +} diff --git a/apollo-portal/src/main/resources/static/scripts/controller/role/AppRoleController.js b/apollo-portal/src/main/resources/static/scripts/controller/role/AppRoleController.js deleted file mode 100644 index 7635cdc2d..000000000 --- a/apollo-portal/src/main/resources/static/scripts/controller/role/AppRoleController.js +++ /dev/null @@ -1,75 +0,0 @@ -role_module.controller('AppRoleController', - ['$scope', '$location', '$window', 'toastr', 'AppService', 'AppUtil', 'PermissionService', - function ($scope, $location, $window, toastr, AppService, AppUtil, PermissionService) { - - var params = AppUtil.parseParams($location.$$url); - $scope.pageContext = { - appId: params.appid - }; - - $scope.submitBtnDisabled = false; - - $scope.userSelectWidgetId = 'toAssignMasterRoleUser'; - - PermissionService.has_assign_user_permission($scope.pageContext.appId) - .then(function (result) { - $scope.hasAssignUserPermission = result.hasPermission; - }, function (reslt) { - - }); - - PermissionService.get_app_role_users($scope.pageContext.appId) - .then(function (result) { - $scope.appRoleUsers = result; - }, function (result) { - - }); - - - $scope.assignMasterRoleToUser = function () { - var user = $('.' + $scope.userSelectWidgetId).select2('data')[0]; - if (!user){ - toastr.warning("请选择用户"); - return; - } - var toAssignMasterRoleUser = user.id; - $scope.submitBtnDisabled = true; - PermissionService.assign_master_role($scope.pageContext.appId, - toAssignMasterRoleUser) - .then(function (result) { - $scope.submitBtnDisabled = false; - toastr.success("添加成功"); - $scope.appRoleUsers.masterUsers.push({userId: toAssignMasterRoleUser}); - $('.' + $scope.userSelectWidgetId).select2("val", ""); - }, function (result) { - $scope.submitBtnDisabled = false; - toastr.error(AppUtil.errorMsg(result), "添加失败"); - }); - }; - - $scope.removeMasterRoleFromUser = function (user) { - if ($scope.appRoleUsers.masterUsers.length <= 1) { - $('#warning').modal('show'); - return; - } - PermissionService.remove_master_role($scope.pageContext.appId, user) - .then(function (result) { - toastr.success("删除成功"); - removeUserFromList($scope.appRoleUsers.masterUsers, user); - }, function (result) { - toastr.error(AppUtil.errorMsg(result), "删除失败"); - }); - }; - - function removeUserFromList(list, user) { - var index = 0; - for (var i = 0; i < list.length; i++) { - if (list[i].userId == user) { - index = i; - break; - } - } - list.splice(index, 1); - } - - }]); diff --git a/apollo-portal/src/main/resources/static/scripts/directive/directive.js b/apollo-portal/src/main/resources/static/scripts/directive/directive.js index c5d7de5b6..01b002317 100644 --- a/apollo-portal/src/main/resources/static/scripts/directive/directive.js +++ b/apollo-portal/src/main/resources/static/scripts/directive/directive.js @@ -275,13 +275,14 @@ directive_module.directive('apollouserselector', function ($compile, $window) { transclude: true, replace: true, scope: { - id: '=apolloId' + id: '=apolloId', + disabled: '=' }, link: function (scope, element, attrs) { scope.$watch("id", initSelect2); - var searchUsersAjax = { + var select2Options = { ajax: { url: '/users', dataType: 'json', @@ -311,8 +312,9 @@ directive_module.directive('apollouserselector', function ($compile, $window) { }; function initSelect2() { - $('.' + scope.id).select2(searchUsersAjax); + $('.' + scope.id).select2(select2Options); } + } } diff --git a/apollo-portal/src/main/resources/static/scripts/services/AppService.js b/apollo-portal/src/main/resources/static/scripts/services/AppService.js index 6f15f25c3..14071c07b 100644 --- a/apollo-portal/src/main/resources/static/scripts/services/AppService.js +++ b/apollo-portal/src/main/resources/static/scripts/services/AppService.js @@ -11,7 +11,7 @@ appService.service('AppService', ['$resource', '$q', function ($resource, $q) { url: '/apps/by-owner' }, load_navtree: { - methode: 'GET', + method: 'GET', isArray: false, url: '/apps/:appId/navtree' }, @@ -23,6 +23,10 @@ appService.service('AppService', ['$resource', '$q', function ($resource, $q) { method: 'POST', url: '/apps' }, + update_app: { + method: 'PUT', + url: '/apps/:appId' + }, create_app_remote: { method: 'POST', url: '/apps/envs/:env' @@ -78,6 +82,17 @@ appService.service('AppService', ['$resource', '$q', function ($resource, $q) { }); return d.promise; }, + update: function (app) { + var d = $q.defer(); + app_resource.update_app({ + appId: app.appId + }, app, function (result) { + d.resolve(result); + }, function (result) { + d.reject(result); + }); + return d.promise; + }, create_remote: function (env, app) { var d = $q.defer(); app_resource.create_app_remote({env: env}, app, function (result) { diff --git a/apollo-portal/src/main/resources/static/scripts/valdr.js b/apollo-portal/src/main/resources/static/scripts/valdr.js index 21917708f..7f42e522b 100644 --- a/apollo-portal/src/main/resources/static/scripts/valdr.js +++ b/apollo-portal/src/main/resources/static/scripts/valdr.js @@ -1,4 +1,7 @@ -app_module.config(function (valdrProvider) { +app_module.config(appValdr); +setting_module.config(appValdr); + +function appValdr(valdrProvider) { valdrProvider.addConstraints({ 'App': { 'appId': { @@ -21,7 +24,7 @@ app_module.config(function (valdrProvider) { } } }) -}); +} cluster_module.config(function (valdrProvider) { valdrProvider.addConstraints({ diff --git a/apollo-portal/src/main/resources/static/styles/common-style.css b/apollo-portal/src/main/resources/static/styles/common-style.css index e34a1205f..082af3692 100644 --- a/apollo-portal/src/main/resources/static/styles/common-style.css +++ b/apollo-portal/src/main/resources/static/styles/common-style.css @@ -144,6 +144,7 @@ pre { .footer { width: 100%; height: 75px; + margin-top: 50px; padding-top: 25px; } @@ -494,14 +495,15 @@ table th { margin: 0; } -.list-group-item .icon-plus-orange { - background: url(../img/plus-orange.png) no-repeat; +.list-group-item .icon-project-manage { + background: url(../img/manage.png) no-repeat; } -.list-group-item .icon-user-manage { - background: url(../img/user_manage.png) no-repeat; +.list-group-item .icon-plus-orange { + background: url(../img/add.png) no-repeat; } + .list-group-item .icon-text { background-size: 20px; background-position: 5% 50%; @@ -790,3 +792,11 @@ table th { background: #fff; } +.project-setting .panel-body { + padding-top: 35px +} + +.project-setting .panel-body .context { + padding-left: 30px; +} + diff --git a/apollo-portal/src/main/resources/static/views/common/nav.html b/apollo-portal/src/main/resources/static/views/common/nav.html index dd9019620..5e30e7b4b 100644 --- a/apollo-portal/src/main/resources/static/views/common/nav.html +++ b/apollo-portal/src/main/resources/static/views/common/nav.html @@ -22,14 +22,14 @@