This is an automated email from the ASF dual-hosted git repository.

rohit pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/main by this push:
     new b280370a983 Few UI fixes and details improvements (#7434)
b280370a983 is described below

commit b280370a983aca2fa5c065960c25786e9b40341b
Author: Harikrishna <[email protected]>
AuthorDate: Tue May 2 17:06:54 2023 +0530

    Few UI fixes and details improvements (#7434)
    
    * Better hover label and message for generate API/secret keys form
    
    * Added a message to select network during instance deployment
    
    * Removed project icon in dashboard listing
    
    * Disable network operations for the user who does not have permission
    
    * UI allignments
    
    * added document help for sticky policy secion under load balancer
    
    * Added tooltips and some form layout changes
    
    * donot display options to configure when stickypolicy is none
    
    * Network selection message allignment
    
    * Fixed the grid view to be uniform in infra summary page
---
 .../loadbalancer/CreateLBStickinessPolicyCmd.java  |   2 +-
 ui/public/locales/en.json                          |   5 +-
 ui/src/components/header/ProjectMenu.vue           |  12 --
 ui/src/components/view/ActionButton.vue            |   5 +-
 ui/src/config/section/network.js                   |   3 +
 ui/src/config/section/user.js                      |   1 +
 ui/src/views/AutogenView.vue                       |  11 +-
 ui/src/views/compute/DeployVM.vue                  |   5 +-
 ui/src/views/infra/InfraSummary.vue                |   4 +-
 ui/src/views/network/LoadBalancing.vue             | 121 ++++++++++++---------
 10 files changed, 97 insertions(+), 72 deletions(-)

diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBStickinessPolicyCmd.java
 
b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBStickinessPolicyCmd.java
index 45e6f81a0aa..66a15984ae4 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBStickinessPolicyCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBStickinessPolicyCmd.java
@@ -68,7 +68,7 @@ public class CreateLBStickinessPolicyCmd extends 
BaseAsyncCreateCmd {
     @Parameter(name = ApiConstants.METHOD_NAME,
                type = CommandType.STRING,
                required = true,
-               description = "name of the load balancer stickiness policy 
method, possible values can be obtained from listNetworks API")
+               description = "name of the load balancer stickiness policy 
method, possible values are LbCookie, AppCookie, SourceBased")
     private String stickinessMethodName;
 
     @Parameter(name = ApiConstants.PARAM_LIST, type = CommandType.MAP, 
description = "param list. Example: 
param[0].name=cookiename&param[0].value=LBCookie ")
diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json
index dfa813238be..5284a3b1379 100644
--- a/ui/public/locales/en.json
+++ b/ui/public/locales/en.json
@@ -123,6 +123,7 @@
 "label.action.expunge.instance": "Expunge instance",
 "label.action.force.reconnect": "Force reconnect",
 "label.action.generate.keys": "Generate keys",
+"label.action.generate.api.secret.keys": "Generate New API/Secret Keys",
 "label.action.get.diagnostics": "Get diagnostics data",
 "label.action.health.monitor": "Health monitor",
 "label.action.image.store.read.only": "Make image store read-only",
@@ -2691,7 +2692,7 @@
 "message.failed.to.add": "Failed to add",
 "message.failed.to.assign.vms": "Failed to assign VMs",
 "message.failed.to.remove": "Failed to remove",
-"message.generate.keys": "Please confirm that you would like to generate new 
keys for this user.",
+"message.generate.keys": "Please confirm that you would like to generate new 
API/Secret keys for this user.",
 "message.chart.statistic.info": "The shown charts are self-adjustable, that 
means, if the value gets close to the limit or overpass it, it will grow to 
adjust the shown value",
 "message.guest.traffic.in.advanced.zone": "Guest network traffic is 
communication between end-user virtual machines. Specify a range of VLAN IDs or 
VXLAN network identifiers (VNIs) to carry guest traffic for each physical 
network.",
 "message.guest.traffic.in.basic.zone": "Guest network traffic is communication 
between end-user virtual machines. Specify a range of IP addresses that 
CloudStack can assign to guest VMs. Make sure this range does not overlap the 
reserved system IP range.",
@@ -2743,6 +2744,7 @@
 "message.linstor.resourcegroup.description": "Linstor resource group to use 
for primary storage.",
 "message.listnsp.not.return.providerid": "error: listNetworkServiceProviders 
API doesn't return VirtualRouter provider ID.",
 "message.load.host.failed": "Failed to load hosts.",
+"message.loadbalancer.stickypolicy.configuration": "Customize the load 
balancer stickiness policy:",
 "message.loading.add.interface.static.route": "Adding interface Static 
Route...",
 "message.loading.add.network.static.route": "Adding network Static Route...",
 "message.loading.add.policy.rule": "Adding Policy rule...",
@@ -2786,6 +2788,7 @@
 "message.network.offering.promiscuous.mode": "Applicable for guest networks on 
VMware hypervisor only.\nReject - The switch drops any outbound frame from a 
virtual machine adapter with a source MAC address that is different from the 
one in the .vmx configuration file.\nAccept - The switch does not perform 
filtering, and permits all outbound frames.\nNone - Default to value from 
global setting.",
 "message.network.removenic": "Please confirm that want to remove this NIC, 
which will also remove the associated network from the VM.",
 "message.network.secondaryip": "Please confirm that you would like to acquire 
a new secondary IP for this NIC. \n NOTE: You need to manually configure the 
newly-acquired secondary IP inside the virtual machine.",
+"message.network.selection": "Choose one or more networks to attach the 
instance to. A new network can also be created here.",
 "message.network.updateip": "Please confirm that you would like to change the 
IP address for this NIC on VM.",
 "message.network.usage.info.data.points": "Each data point represents the 
difference in data traffic since the last data point.",
 "message.network.usage.info.sum.of.vnics": "The network usage shown is made up 
of the sum of data traffic from all the vNICs in the VM.",
diff --git a/ui/src/components/header/ProjectMenu.vue 
b/ui/src/components/header/ProjectMenu.vue
index 722bc2877d6..11b1a7957e4 100644
--- a/ui/src/components/header/ProjectMenu.vue
+++ b/ui/src/components/header/ProjectMenu.vue
@@ -27,18 +27,6 @@
       @focus="fetchData"
       showSearch>
 
-      <template #suffixIcon>
-        <a-tooltip placement="bottom">
-          <template #title>
-            <span>{{ $t('label.projects') }}</span>
-          </template>
-          <span class="custom-suffix-icon">
-            <ProjectOutlined v-if="!loading" class="ant-select-suffix" />
-            <LoadingOutlined v-else />
-          </span>
-        </a-tooltip>
-      </template>
-
       <a-select-option
         v-for="(project, index) in projects"
         :key="index"
diff --git a/ui/src/components/view/ActionButton.vue 
b/ui/src/components/view/ActionButton.vue
index 5f5761cbe1c..f15ec2fd9f3 100644
--- a/ui/src/components/view/ActionButton.vue
+++ b/ui/src/components/view/ActionButton.vue
@@ -47,7 +47,10 @@
       :key="actionIndex"
       arrowPointAtCenter
       placement="bottomRight">
-      <template #title>
+      <template v-if="action.hoverLabel" #title>
+        {{ $t(action.hoverLabel) }}
+      </template>
+      <template v-else #title>
         {{ $t(action.label) }}
       </template>
       <a-badge
diff --git a/ui/src/config/section/network.js b/ui/src/config/section/network.js
index c83c1ddb8fd..281479dc73c 100644
--- a/ui/src/config/section/network.js
+++ b/ui/src/config/section/network.js
@@ -130,6 +130,7 @@ export default {
           icon: 'edit-outlined',
           label: 'label.update.network',
           dataView: true,
+          disabled: (record, user) => { return (record.account !== 
user.userInfo.account && !['Admin', 
'DomainAdmin'].includes(user.userInfo.roletype)) },
           popup: true,
           component: shallowRef(defineAsyncComponent(() => 
import('@/views/network/UpdateNetwork.vue')))
         },
@@ -139,6 +140,7 @@ export default {
           label: 'label.restart.network',
           message: 'message.restart.network',
           dataView: true,
+          disabled: (record, user) => { return (record.account !== 
user.userInfo.account && !['Admin', 
'DomainAdmin'].includes(user.userInfo.roletype)) },
           args: (record, store, isGroupAction) => {
             var fields = []
             if (isGroupAction || record.vpcid == null) {
@@ -177,6 +179,7 @@ export default {
           label: 'label.action.delete.network',
           message: 'message.action.delete.network',
           dataView: true,
+          disabled: (record, user) => { return (record.account !== 
user.userInfo.account && !['Admin', 
'DomainAdmin'].includes(user.userInfo.roletype)) },
           groupAction: true,
           popup: true,
           groupMap: (selection) => { return selection.map(x => { return { id: 
x } }) }
diff --git a/ui/src/config/section/user.js b/ui/src/config/section/user.js
index c5a3325e892..eef9ea3f939 100644
--- a/ui/src/config/section/user.js
+++ b/ui/src/config/section/user.js
@@ -68,6 +68,7 @@ export default {
       api: 'registerUserKeys',
       icon: 'file-protect-outlined',
       label: 'label.action.generate.keys',
+      hoverLabel: 'label.action.generate.api.secret.keys',
       message: 'message.generate.keys',
       dataView: true
     },
diff --git a/ui/src/views/AutogenView.vue b/ui/src/views/AutogenView.vue
index fd241fee163..44c5b5bea19 100644
--- a/ui/src/views/AutogenView.vue
+++ b/ui/src/views/AutogenView.vue
@@ -20,7 +20,7 @@
     <a-affix :offsetTop="this.$store.getters.shutdownTriggered ? 103 : 78">
       <a-card class="breadcrumb-card" style="z-index: 10">
         <a-row>
-          <a-col :span="device === 'mobile' ? 24 : 12" style="padding-left: 
12px">
+          <a-col :span="device === 'mobile' ? 24 : 12" style="padding-left: 
12px; margin-top: 10px">
             <breadcrumb :resource="resource">
               <template #end>
                 <a-button
@@ -34,14 +34,14 @@
                 </a-button>
                 <a-switch
                   v-if="!dataView && ['vm', 'volume', 'zone', 'cluster', 
'host', 'storagepool', 'managementserver'].includes($route.name)"
-                  style="margin-left: 8px"
+                  style="margin-left: 8px; margin-bottom: 3px"
                   :checked-children="$t('label.metrics')"
                   :un-checked-children="$t('label.metrics')"
                   :checked="$store.getters.metrics"
                   @change="(checked, event) => { $store.dispatch('SetMetrics', 
checked) }"/>
                 <a-switch
                   v-if="!projectView && hasProjectId"
-                  style="margin-left: 8px"
+                  style="margin-left: 8px; margin-bottom: 3px"
                   :checked-children="$t('label.projects')"
                   :un-checked-children="$t('label.projects')"
                   :checked="$store.getters.listAllProjects"
@@ -54,7 +54,7 @@
                     v-if="!dataView && filters && filters.length > 0"
                     :placeholder="$t('label.filterby')"
                     :value="filterValue"
-                    style="min-width: 120px; margin-left: 10px"
+                    style="min-width: 120px; margin-left: 10px; margin-top: 
-4px"
                     @change="changeFilter"
                     showSearch
                     optionFilterProp="label"
@@ -84,7 +84,7 @@
           </a-col>
           <a-col
             :span="device === 'mobile' ? 24 : 12"
-            :style="device === 'mobile' ? { float: 'right', 'margin-top': 
'12px', 'margin-bottom': '-6px', display: 'table' } : { float: 'right', 
display: 'table', 'margin-bottom': '-6px' }" >
+            :style="device === 'mobile' ? { float: 'right', 'margin-top': 
'12px', 'margin-bottom': '-6px', display: 'table' } : { float: 'right', 
display: 'table', 'margin-bottom': '-4px' }" >
             <slot name="action" v-if="dataView && 
$route.path.startsWith('/publicip')"></slot>
             <action-button
               v-else
@@ -99,6 +99,7 @@
             <search-view
               v-if="!dataView"
               :searchFilters="searchFilters"
+              style="min-width: 120px; margin-left: 10px; margin-top: 5px"
               :searchParams="searchParams"
               :apiName="apiName"
               @search="onSearch"
diff --git a/ui/src/views/compute/DeployVM.vue 
b/ui/src/views/compute/DeployVM.vue
index 42eda874a87..064dac21e79 100644
--- a/ui/src/views/compute/DeployVM.vue
+++ b/ui/src/views/compute/DeployVM.vue
@@ -387,7 +387,10 @@
                 :status="zoneSelected ? 'process' : 'wait'"
                 v-if="zone && zone.networktype !== 'Basic'">
                 <template #description>
-                  <div v-if="zoneSelected">
+                  <div v-if="zoneSelected" style="margin-top: 5px">
+                    <div style="margin-bottom: 10px">
+                      {{ $t('message.network.selection') }}
+                    </div>
                     <div v-if="vm.templateid && templateNics && 
templateNics.length > 0">
                       <instance-nics-network-select-list-view
                         :nics="templateNics"
diff --git a/ui/src/views/infra/InfraSummary.vue 
b/ui/src/views/infra/InfraSummary.vue
index 941d15b440d..8411dca373c 100644
--- a/ui/src/views/infra/InfraSummary.vue
+++ b/ui/src/views/infra/InfraSummary.vue
@@ -149,8 +149,10 @@
     </a-col>
     <template v-for="(section, index) in sections" :key="index">
       <a-col
+        :xs="12"
+        :sm="8"
         :md="6"
-        style="margin-bottom: 12px"
+        :style="{ marginBottom: '12px' }"
         v-if="routes[section]">
         <chart-card :loading="loading">
           <div class="chart-card-inner">
diff --git a/ui/src/views/network/LoadBalancing.vue 
b/ui/src/views/network/LoadBalancing.vue
index 460d3529a0e..a03bc38e71f 100644
--- a/ui/src/views/network/LoadBalancing.vue
+++ b/ui/src/views/network/LoadBalancing.vue
@@ -267,7 +267,6 @@
     </a-modal>
 
     <a-modal
-      :title="$t('label.configure.sticky.policy')"
       :visible="stickinessModalVisible"
       :footer="null"
       :afterClose="closeModal"
@@ -276,6 +275,16 @@
       :okButtonProps="{ props: {htmlType: 'submit'}}"
       @cancel="stickinessModalVisible = false">
 
+      <template #title>
+        <span>{{ $t('label.configure.sticky.policy') }}</span>
+        <a
+          style="margin-left: 5px"
+          :href="$config.docBase + 
'/adminguide/networking/external_firewalls_and_load_balancers.html#sticky-session-policies-for-load-balancer-rules'"
+          target="_blank">
+          <question-circle-outlined />
+        </a>
+      </template>
+
       <span v-show="stickinessModalLoading" class="modal-loading">
         <loading-outlined />
       </span>
@@ -288,7 +297,10 @@
         v-ctrl-enter="handleSubmitStickinessForm"
         class="custom-ant-form"
        >
-        <a-form-item name="methodname" ref="methodname" 
:label="$t('label.stickiness.method')">
+        <a-form-item name="methodname" ref="methodname">
+          <template #label>
+            <tooltip-label :title="$t('label.stickiness.method')" 
:tooltip="createLoadBalancerStickinessPolicyParams.methodname.description" 
:tooltip-placement="'right'"/>
+          </template>
           <a-select
             v-focus="true"
             v-model:value="form.methodname"
@@ -307,58 +319,66 @@
         <a-form-item
           name="name"
           ref="name"
-          :label="$t('label.sticky.name')"
           v-show="stickinessPolicyMethod === 'LbCookie' || 
stickinessPolicyMethod ===
             'AppCookie' || stickinessPolicyMethod === 'SourceBased'">
           <a-input v-model:value="form.name" />
+          <template #label>
+            <tooltip-label :title="$t('label.sticky.name')" 
:tooltip="createLoadBalancerStickinessPolicyParams.name.description" 
:tooltip-placement="'right'"/>
+          </template>
         </a-form-item>
-        <a-form-item
-          name="cookieName"
-          ref="cookieName"
-          :label="$t('label.sticky.cookie-name')"
-          v-show="stickinessPolicyMethod === 'LbCookie' || 
stickinessPolicyMethod ===
-            'AppCookie'">
-          <a-input v-model:value="form.cookieName" />
-        </a-form-item>
-        <a-form-item
-          name="mode"
-          ref="mode"
-          :label="$t('label.sticky.mode')"
-          v-show="stickinessPolicyMethod === 'LbCookie' || 
stickinessPolicyMethod ===
-            'AppCookie'">
-          <a-input v-model:value="form.mode" />
-        </a-form-item>
-        <a-form-item name="nocache" ref="nocache" 
:label="$t('label.sticky.nocache')" v-show="stickinessPolicyMethod === 
'LbCookie'">
-          <a-checkbox v-model:checked="form.nocache"></a-checkbox>
-        </a-form-item>
-        <a-form-item name="indirect" ref="indirect" 
:label="$t('label.sticky.indirect')" v-show="stickinessPolicyMethod === 
'LbCookie'">
-          <a-checkbox v-model:checked="form.indirect"></a-checkbox>
-        </a-form-item>
-        <a-form-item name="postonly" ref="postonly" 
:label="$t('label.sticky.postonly')" v-show="stickinessPolicyMethod === 
'LbCookie'">
-          <a-checkbox v-model:checked="form.postonly"></a-checkbox>
-        </a-form-item>
-        <a-form-item name="domain" ref="domain" :label="$t('label.domain')" 
v-show="stickinessPolicyMethod === 'LbCookie'">
-          <a-input v-model:value="form.domain" />
-        </a-form-item>
-        <a-form-item name="length" ref="length" 
:label="$t('label.sticky.length')" v-show="stickinessPolicyMethod === 
'AppCookie'">
-          <a-input v-model:value="form.length" type="number" />
-        </a-form-item>
-        <a-form-item name="holdtime" ref="holdtime" 
:label="$t('label.sticky.holdtime')" v-show="stickinessPolicyMethod === 
'AppCookie'">
-          <a-input v-model:value="form.holdtime" type="number" />
-        </a-form-item>
-        <a-form-item name="requestLearn" ref="requestLearn" 
:label="$t('label.sticky.request-learn')" v-show="stickinessPolicyMethod === 
'AppCookie'">
-          <a-checkbox v-model:checked="form.requestLearn"></a-checkbox>
-        </a-form-item>
-        <a-form-item name="prefix" ref="prefix" 
:label="$t('label.sticky.prefix')" v-show="stickinessPolicyMethod === 
'AppCookie'">
-          <a-checkbox v-model:checked="form.prefix"></a-checkbox>
-        </a-form-item>
-        <a-form-item name="tablesize" ref="tablesize" 
:label="$t('label.sticky.tablesize')" v-show="stickinessPolicyMethod === 
'SourceBased'">
-          <a-input v-model:value="form.tablesize" />
-        </a-form-item>
-        <a-form-item name="expire" ref="expire" 
:label="$t('label.sticky.expire')" v-show="stickinessPolicyMethod === 
'SourceBased'">
-          <a-input v-model:value="form.expire" />
-        </a-form-item>
-
+        <div v-if="stickinessPolicyMethod !== 'none'">
+          <br/>
+          {{ $t('message.loadbalancer.stickypolicy.configuration') }}
+          <br/>
+          <a-card>
+            <a-form-item
+              name="cookieName"
+              ref="cookieName"
+              :label="$t('label.sticky.cookie-name')"
+              v-show="stickinessPolicyMethod === 'LbCookie' || 
stickinessPolicyMethod ===
+                'AppCookie'">
+              <a-input v-model:value="form.cookieName" />
+            </a-form-item>
+            <a-form-item
+              name="mode"
+              ref="mode"
+              :label="$t('label.sticky.mode')"
+              v-show="stickinessPolicyMethod === 'LbCookie' || 
stickinessPolicyMethod ===
+                'AppCookie'">
+              <a-input v-model:value="form.mode" />
+            </a-form-item>
+            <a-form-item name="nocache" ref="nocache" 
:label="$t('label.sticky.nocache')" v-show="stickinessPolicyMethod === 
'LbCookie'">
+              <a-checkbox v-model:checked="form.nocache"></a-checkbox>
+            </a-form-item>
+            <a-form-item name="indirect" ref="indirect" 
:label="$t('label.sticky.indirect')" v-show="stickinessPolicyMethod === 
'LbCookie'">
+              <a-checkbox v-model:checked="form.indirect"></a-checkbox>
+            </a-form-item>
+            <a-form-item name="postonly" ref="postonly" 
:label="$t('label.sticky.postonly')" v-show="stickinessPolicyMethod === 
'LbCookie'">
+              <a-checkbox v-model:checked="form.postonly"></a-checkbox>
+            </a-form-item>
+            <a-form-item name="domain" ref="domain" 
:label="$t('label.domain')" v-show="stickinessPolicyMethod === 'LbCookie'">
+              <a-input v-model:value="form.domain" />
+            </a-form-item>
+            <a-form-item name="length" ref="length" 
:label="$t('label.sticky.length')" v-show="stickinessPolicyMethod === 
'AppCookie'">
+              <a-input v-model:value="form.length" type="number" />
+            </a-form-item>
+            <a-form-item name="holdtime" ref="holdtime" 
:label="$t('label.sticky.holdtime')" v-show="stickinessPolicyMethod === 
'AppCookie'">
+              <a-input v-model:value="form.holdtime" type="number" />
+            </a-form-item>
+            <a-form-item name="requestLearn" ref="requestLearn" 
:label="$t('label.sticky.request-learn')" v-show="stickinessPolicyMethod === 
'AppCookie'">
+              <a-checkbox v-model:checked="form.requestLearn"></a-checkbox>
+            </a-form-item>
+            <a-form-item name="prefix" ref="prefix" 
:label="$t('label.sticky.prefix')" v-show="stickinessPolicyMethod === 
'AppCookie'">
+              <a-checkbox v-model:checked="form.prefix"></a-checkbox>
+            </a-form-item>
+            <a-form-item name="tablesize" ref="tablesize" 
:label="$t('label.sticky.tablesize')" v-show="stickinessPolicyMethod === 
'SourceBased'">
+              <a-input v-model:value="form.tablesize" />
+            </a-form-item>
+            <a-form-item name="expire" ref="expire" 
:label="$t('label.sticky.expire')" v-show="stickinessPolicyMethod === 
'SourceBased'">
+              <a-input v-model:value="form.expire" />
+            </a-form-item>
+          </a-card>
+        </div>
         <div :span="24" class="action-button">
           <a-button @click="stickinessModalVisible = false">{{ 
$t('label.cancel') }}</a-button>
           <a-button type="primary" ref="submit" 
@click="handleSubmitStickinessForm">{{ $t('label.ok') }}</a-button>
@@ -804,6 +824,7 @@ export default {
   },
   beforeCreate () {
     this.createLoadBalancerRuleParams = 
this.$getApiParams('createLoadBalancerRule')
+    this.createLoadBalancerStickinessPolicyParams = 
this.$getApiParams('createLBStickinessPolicy')
   },
   created () {
     this.initForm()

Reply via email to