Show time correctly in the backup schedule UI  (#12012)

diff --git a/ui/src/views/compute/backup/BackupSchedule.vue b/ui/src/views/compute/backup/BackupSchedule.vue
index 627bcd8..b3e894e 100644
--- a/ui/src/views/compute/backup/BackupSchedule.vue
+++ b/ui/src/views/compute/backup/BackupSchedule.vue
@@ -99,7 +99,7 @@
       default: false
     },
     dataSource: {
-      type: Object,
+      type: Array,
       required: true
     },
     deleteFn: {
@@ -128,6 +128,7 @@
           dataIndex: 'intervaltype'
         },
         {
+          key: 'time',
           title: this.$t('label.time'),
           dataIndex: 'schedule'
         },
diff --git a/ui/src/views/compute/backup/FormSchedule.vue b/ui/src/views/compute/backup/FormSchedule.vue
index 1833449..7d951de 100644
--- a/ui/src/views/compute/backup/FormSchedule.vue
+++ b/ui/src/views/compute/backup/FormSchedule.vue
@@ -35,16 +35,16 @@
                   v-model:value="form.intervaltype"
                   button-style="solid"
                   @change="handleChangeIntervalType">
-                  <a-radio-button value="hourly">
+                  <a-radio-button value="hourly" :disabled="isIntervalDisabled('hourly')">
                     {{ $t('label.hourly') }}
                   </a-radio-button>
-                  <a-radio-button value="daily">
+                  <a-radio-button value="daily" :disabled="isIntervalDisabled('daily')">
                     {{ $t('label.daily') }}
                   </a-radio-button>
-                  <a-radio-button value="weekly">
+                  <a-radio-button value="weekly" :disabled="isIntervalDisabled('weekly')">
                     {{ $t('label.weekly') }}
                   </a-radio-button>
-                  <a-radio-button value="monthly">
+                  <a-radio-button value="monthly" :disabled="isIntervalDisabled('monthly')">
                     {{ $t('label.monthly') }}
                   </a-radio-button>
                 </a-radio-group>
@@ -54,6 +54,7 @@
               <a-form-item :label="$t('label.time')" ref="time" name="time">
                 <a-input-number
                   style="width: 100%"
+                  :disabled="isIntervalDisabled(form.intervaltype)"
                   v-model:value="form.time"
                   :placeholder="$t('label.minute.past.hour')"
                   :min="1"
@@ -70,6 +71,7 @@
                 <a-time-picker
                   use12Hours
                   format="h:mm A"
+                  :disabled="isIntervalDisabled(form.intervaltype)"
                   v-model:value="form.timeSelect"
                   style="width: 100%;" />
               </a-form-item>
@@ -79,6 +81,7 @@
                 <a-select
                   v-model:value="form['day-of-week']"
                   showSearch
+                  :disabled="isIntervalDisabled(form.intervaltype)"
                   optionFilterProp="label"
                   :filterOption="(input, option) => {
                     return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
@@ -94,6 +97,7 @@
                 <a-select
                   v-model:value="form['day-of-month']"
                   showSearch
+                  :disabled="isIntervalDisabled(form.intervaltype)"
                   optionFilterProp="label"
                   :filterOption="(input, option) => {
                     return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
@@ -180,6 +184,10 @@
       type: Boolean,
       default: false
     },
+    dataSource: {
+      type: Array,
+      required: true
+    },
     resource: {
       type: Object,
       required: true
@@ -210,6 +218,38 @@
     this.fetchTimeZone()
     this.fetchBackupOffering()
   },
+  mounted () {
+    if (this.form.intervaltype && this.isIntervalDisabled(this.form.intervaltype)) {
+      const nextAvailable = this.getNextAvailableIntervalType(this.form.intervaltype)
+      if (nextAvailable) {
+        this.form.intervaltype = nextAvailable
+        this.handleChangeIntervalType()
+      }
+    }
+  },
+  watch: {
+    dataSource: {
+      handler () {
+        if (this.form.intervaltype && this.getNextAvailableIntervalType && this.isIntervalDisabled(this.form.intervaltype)) {
+          const nextAvailable = this.getNextAvailableIntervalType(this.form.intervaltype)
+          if (nextAvailable) {
+            this.form.intervaltype = nextAvailable
+            this.handleChangeIntervalType()
+          }
+        }
+      },
+      deep: true
+    },
+    'form.intervaltype' (newVal) {
+      if (newVal && this.getNextAvailableIntervalType && this.isIntervalDisabled(newVal)) {
+        const nextAvailable = this.getNextAvailableIntervalType(newVal)
+        if (nextAvailable) {
+          this.form.intervaltype = nextAvailable
+          this.handleChangeIntervalType()
+        }
+      }
+    }
+  },
   inject: ['refreshSchedule', 'closeSchedule'],
   computed: {
     isQuiesceVmSupported () {
@@ -274,19 +314,39 @@
         })
       }
     },
