fix: bugs in VM selection table

Signed-off-by: Andy Lee <andy.lee@suse.com>
This commit is contained in:
Andy Lee 2026-07-31 14:25:18 +08:00
parent facddcb9a7
commit 3817269c0a
No known key found for this signature in database
GPG Key ID: 39DC4436AE3564D5
4 changed files with 79 additions and 45 deletions

View File

@ -126,6 +126,10 @@ const applyStorageMapTargets = (mapSpec, { markOverridden = false, captureInheri
if (match?.destination?.storageClass) {
entry.target = match.destination.storageClass;
if (captureInherited) {
entry.inheritedFromProvider = true;
}
if (match.destination.volumeMode) {
entry.volumeMode = match.destination.volumeMode;
@ -261,6 +265,7 @@ const buildStorageEntries = () => {
accessModes: [...DEFAULT_ACCESS_MODES],
inheritedVolumeMode: DEFAULT_VOLUME_MODE,
inheritedAccessModes: [...DEFAULT_ACCESS_MODES],
inheritedFromProvider: false,
overridden: false,
usedBy: [],
_key: `stor-${ ds.id }`,
@ -302,6 +307,7 @@ const buildStorageEntriesFromProvider = (datastoresData) => {
accessModes: [...DEFAULT_ACCESS_MODES],
inheritedVolumeMode: DEFAULT_VOLUME_MODE,
inheritedAccessModes: [...DEFAULT_ACCESS_MODES],
inheritedFromProvider: false,
overridden: false,
usedBy: [],
_key: `stor-${ ds.id || ds.name }`,

View File

@ -108,7 +108,7 @@ const formatModes = (entry) => {
<div class="storage-defaults-info">
<span class="storage-defaults-summary">{{ formatModes(entry) }}</span>
<span
v-if="inheritedProviderName && !entry.overridden"
v-if="inheritedProviderName && entry.inheritedFromProvider && !entry.overridden"
class="text-deemphasized storage-defaults-inherited"
>
{{ t('harvester.addons.vmMigration.storageDefaults.inherited', { provider: inheritedProviderName }) }}

View File

@ -25,8 +25,9 @@ const { discoveredVMs, selectedVMIds, tableRows } = toRefs(props.stepData);
const selectedVMs = ref([]);
const loading = ref(true);
const networkMap = ref({});
const datastoreMap = ref({});
// Restored from stepData so friendly names survive step navigation / remount.
const networkMap = ref(props.stepData.networkMap || {});
const datastoreMap = ref(props.stepData.datastoreMap || {});
const sortableTableRef = ref(null);
const allVMsSelected = ref(false);
const errors = ref([]);
@ -240,12 +241,22 @@ const clearSelection = () => {
if (table) {
table.clearSelection();
if (typeof table.setPage === 'function') {
table.setPage(1);
}
}
});
};
// Re-sorts the table so currently-selected VMs appear on the first pages.
const showSelectedFirst = () => {
const selectAllVMs = () => {
allVMsSelected.value = true;
selectedVMIds.value = new Set(discoveredVMs.value.map((vm) => vm.id));
selectedVMs.value = discoveredVMs.value.slice();
};
// Moves currently-selected VMs to the first page(s) and re-checks them.
const sortSelectedToFront = () => {
if (selectedVMIds.value.size === 0) {
return;
}
@ -258,19 +269,33 @@ const showSelectedFirst = () => {
h.name === 'vmName' ? { ...h, sort: ['selectedSort', 'vmName'] } : h
));
skipNextSelectionEvent = true;
nextTick(() => {
const table = sortableTableRef.value;
if (table) {
table.page = 1;
}
});
};
if (!table) {
skipNextSelectionEvent = false;
const selectAllVMs = () => {
allVMsSelected.value = true;
selectedVMIds.value = new Set(discoveredVMs.value.map((vm) => vm.id));
selectedVMs.value = discoveredVMs.value.slice();
return;
}
if (typeof table.changeSort === 'function') {
table.changeSort('vmName', false);
} else if (typeof table.setPage === 'function') {
table.setPage(1);
}
nextTick(() => {
const rowsToReselect = (table.pagedRows || []).filter((row) => selectedVMIds.value.has(row._original?.id));
if (rowsToReselect.length > 0) {
table.update(rowsToReselect, []);
}
skipNextSelectionEvent = false;
});
});
};
watch(
@ -342,6 +367,9 @@ const fetchVMs = async() => {
return map;
}, {});
props.stepData.networkMap = networkMap.value;
props.stepData.datastoreMap = datastoreMap.value;
lastFetchedAt.value = Date.now();
tableRows.value = buildTableRows();
};
@ -398,6 +426,10 @@ const init = async() => {
tableRows.value = buildTableRows();
loading.value = false;
// Returning to the step with an existing selection: bring selected VMs forward and re-check them.
await nextTick();
sortSelectedToFront();
return;
}
@ -465,7 +497,6 @@ init();
:row-actions="false"
:groupable="false"
:paging="true"
:rows-per-page="20"
key-field="_key"
@selection="onSelect"
>
@ -475,13 +506,9 @@ init();
{{ t('harvester.addons.vmMigration.selectVms.availableVms') }}
</h3>
<span class="selected-actions">
<a
role="button"
:class="{ disabled: selectedCount === 0 }"
@click.prevent="showSelectedFirst"
>
<span class="text-deemphasized">
{{ selectedCount }} {{ t('harvester.addons.vmMigration.selectVms.selected') }}
</a>
</span>
<template v-if="selectedCount > 0">
<span class="text-deemphasized">|</span>
<a

View File

@ -136,6 +136,7 @@ const cancel = () => {
.storage-defaults-card {
margin: 0;
padding: 20px;
}
.description {