mirror of
https://github.com/harvester/harvester-ui-extension.git
synced 2026-08-18 05:39:35 +00:00
fix: bugs in VM selection table
Signed-off-by: Andy Lee <andy.lee@suse.com>
This commit is contained in:
parent
facddcb9a7
commit
3817269c0a
@ -126,6 +126,10 @@ const applyStorageMapTargets = (mapSpec, { markOverridden = false, captureInheri
|
|||||||
if (match?.destination?.storageClass) {
|
if (match?.destination?.storageClass) {
|
||||||
entry.target = match.destination.storageClass;
|
entry.target = match.destination.storageClass;
|
||||||
|
|
||||||
|
if (captureInherited) {
|
||||||
|
entry.inheritedFromProvider = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (match.destination.volumeMode) {
|
if (match.destination.volumeMode) {
|
||||||
entry.volumeMode = match.destination.volumeMode;
|
entry.volumeMode = match.destination.volumeMode;
|
||||||
|
|
||||||
@ -252,18 +256,19 @@ const buildStorageEntries = () => {
|
|||||||
if (ds && ds.id) {
|
if (ds && ds.id) {
|
||||||
if (!datastoreMap[ds.id]) {
|
if (!datastoreMap[ds.id]) {
|
||||||
datastoreMap[ds.id] = {
|
datastoreMap[ds.id] = {
|
||||||
name: ds.name || t('harvester.addons.vmMigration.generic.unknown'),
|
name: ds.name || t('harvester.addons.vmMigration.generic.unknown'),
|
||||||
id: ds.id,
|
id: ds.id,
|
||||||
type: ds.type || '',
|
type: ds.type || '',
|
||||||
capacity: 0,
|
capacity: 0,
|
||||||
target: '',
|
target: '',
|
||||||
volumeMode: DEFAULT_VOLUME_MODE,
|
volumeMode: DEFAULT_VOLUME_MODE,
|
||||||
accessModes: [...DEFAULT_ACCESS_MODES],
|
accessModes: [...DEFAULT_ACCESS_MODES],
|
||||||
inheritedVolumeMode: DEFAULT_VOLUME_MODE,
|
inheritedVolumeMode: DEFAULT_VOLUME_MODE,
|
||||||
inheritedAccessModes: [...DEFAULT_ACCESS_MODES],
|
inheritedAccessModes: [...DEFAULT_ACCESS_MODES],
|
||||||
overridden: false,
|
inheritedFromProvider: false,
|
||||||
usedBy: [],
|
overridden: false,
|
||||||
_key: `stor-${ ds.id }`,
|
usedBy: [],
|
||||||
|
_key: `stor-${ ds.id }`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,18 +298,19 @@ const buildNetworkEntriesFromProvider = (networksData) => {
|
|||||||
|
|
||||||
const buildStorageEntriesFromProvider = (datastoresData) => {
|
const buildStorageEntriesFromProvider = (datastoresData) => {
|
||||||
storageEntries.value = (Array.isArray(datastoresData) ? datastoresData : []).map((ds) => ({
|
storageEntries.value = (Array.isArray(datastoresData) ? datastoresData : []).map((ds) => ({
|
||||||
name: ds.name || ds.id,
|
name: ds.name || ds.id,
|
||||||
id: ds.id || '',
|
id: ds.id || '',
|
||||||
type: ds.type || '',
|
type: ds.type || '',
|
||||||
capacity: ds.capacity || 0,
|
capacity: ds.capacity || 0,
|
||||||
target: '',
|
target: '',
|
||||||
volumeMode: DEFAULT_VOLUME_MODE,
|
volumeMode: DEFAULT_VOLUME_MODE,
|
||||||
accessModes: [...DEFAULT_ACCESS_MODES],
|
accessModes: [...DEFAULT_ACCESS_MODES],
|
||||||
inheritedVolumeMode: DEFAULT_VOLUME_MODE,
|
inheritedVolumeMode: DEFAULT_VOLUME_MODE,
|
||||||
inheritedAccessModes: [...DEFAULT_ACCESS_MODES],
|
inheritedAccessModes: [...DEFAULT_ACCESS_MODES],
|
||||||
overridden: false,
|
inheritedFromProvider: false,
|
||||||
usedBy: [],
|
overridden: false,
|
||||||
_key: `stor-${ ds.id || ds.name }`,
|
usedBy: [],
|
||||||
|
_key: `stor-${ ds.id || ds.name }`,
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -108,7 +108,7 @@ const formatModes = (entry) => {
|
|||||||
<div class="storage-defaults-info">
|
<div class="storage-defaults-info">
|
||||||
<span class="storage-defaults-summary">{{ formatModes(entry) }}</span>
|
<span class="storage-defaults-summary">{{ formatModes(entry) }}</span>
|
||||||
<span
|
<span
|
||||||
v-if="inheritedProviderName && !entry.overridden"
|
v-if="inheritedProviderName && entry.inheritedFromProvider && !entry.overridden"
|
||||||
class="text-deemphasized storage-defaults-inherited"
|
class="text-deemphasized storage-defaults-inherited"
|
||||||
>
|
>
|
||||||
{{ t('harvester.addons.vmMigration.storageDefaults.inherited', { provider: inheritedProviderName }) }}
|
{{ t('harvester.addons.vmMigration.storageDefaults.inherited', { provider: inheritedProviderName }) }}
|
||||||
|
|||||||
@ -25,8 +25,9 @@ const { discoveredVMs, selectedVMIds, tableRows } = toRefs(props.stepData);
|
|||||||
|
|
||||||
const selectedVMs = ref([]);
|
const selectedVMs = ref([]);
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
const networkMap = ref({});
|
// Restored from stepData so friendly names survive step navigation / remount.
|
||||||
const datastoreMap = ref({});
|
const networkMap = ref(props.stepData.networkMap || {});
|
||||||
|
const datastoreMap = ref(props.stepData.datastoreMap || {});
|
||||||
const sortableTableRef = ref(null);
|
const sortableTableRef = ref(null);
|
||||||
const allVMsSelected = ref(false);
|
const allVMsSelected = ref(false);
|
||||||
const errors = ref([]);
|
const errors = ref([]);
|
||||||
@ -240,12 +241,22 @@ const clearSelection = () => {
|
|||||||
|
|
||||||
if (table) {
|
if (table) {
|
||||||
table.clearSelection();
|
table.clearSelection();
|
||||||
|
|
||||||
|
if (typeof table.setPage === 'function') {
|
||||||
|
table.setPage(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Re-sorts the table so currently-selected VMs appear on the first pages.
|
const selectAllVMs = () => {
|
||||||
const showSelectedFirst = () => {
|
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) {
|
if (selectedVMIds.value.size === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -258,19 +269,33 @@ const showSelectedFirst = () => {
|
|||||||
h.name === 'vmName' ? { ...h, sort: ['selectedSort', 'vmName'] } : h
|
h.name === 'vmName' ? { ...h, sort: ['selectedSort', 'vmName'] } : h
|
||||||
));
|
));
|
||||||
|
|
||||||
|
skipNextSelectionEvent = true;
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
const table = sortableTableRef.value;
|
const table = sortableTableRef.value;
|
||||||
|
|
||||||
if (table) {
|
if (!table) {
|
||||||
table.page = 1;
|
skipNextSelectionEvent = false;
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const selectAllVMs = () => {
|
return;
|
||||||
allVMsSelected.value = true;
|
}
|
||||||
selectedVMIds.value = new Set(discoveredVMs.value.map((vm) => vm.id));
|
|
||||||
selectedVMs.value = discoveredVMs.value.slice();
|
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(
|
watch(
|
||||||
@ -342,6 +367,9 @@ const fetchVMs = async() => {
|
|||||||
return map;
|
return map;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
|
props.stepData.networkMap = networkMap.value;
|
||||||
|
props.stepData.datastoreMap = datastoreMap.value;
|
||||||
|
|
||||||
lastFetchedAt.value = Date.now();
|
lastFetchedAt.value = Date.now();
|
||||||
tableRows.value = buildTableRows();
|
tableRows.value = buildTableRows();
|
||||||
};
|
};
|
||||||
@ -398,6 +426,10 @@ const init = async() => {
|
|||||||
tableRows.value = buildTableRows();
|
tableRows.value = buildTableRows();
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
|
|
||||||
|
// Returning to the step with an existing selection: bring selected VMs forward and re-check them.
|
||||||
|
await nextTick();
|
||||||
|
sortSelectedToFront();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,7 +497,6 @@ init();
|
|||||||
:row-actions="false"
|
:row-actions="false"
|
||||||
:groupable="false"
|
:groupable="false"
|
||||||
:paging="true"
|
:paging="true"
|
||||||
:rows-per-page="20"
|
|
||||||
key-field="_key"
|
key-field="_key"
|
||||||
@selection="onSelect"
|
@selection="onSelect"
|
||||||
>
|
>
|
||||||
@ -475,13 +506,9 @@ init();
|
|||||||
{{ t('harvester.addons.vmMigration.selectVms.availableVms') }}
|
{{ t('harvester.addons.vmMigration.selectVms.availableVms') }}
|
||||||
</h3>
|
</h3>
|
||||||
<span class="selected-actions">
|
<span class="selected-actions">
|
||||||
<a
|
<span class="text-deemphasized">
|
||||||
role="button"
|
|
||||||
:class="{ disabled: selectedCount === 0 }"
|
|
||||||
@click.prevent="showSelectedFirst"
|
|
||||||
>
|
|
||||||
{{ selectedCount }} {{ t('harvester.addons.vmMigration.selectVms.selected') }}
|
{{ selectedCount }} {{ t('harvester.addons.vmMigration.selectVms.selected') }}
|
||||||
</a>
|
</span>
|
||||||
<template v-if="selectedCount > 0">
|
<template v-if="selectedCount > 0">
|
||||||
<span class="text-deemphasized">|</span>
|
<span class="text-deemphasized">|</span>
|
||||||
<a
|
<a
|
||||||
|
|||||||
@ -136,6 +136,7 @@ const cancel = () => {
|
|||||||
|
|
||||||
.storage-defaults-card {
|
.storage-defaults-card {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.description {
|
.description {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user