feat: add banner

Signed-off-by: Andy Lee <andy.lee@suse.com>
This commit is contained in:
Andy Lee 2025-10-26 14:27:49 +08:00
parent 9a08582f51
commit e14f403075
No known key found for this signature in database
GPG Key ID: EC774C32160918ED
5 changed files with 96 additions and 26 deletions

View File

@ -2,14 +2,12 @@
import LabelValue from '@shell/components/LabelValue';
import CreateEditView from '@shell/mixins/create-edit-view';
import ResourceTabs from '@shell/components/form/ResourceTabs';
import DetailText from '@shell/components/DetailText';
import Tab from '@shell/components/Tabbed/Tab';
export default {
components: {
ResourceTabs,
DetailText,
Tab,
LabelValue
},
@ -26,15 +24,12 @@ export default {
},
data() {
console.log('this.value.status', this.value.status);
const { profileStatus } = this.value.status;
console.log("🚀 ~ profileStatus:", profileStatus)
return {
profileStatus : profileStatus || []
};
return { profileStatus: profileStatus || [] };
},
methods:{
methods: {
vGPUIDList(profile) {
return profile.vGPUID?.join(', ') || '';
}
@ -66,7 +61,7 @@ export default {
class="mb-20"
/>
</div>
<div class="col span-3">
<div class="col span-3">
<LabelValue
:name="t('harvester.migconfiguration.available')"
:value="profile.available"

View File

@ -10,8 +10,6 @@ import CreateEditView from '@shell/mixins/create-edit-view';
export default {
name: 'HarvesterEditMIGConfiguration',
// emits: ['update:value'],
components: {
Tab,
Tabbed,
@ -66,12 +64,12 @@ export default {
updateRequested(neu, profile) {
if (neu === null || neu === '') return;
const newValue = Number(neu);
const availableCount = this.available(profile);
const maxValue = Math.max(this.available(profile), profile.requested)
if (newValue < 0) {
profile.requested = 0;
} else if (newValue > maxValue) {
profile.requested = maxValue;
} else if ( newValue > availableCount ) {
profile.requested = availableCount;
} else {
profile.requested = newValue;
}
@ -117,7 +115,6 @@ export default {
<LabeledInput
v-model:value="profile.requested"
:min="0"
:max="available(profile)"
type="number"
class="mb-20"
:label="`${t('harvester.migconfiguration.requested')} (available : ${available(profile)})`"

View File

@ -1674,6 +1674,10 @@ harvester:
available: Available
total: Total
vGPUID: vGPU ID
goSriovGPU:
prefix: Please enable the supported GPU devices in
middle: SR-IOV GPU Devices
suffix: page to manage the vGPU MIG configurations.
vgpu:
label: vGPU Devices

View File

@ -1,10 +1,12 @@
<script>
import { STATE, NAME} from '@shell/config/table-headers';
import { STATE, NAME } from '@shell/config/table-headers';
import { allHash } from '@shell/utils/promise';
import Banner from '@components/Banner/Banner.vue';
import Loading from '@shell/components/Loading';
import ResourceTable from '@shell/components/ResourceTable';
import { HCI } from '../types';
import { ADD_ONS } from '../config/harvester-map';
import MessageLink from '@shell/components/MessageLink';
export default {
name: 'ListMIGConfigurations',
@ -15,28 +17,46 @@ export default {
Banner,
Loading,
ResourceTable,
MessageLink,
},
async fetch() {
const inStore = this.$store.getters['currentProduct'].inStore;
this.schema = this.$store.getters[`${ inStore }/schemaFor`](HCI.MIG_CONFIGURATION);
this.hasAddonSchema = this.$store.getters[`${ inStore }/schemaFor`](HCI.ADD_ONS);
if (this.hasSchema) {
try {
const hash = await allHash({ migconfigs: this.$store.dispatch(`${ inStore }/findAll`, { type: HCI.MIG_CONFIGURATION }) });
const hash = await allHash({
migconfigs: this.$store.dispatch(`${ inStore }/findAll`, { type: HCI.MIG_CONFIGURATION }),
vGpuDevices: this.$store.dispatch(`${ inStore }/findAll`, { type: HCI.VGPU_DEVICE }),
addons: this.$store.dispatch(`${ inStore }/findAll`, { type: HCI.ADD_ONS })
});
this.hasPCIAddon = hash.addons.find((addon) => addon.name === ADD_ONS.PCI_DEVICE_CONTROLLER)?.spec?.enabled === true;
this.hasSriovgpuAddon = hash.addons.find((addon) => addon.name === ADD_ONS.NVIDIA_DRIVER_TOOLKIT_CONTROLLER)?.spec?.enabled === true;
this.hasSRIOVGPUSchema = !!this.$store.getters[`${ inStore }/schemaFor`](HCI.SR_IOVGPU_DEVICE);
if (this.hasSRIOVGPUSchema) {
await this.$store.dispatch(`${ inStore }/findAll`, { type: HCI.SR_IOVGPU_DEVICE });
}
this.rows = hash.migconfigs;
} catch (e) {}
}
},
data() {
// const inStore = this.$store.getters['currentProduct'].inStore;
return {
rows: [],
schema: null,
rows: [],
schema: null,
hasAddonSchema: false,
hasPCIAddon: false,
hasSriovgpuAddon: false,
hasSRIOVGPUSchema: false,
toVGpuAddon: `${ HCI.ADD_ONS }/harvester-system/${ ADD_ONS.NVIDIA_DRIVER_TOOLKIT_CONTROLLER }?mode=edit`,
toPciAddon: `${ HCI.ADD_ONS }/harvester-system/${ ADD_ONS.PCI_DEVICE_CONTROLLER }?mode=edit`,
SRIOVGPUPage: `${ HCI.ADD_ONS }/harvester-system/${ ADD_ONS.NVIDIA_DRIVER_TOOLKIT_CONTROLLER }?mode=edit`,
};
},
@ -52,6 +72,17 @@ export default {
return rows;
},
sriovGPUPage() {
return {
name: 'harvester-c-cluster-resource',
params: { cluster: this.$store.getters['clusterId'], resource: HCI.SR_IOVGPU_DEVICE },
};
},
showEnableSRIOVGPUMessage() {
return this.rowsData.length === 0;
},
headers() {
const cols = [
STATE,
@ -87,9 +118,50 @@ export default {
<template>
<Loading v-if="$fetchState.pending" />
<div v-else-if="!hasAddonSchema">
<Banner color="warning">
{{ t('harvester.vgpu.noPermission') }}
</Banner>
</div>
<div v-else-if="!hasSriovgpuAddon || !hasPCIAddon">
<Banner
v-if="!hasSriovgpuAddon"
color="warning"
>
<MessageLink
:to="toVGpuAddon"
prefix-label="harvester.vgpu.goSetting.prefix"
middle-label="harvester.vgpu.goSetting.middle"
suffix-label="harvester.vgpu.goSetting.suffix"
/>
</Banner>
<Banner
v-if="!hasPCIAddon"
color="warning"
>
<MessageLink
:to="toPciAddon"
prefix-label="harvester.pci.goSetting.prefix"
middle-label="harvester.pci.goSetting.middle"
suffix-label="harvester.pci.goSetting.suffix"
/>
</Banner>
</div>
<div v-else-if="hasSchema">
<Banner
color="info"
v-if="showEnableSRIOVGPUMessage"
color="warning"
>
<MessageLink
:to="sriovGPUPage"
prefix-label="harvester.migconfiguration.goSriovGPU.prefix"
middle-label="harvester.migconfiguration.goSriovGPU.middle"
suffix-label="harvester.migconfiguration.goSriovGPU.suffix"
/>
</Banner>
<Banner
v-if="!showEnableSRIOVGPUMessage"
color="warning"
:label="t('harvester.migconfiguration.infoBanner')"
/>
<ResourceTable

View File

@ -1,9 +1,6 @@
import SteveModel from '@shell/plugins/steve/steve-class';
import { escapeHtml } from '@shell/utils/string';
import { colorForState } from '@shell/plugins/dashboard-store/resource-class';
// import { NODE } from '@shell/config/types';
// import { HCI as HCI_ANNOTATIONS } from '@pkg/harvester/config/labels-annotations';
// import { HCI } from '../types';
/**
* Class representing vGPU MIGConfiguration resource.
@ -17,7 +14,8 @@ export default class MIGCONFIGURATION extends SteveModel {
if (action.action === 'goToEditYaml') {
return { ...action, enabled: true };
} else if (action.action === 'goToEdit') {
return { ...action, enabled: !this.spec.enabled };
// need to wait for status to be disabled, then allow user to editConfig
return { ...action, enabled: !this.spec.enabled && this.configStatus === 'disabled' };
} else {
return action;
}
@ -49,6 +47,10 @@ export default class MIGCONFIGURATION extends SteveModel {
return false;
}
get configStatus() {
return this.status.status;
}
get actualState() {
return this.isEnabled ? 'Enabled' : 'Disabled';
}