-    handleChangeIntervalType (e) {
-      switch (this.form.intervaltype) {
-        case 'weekly':
-          this.fetchDayOfWeek()
-          break
-        case 'monthly':
-          this.intervalValue = 'MONTHLY'
-          this.fetchDayOfMonth()
-          break
-        default:
-          break
+    handleChangeIntervalType () {
+      if (this.form.intervaltype === 'weekly') {
+        this.fetchDayOfWeek()
+      } else if (this.form.intervaltype === 'monthly') {
+        this.fetchDayOfMonth()
       }
     },
+    getNextAvailableIntervalType (currentIntervalType) {
+      const intervalTypes = ['hourly', 'daily', 'weekly', 'monthly']
+      const currentIndex = intervalTypes.indexOf(currentIntervalType ? currentIntervalType.toLowerCase() : '')
+      const startIndex = currentIndex >= 0 ? currentIndex : -1
+
+      for (let i = 1; i <= intervalTypes.length; i++) {
+        const nextIndex = (startIndex + i) % intervalTypes.length
+        const nextIntervalType = intervalTypes[nextIndex]
+
+        if (!this.isIntervalDisabled(nextIntervalType)) {
+          return nextIntervalType
+        }
+      }
+      return null
+    },
+    isIntervalDisabled (intervalType) {
+      intervalType = intervalType.toUpperCase()
+      if (this.dataSource?.length === 0) {
+        return false
+      }
+      const dataSource = this.dataSource.filter(item => item.intervaltype === intervalType)
+      if (dataSource && dataSource.length > 0) {
+        return true
+      }
+      return false
+    },
     handleSubmit (e) {
       if (this.actionLoading) return
       this.formRef.value.validate().then(() => {
@@ -294,7 +354,7 @@
         const values = this.handleRemoveFields(formRaw)
         const params = {}
         params.virtualmachineid = this.resource.id
-        params.intervaltype = values.intervaltype
+        params.intervaltype = values.intervaltype.toUpperCase()
         params.maxbackups = values.maxbackups
         params.timezone = values.timezone
         if (values.quiescevm) {
diff --git a/ui/src/views/compute/wizard/DeployInstanceBackupSelection.vue b/ui/src/views/compute/wizard/DeployInstanceBackupSelection.vue
index 6f6c0b5..d35ed00 100644
--- a/ui/src/views/compute/wizard/DeployInstanceBackupSelection.vue
+++ b/ui/src/views/compute/wizard/DeployInstanceBackupSelection.vue
@@ -55,6 +55,7 @@
       @cancel="closeModals">
       <form-schedule
         :resource="addFormResource"
+        :dataSource="dataSource"
         :submitFn="handleAddBackupSchedule" />
     </a-modal>
   </div>
@@ -90,7 +91,8 @@
     return {
       backupOffering: null,
       showAddBackupSchedule: false,
-      localBackupOfferingId: this.backupOfferingId
+      localBackupOfferingId: this.backupOfferingId,
+      dataSource: []
     }
   },
   provide () {
diff --git a/ui/src/views/storage/FormSchedule.vue b/ui/src/views/storage/FormSchedule.vue
index acc12e8..433e399 100644
--- a/ui/src/views/storage/FormSchedule.vue
+++ b/ui/src/views/storage/FormSchedule.vue
@@ -38,16 +38,16 @@
                   v-model:value="form.intervaltype"
                   buttonStyle="solid"
                   @change="handleChangeIntervalType">
-                  <a-radio-button value="hourly" :disabled="handleVisibleInterval(0)">
+                  <a-radio-button value="hourly" :disabled="isIntervalDisabled('hourly')">
                     {{ $t('label.hourly') }}
                   </a-radio-button>
-                  <a-radio-button value="daily" :disabled="handleVisibleInterval(1)">
+                  <a-radio-button value="daily" :disabled="isIntervalDisabled('daily')">
                     {{ $t('label.daily') }}
                   </a-radio-button>
-                  <a-radio-button value="weekly" :disabled="handleVisibleInterval(2)">
+                  <a-radio-button value="weekly" :disabled="isIntervalDisabled('weekly')">
                     {{ $t('label.weekly') }}
                   </a-radio-button>
-                  <a-radio-button value="monthly" :disabled="handleVisibleInterval(3)">
+                  <a-radio-button value="monthly" :disabled="isIntervalDisabled('monthly')">
                     {{ $t('label.monthly') }}
                   </a-radio-button>
                 </a-radio-group>
@@ -60,6 +60,7 @@
                   :title="$t('label.minute.past.hour')">
                   <a-input-number
                     style="width: 100%"
+                    :disabled="isIntervalDisabled(form.intervaltype)"
                     v-model:value="form.time"
                     :min="1"
                     :max="59"
@@ -76,6 +77,7 @@
                 <a-time-picker
                   use12Hours
                   format="h:mm A"
+                  :disabled="isIntervalDisabled(form.intervaltype)"
                   v-model:value="form.timeSelect"
                   style="width: 100%;" />
               </a-form-item>
@@ -85,6 +87,7 @@
                 <a-select
                   v-model:value="form['day-of-week']"
                   showSearch
+                  :disabled="isIntervalDisabled(form.intervaltype)"
                   optionFilterProp="label"
                   :filterOption="(input, option) => {
                     return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
@@ -100,6 +103,7 @@
                 <a-select
                   v-model:value="form['day-of-month']"
                   showSearch
+                  :disabled="isIntervalDisabled(form.intervaltype)"
                   optionFilterProp="value"
                   :filterOption="(input, option) => {
                     return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0
@@ -311,6 +315,15 @@
     this.volumeId = this.resource.id
     this.fetchTimeZone()
   },
+  mounted () {
+    if (this.form.intervaltype && this.isIntervalDisabled(this.form.intervaltype)) {
+      const nextAvailable = this.getNextAvailableIntervalType(this.form.intervaltype)
+      if (nextAvailable) {
+        this.form.intervaltype = nextAvailable
+        this.handleChangeIntervalType()
+      }
+    }
+  },
   computed: {
     formattedAdditionalZoneMessage () {
       return `${this.$t('message.snapshot.additional.zones').replace('%x', this.resource.zonename)}`
@@ -319,6 +332,20 @@
       return isAdmin()
     }
   },
+  watch: {
+    dataSource: {
+      handler () {
+        if (this.form.intervaltype && this.getNextAvailableIntervalType && this.isIntervalDisabled(this.form.intervaltype)) {
+          const nextAvailable = this.getNextAvailableIntervalType(this.form.intervaltype)
+          if (nextAvailable) {
+            this.form.intervaltype = nextAvailable
+            this.handleChangeIntervalType()
+          }
+        }
+      },
+      deep: true
+    }
+  },
   methods: {
     initForm () {
       this.formRef = ref()
@@ -404,28 +431,46 @@
       }
     },
     handleChangeIntervalType () {
-      switch (this.form.intervaltype) {
+      if (this.form.intervaltype === 'weekly') {
+        this.fetchDayOfWeek()
+      } else if (this.form.intervaltype === 'monthly') {
+        this.fetchDayOfMonth()
+      }
+      this.intervalValue = this.getIntervalValue(this.formintervaltype)
+    },
+    getIntervalValue (intervalType) {
+      switch (intervalType) {
         case 'hourly':
-          this.intervalValue = 0
-          break
+          return 0
         case 'daily':
-          this.intervalValue = 1
-          break
+          return 1
         case 'weekly':
-          this.intervalValue = 2
-          this.fetchDayOfWeek()
-          break
+          return 2
         case 'monthly':
-          this.intervalValue = 3
-          this.fetchDayOfMonth()
-          break
+          return 3
       }
     },
-    handleVisibleInterval (intervalType) {
+    getNextAvailableIntervalType (currentIntervalType) {
+      const intervalTypes = ['hourly', 'daily', 'weekly', 'monthly']
+      const currentIndex = intervalTypes.indexOf(currentIntervalType)
+      const startIndex = currentIndex >= 0 ? currentIndex : -1
+
+      for (let i = 1; i <= intervalTypes.length; i++) {
+        const nextIndex = (startIndex + i) % intervalTypes.length
+        const nextIntervalType = intervalTypes[nextIndex]
+
+        if (!this.isIntervalDisabled(nextIntervalType)) {
+          return nextIntervalType
+        }
+      }
+      return null
+    },
+    isIntervalDisabled (intervalType) {
+      const intervalValue = this.getIntervalValue(intervalType)
       if (this.dataSource.length === 0) {
         return false
       }
-      const dataSource = this.dataSource.filter(item => item.intervaltype === intervalType)
+      const dataSource = this.dataSource.filter(item => item.intervaltype === intervalValue)
       if (dataSource && dataSource.length > 0) {
         return true
       }