mirror of
https://github.com/harvester/harvester-ui-extension.git
synced 2025-12-14 21:51:43 +00:00
176 lines
4.4 KiB
Vue
176 lines
4.4 KiB
Vue
<script>
|
|
|
|
import KeyValue from '@shell/components/form/KeyValue';
|
|
import LabeledSelect from '@shell/components/form/LabeledSelect';
|
|
|
|
import { allHash } from '@shell/utils/promise';
|
|
import { clone } from '@shell/utils/object';
|
|
import { HCI } from '../../../types';
|
|
import { NODE } from '@shell/config/types';
|
|
import { LVM_TOPOLOGY_LABEL } from '../index.vue';
|
|
|
|
const DEFAULT_PARAMETERS = [
|
|
'type',
|
|
'vgName'
|
|
];
|
|
|
|
const DEFAULT_TOPOLOGIES = [{
|
|
matchLabelExpressions: [{
|
|
key: LVM_TOPOLOGY_LABEL,
|
|
values: []
|
|
}]
|
|
}];
|
|
|
|
export default {
|
|
components: {
|
|
KeyValue,
|
|
LabeledSelect,
|
|
},
|
|
|
|
props: {
|
|
value: {
|
|
type: Object,
|
|
required: true
|
|
},
|
|
mode: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
realMode: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
},
|
|
|
|
async fetch() {
|
|
const inStore = this.$store.getters['currentProduct'].inStore;
|
|
|
|
await allHash({
|
|
nodes: this.$store.dispatch(`${ inStore }/findAll`, { type: NODE }),
|
|
lvmVolumeGroups: this.$store.dispatch(`${ inStore }/findAll`, { type: HCI.LVM_VOLUME_GROUP }),
|
|
});
|
|
},
|
|
|
|
data() {
|
|
const node = (this.value.allowedTopologies?.[0]?.matchLabelExpressions || []).find((t) => t.key === LVM_TOPOLOGY_LABEL)?.values[0];
|
|
|
|
return {
|
|
volumeGroupTypes: ['striped', 'dm-thin'],
|
|
node,
|
|
};
|
|
},
|
|
|
|
watch: {
|
|
node(value) {
|
|
delete (this.value.parameters.vgName);
|
|
|
|
const allowedTopologies = [...DEFAULT_TOPOLOGIES];
|
|
|
|
allowedTopologies[0].matchLabelExpressions[0].values = [value];
|
|
|
|
this.value.allowedTopologies = allowedTopologies;
|
|
}
|
|
},
|
|
|
|
computed: {
|
|
nodes() {
|
|
const inStore = this.$store.getters['currentProduct'].inStore;
|
|
const nodes = this.$store.getters[`${ inStore }/all`](NODE) || [];
|
|
|
|
return nodes.filter((n) => n.labels[LVM_TOPOLOGY_LABEL] === n.name).map((n) => n.name);
|
|
},
|
|
|
|
volumeGroups() {
|
|
const inStore = this.$store.getters['currentProduct'].inStore;
|
|
const lvmVolumeGroups = this.$store.getters[`${ inStore }/all`](HCI.LVM_VOLUME_GROUP) || [];
|
|
|
|
return lvmVolumeGroups
|
|
.filter((group) => group.spec.nodeName === this.node)
|
|
.map((g) => g.spec.vgName);
|
|
},
|
|
|
|
parameters: {
|
|
get() {
|
|
const parameters = clone(this.value?.parameters) || {};
|
|
|
|
DEFAULT_PARAMETERS.map((key) => {
|
|
delete parameters[key];
|
|
});
|
|
|
|
return parameters;
|
|
},
|
|
|
|
set(value) {
|
|
Object.assign(this.value.parameters, value);
|
|
}
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
<template>
|
|
<div>
|
|
<div class="row mt-10">
|
|
<div class="col span-6">
|
|
<LabeledSelect
|
|
v-model:value="node"
|
|
:label="t('harvester.storage.parameters.node.label')"
|
|
:options="nodes"
|
|
:mode="mode"
|
|
:required="true"
|
|
>
|
|
<template #no-options="{ searching }">
|
|
<span
|
|
v-if="!searching"
|
|
class="text-muted"
|
|
>
|
|
{{ t('harvester.storage.parameters.diskSelector.no-options', null, true) }}
|
|
</span>
|
|
</template>
|
|
</LabeledSelect>
|
|
</div>
|
|
</div>
|
|
<div class="row mt-10">
|
|
<div class="col span-6">
|
|
<LabeledSelect
|
|
v-model:value="value.parameters.vgName"
|
|
:label="t('harvester.storage.parameters.lvmVolumeGroup.label')"
|
|
:options="volumeGroups"
|
|
:mode="mode"
|
|
:required="true"
|
|
>
|
|
<template #no-options="{ searching }">
|
|
<span
|
|
v-if="!searching"
|
|
class="text-muted"
|
|
>
|
|
{{ t('harvester.storage.parameters.lvmVolumeGroup.no-options', null, true) }}
|
|
</span>
|
|
</template>
|
|
</LabeledSelect>
|
|
</div>
|
|
<div class="col span-6">
|
|
<LabeledSelect
|
|
v-model:value="value.parameters.type"
|
|
:label="t('harvester.storage.parameters.lvmVolumeGroupType.label')"
|
|
:options="volumeGroupTypes"
|
|
:mode="mode"
|
|
:required="true"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<KeyValue
|
|
v-model:value="parameters"
|
|
:add-label="t('storageClass.longhorn.addLabel')"
|
|
:read-allowed="false"
|
|
:mode="mode"
|
|
class="mt-10"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
.labeled-input.compact-input {
|
|
padding: 7px 10px;
|
|
}
|
|
</style>
|