diff --git a/ui/src/config/router.js b/ui/src/config/router.js index 0c0699b818e..1ead309a18d 100644 --- a/ui/src/config/router.js +++ b/ui/src/config/router.js @@ -51,6 +51,9 @@ function generateRouterMap (section) { map.meta.permission = section.children[0].permission map.children = [] for (const child of section.children) { + if ('show' in child && !child.show()) { + continue + } var component = child.component ? child.component : AutogenView var route = { name: child.name, diff --git a/ui/src/config/section/network.js b/ui/src/config/section/network.js index 3acf1a2002a..d22a3c06e94 100644 --- a/ui/src/config/section/network.js +++ b/ui/src/config/section/network.js @@ -184,6 +184,16 @@ export default { name: 'egress.rule', component: () => import('@/views/network/IngressEgressRuleConfigure.vue') }], + show: () => { + if (!store.getters.zones || store.getters.zones.length === 0) { + return false + } + const listZoneHaveSGEnabled = store.getters.zones.filter(zone => zone.securitygroupsenabled === true) + if (!listZoneHaveSGEnabled || listZoneHaveSGEnabled.length === 0) { + return false + } + return true + }, actions: [ { api: 'createSecurityGroup', diff --git a/ui/src/config/section/user.js b/ui/src/config/section/user.js index e5e853aa0b9..0b6d5041420 100644 --- a/ui/src/config/section/user.js +++ b/ui/src/config/section/user.js @@ -30,14 +30,16 @@ export default { icon: 'plus', label: 'label.add.user', listView: true, - args: ['username', 'password', 'confirmpassword', 'email', 'firstname', 'lastname', 'timezone', 'account', 'domainid'] + popup: true, + component: () => import('@/views/iam/AddUser.vue') }, { api: 'updateUser', icon: 'edit', label: 'label.edit', dataView: true, - args: ['username', 'email', 'firstname', 'lastname', 'timezone'] + popup: true, + component: () => import('@/views/iam/EditUser.vue') }, { api: 'updateUser', diff --git a/ui/src/locales/en.json b/ui/src/locales/en.json index f0831d852a2..4d92e475e54 100644 --- a/ui/src/locales/en.json +++ b/ui/src/locales/en.json @@ -608,6 +608,7 @@ "label.create.nfs.secondary.staging.storage": "Create NFS Secondary Staging Store", "label.create.nfs.secondary.staging.store": "Create NFS secondary staging store", "label.create.project": "Create project", +"label.create.user": "Create user", "label.create.site.vpn.connection": "Create Site-to-Site VPN Connection", "label.create.site.vpn.gateway": "Create Site-to-Site VPN Gateway", "label.create.ssh.key.pair": "Create a SSH Key Pair", @@ -795,6 +796,7 @@ "label.edit.region": "Edit Region", "label.edit.role": "Edit Role", "label.edit.rule": "Edit rule", +"label.edit.user": "Edit user", "label.edit.secondary.ips": "Edit secondary IPs", "label.edit.tags": "Edit tags", "label.edit.traffic.type": "Edit traffic type", @@ -2996,6 +2998,9 @@ "message.step.4.continue": "Please select at least one network to continue", "message.step.4.desc": "Please select the primary network that your virtual instance will be connected to.", "message.storage.traffic": "Traffic between CloudStack's internal resources, including any components that communicate with the Management Server, such as hosts and CloudStack system VMs. Please configure storage traffic here.", +"message.success.enable.saml.auth": "Successfully enabled SAML Authorization", +"message.success.create.user": "Successfully created user", +"message.success.update.user": "Successfully updated user", "message.success.acquire.ip": "Successfully acquired IP", "message.success.add.egress.rule": "Successfully added new Egress rule", "message.success.add.firewall.rule": "Successfully added new Firewall rule", diff --git a/ui/src/store/getters.js b/ui/src/store/getters.js index aad4a889303..73042aaf5ab 100644 --- a/ui/src/store/getters.js +++ b/ui/src/store/getters.js @@ -32,7 +32,8 @@ const getters = { multiTab: state => state.app.multiTab, asyncJobIds: state => state.user.asyncJobIds, isLdapEnabled: state => state.user.isLdapEnabled, - cloudian: state => state.user.cloudian + cloudian: state => state.user.cloudian, + zones: state => state.user.zones } export default getters diff --git a/ui/src/store/modules/user.js b/ui/src/store/modules/user.js index 3fa46dac63d..c39e2f4dbb0 100644 --- a/ui/src/store/modules/user.js +++ b/ui/src/store/modules/user.js @@ -23,7 +23,7 @@ import router from '@/router' import store from '@/store' import { login, logout, api } from '@/api' import i18n from '@/locales' -import { ACCESS_TOKEN, CURRENT_PROJECT, DEFAULT_THEME, APIS, ASYNC_JOB_IDS } from '@/store/mutation-types' +import { ACCESS_TOKEN, CURRENT_PROJECT, DEFAULT_THEME, APIS, ASYNC_JOB_IDS, ZONES } from '@/store/mutation-types' const user = { state: { @@ -36,7 +36,8 @@ const user = { project: {}, asyncJobIds: [], isLdapEnabled: false, - cloudian: {} + cloudian: {}, + zones: {} }, mutations: { @@ -75,6 +76,10 @@ const user = { }, RESET_THEME: (state) => { Vue.ls.set(DEFAULT_THEME, 'light') + }, + SET_ZONES: (state, zones) => { + state.zones = zones + Vue.ls.set(ZONES, zones) } }, @@ -119,9 +124,11 @@ const user = { GetInfo ({ commit }) { return new Promise((resolve, reject) => { const cachedApis = Vue.ls.get(APIS, {}) + const cachedZones = Vue.ls.get(ZONES, []) const hasAuth = Object.keys(cachedApis).length > 0 if (hasAuth) { console.log('Login detected, using cached APIs') + commit('SET_ZONES', cachedZones) commit('SET_APIS', cachedApis) // Ensuring we get the user info so that store.getters.user is never empty when the page is freshly loaded @@ -140,6 +147,10 @@ const user = { }) } else { const hide = message.loading(i18n.t('message.discovering.feature'), 0) + api('listZones', { listall: true }).then(json => { + const zones = json.listzonesresponse.zone || [] + commit('SET_ZONES', zones) + }) api('listApis').then(response => { const apis = {} const apiList = response.listapisresponse.api diff --git a/ui/src/store/mutation-types.js b/ui/src/store/mutation-types.js index 9a925706ba5..caec6a44358 100644 --- a/ui/src/store/mutation-types.js +++ b/ui/src/store/mutation-types.js @@ -28,6 +28,7 @@ export const DEFAULT_FIXED_HEADER_HIDDEN = 'DEFAULT_FIXED_HEADER_HIDDEN' export const DEFAULT_CONTENT_WIDTH_TYPE = 'DEFAULT_CONTENT_WIDTH_TYPE' export const DEFAULT_MULTI_TAB = 'DEFAULT_MULTI_TAB' export const APIS = 'APIS' +export const ZONES = 'ZONES' export const ASYNC_JOB_IDS = 'ASYNC_JOB_IDS' export const CONTENT_WIDTH_TYPE = { diff --git a/ui/src/views/compute/DeployVM.vue b/ui/src/views/compute/DeployVM.vue index 152926bc0d8..30119798d46 100644 --- a/ui/src/views/compute/DeployVM.vue +++ b/ui/src/views/compute/DeployVM.vue @@ -215,6 +215,7 @@