From 1d26c481175890b09912703fbbce5c40f9d0d0de Mon Sep 17 00:00:00 2001 From: Marcelo Fukumoto Date: Wed, 27 May 2026 14:26:15 +0200 Subject: [PATCH] feat(forklift): Fixed some UI changes Signed-off-by: Marcelo Fukumoto --- .../vm-migration/ConfigureMappingsStep.vue | 243 ++++-------------- .../vm-migration/ConfigureProviderStep.vue | 10 +- .../components/vm-migration/MappingColumn.vue | 181 +++++++++++++ .../vm-migration/ReviewMigrationStep.vue | 2 +- .../components/vm-migration/SelectVmsStep.vue | 18 +- pkg/harvester/l10n/en-us.yaml | 3 +- .../models/forklift.konveyor.io.plan.js | 50 ++-- 7 files changed, 281 insertions(+), 226 deletions(-) create mode 100644 pkg/harvester/components/vm-migration/MappingColumn.vue diff --git a/pkg/harvester/components/vm-migration/ConfigureMappingsStep.vue b/pkg/harvester/components/vm-migration/ConfigureMappingsStep.vue index e2bbb3a1..4184f68d 100644 --- a/pkg/harvester/components/vm-migration/ConfigureMappingsStep.vue +++ b/pkg/harvester/components/vm-migration/ConfigureMappingsStep.vue @@ -2,11 +2,10 @@ import { ref, computed, watch } from 'vue'; import { useStore } from 'vuex'; import Loading from '@shell/components/Loading'; -import LabeledSelect from '@shell/components/form/LabeledSelect'; -import { RcItemCard } from '@components/RcItemCard'; import { STORAGE_CLASS, NETWORK_ATTACHMENT } from '@shell/config/types'; import { useI18n } from '@shell/composables/useI18n'; import { HCI } from '../../types'; +import MappingColumn from './MappingColumn.vue'; const props = defineProps({ providerName: { type: String, default: '' }, @@ -268,7 +267,7 @@ const formatStorageDetail = (entry) => { const buildNetworkMapSpec = (providerRef) => { return { - map: networkEntries.value.map((entry) => { + map: networkEntries.value.filter((entry) => !!entry.target).map((entry) => { if (entry.target === 'pod') { return { source: { name: entry.name, id: entry.id }, @@ -302,7 +301,7 @@ const buildNetworkMapSpec = (providerRef) => { const buildStorageMapSpec = (providerRef) => { return { - map: storageEntries.value.map((entry) => ({ + map: storageEntries.value.filter((entry) => !!entry.target).map((entry) => ({ source: { name: entry.name, id: entry.id }, destination: { storageClass: entry.target }, })), @@ -478,16 +477,23 @@ const init = async() => { } } - if (props.existingNetworkMap?.spec?.map) { - applyNetworkMapTargets(props.existingNetworkMap.spec.map); - } else { - applyDefaultNetworkMap(); + const hasExistingNetworkTargets = networkEntries.value.some((e) => !!e.target); + const hasExistingStorageTargets = storageEntries.value.some((e) => !!e.target); + + if (!hasExistingNetworkTargets) { + if (props.existingNetworkMap?.spec?.map) { + applyNetworkMapTargets(props.existingNetworkMap.spec.map); + } else { + applyDefaultNetworkMap(); + } } - if (props.existingStorageMap?.spec?.map) { - applyStorageMapTargets(props.existingStorageMap.spec.map); - } else { - applyDefaultStorageMap(); + if (!hasExistingStorageTargets) { + if (props.existingStorageMap?.spec?.map) { + applyStorageMapTargets(props.existingStorageMap.spec.map); + } else { + applyDefaultStorageMap(); + } } loading.value = false; @@ -502,114 +508,45 @@ init(); v-else class="configure-mappings" > -

+

{{ t('harvester.addons.vmMigration.configureMappings.description') }}

- -
-
-

- {{ t('harvester.addons.vmMigration.configureMappings.networkMapping.title') }} -

-

- {{ t('harvester.addons.vmMigration.configureMappings.networkMapping.description') }} -

-
+ + + - - - -
- - -
-
-

- {{ t('harvester.addons.vmMigration.configureMappings.storageMapping.title') }} -

-

- {{ t('harvester.addons.vmMigration.configureMappings.storageMapping.description') }} -

-
- - - - -
+ + +
diff --git a/pkg/harvester/components/vm-migration/ConfigureProviderStep.vue b/pkg/harvester/components/vm-migration/ConfigureProviderStep.vue index 5e5fc309..850f2cc1 100644 --- a/pkg/harvester/components/vm-migration/ConfigureProviderStep.vue +++ b/pkg/harvester/components/vm-migration/ConfigureProviderStep.vue @@ -518,7 +518,7 @@ defineExpose({ testConnection, clickTestButton }); @@ -531,7 +535,7 @@ init(); font-weight: 600; } - .text-muted { + .text-deemphasized { font-size: 13px; } } diff --git a/pkg/harvester/l10n/en-us.yaml b/pkg/harvester/l10n/en-us.yaml index b3ab03d8..9c15a809 100644 --- a/pkg/harvester/l10n/en-us.yaml +++ b/pkg/harvester/l10n/en-us.yaml @@ -1910,10 +1910,11 @@ harvester: description: Map VMware networks and datastores to Harvester and Longhorn target resources save: Save Mappings and Continue noTemplate: Start from scratch + removeMap: Remove Map networkMapping: title: Network Mapping description: Map VMware port groups to Harvester networks - placeholder: Choose a Harvester network... + placeholder: Choose a Harvester network template: Use existing network mapping as template storageMapping: title: Storage Mapping diff --git a/pkg/harvester/models/forklift.konveyor.io.plan.js b/pkg/harvester/models/forklift.konveyor.io.plan.js index c909abe8..c06a85d0 100644 --- a/pkg/harvester/models/forklift.konveyor.io.plan.js +++ b/pkg/harvester/models/forklift.konveyor.io.plan.js @@ -132,29 +132,29 @@ export default class ForkliftPlan extends HarvesterResource { } get _availableActions() { + const canStop = this.isMigrating && !this.planCanceled; + const canStart = !this.planSucceeded && (!this.isMigrating || this.planFailed || this.planCanceled || this.planCritical); + const out = []; + + if (canStart) { + out.push({ + action: 'startMigration', + enabled: true, + icon: 'icon icon-play', + label: this.isForkliftDashboard ? 'Restart' : 'Start', + }); + } + + if (canStop) { + out.push({ + action: 'stopMigration', + enabled: true, + icon: 'icon icon-pause', + label: 'Stop', + }); + } + if (this.isForkliftDashboard) { - const canStop = this.isMigrating && !this.planCanceled; - const canStart = !this.planSucceeded && (!this.isMigrating || this.planFailed || this.planCanceled || this.planCritical); - const out = []; - - if (canStart) { - out.push({ - action: 'startMigration', - enabled: true, - icon: 'icon icon-play', - label: 'Start', - }); - } - - if (canStop) { - out.push({ - action: 'stopMigration', - enabled: true, - icon: 'icon icon-pause', - label: 'Stop', - }); - } - out.push({ action: 'promptRemove', altAction: 'remove', @@ -167,9 +167,11 @@ export default class ForkliftPlan extends HarvesterResource { }); return out; - } + } else { + out.push(...super._availableActions); - return super._availableActions; + return out; + } } async stopMigration() {