mirror of https://github.com/rancher/dashboard.git
172 lines
4.3 KiB
Vue
172 lines
4.3 KiB
Vue
<script>
|
|
import { clone, set } from '@shell/utils/object';
|
|
import { _VIEW } from '@shell/config/query-params';
|
|
|
|
import Mount from '@shell/edit/workload/storage/Mount';
|
|
import ButtonDropdown from '@shell/components/ButtonDropdown';
|
|
import ArrayListGrouped from '@shell/components/form/ArrayListGrouped';
|
|
|
|
export default {
|
|
name: 'ContainerMountPaths',
|
|
|
|
emits: ['update:container'],
|
|
|
|
components: {
|
|
ArrayListGrouped, ButtonDropdown, Mount
|
|
},
|
|
|
|
props: {
|
|
mode: {
|
|
type: String,
|
|
default: 'create',
|
|
},
|
|
|
|
// pod spec
|
|
value: {
|
|
type: Object,
|
|
default: () => {
|
|
return {};
|
|
},
|
|
},
|
|
|
|
container: {
|
|
type: Object,
|
|
default: () => {
|
|
return {};
|
|
},
|
|
},
|
|
},
|
|
|
|
data() {
|
|
// set volumeMount field
|
|
this.initializeStorage();
|
|
|
|
return { selectedContainerVolumes: this.getSelectedContainerVolumes() };
|
|
},
|
|
|
|
computed: {
|
|
isView() {
|
|
return this.mode === _VIEW;
|
|
},
|
|
|
|
availableVolumeOptions() {
|
|
const containerVolumes = (this.container?.volumeMounts || []).map((item) => item.name);
|
|
|
|
return (this.value?.volumes || []).filter((vol) => !containerVolumes.includes(vol.name)).map((item) => {
|
|
return {
|
|
label: `${ item.name } (${ this.headerFor(item) })`,
|
|
action: this.selectVolume,
|
|
value: item.name
|
|
};
|
|
});
|
|
},
|
|
},
|
|
|
|
watch: {
|
|
selectedContainerVolumes: {
|
|
deep: true,
|
|
handler(neu, old) {
|
|
const names = neu.map((item) => item.name);
|
|
|
|
this.container.volumeMounts = this.container.volumeMounts.filter((mount) => names.includes(mount.name));
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
methods: {
|
|
/**
|
|
* Initialize missing values for the container
|
|
*/
|
|
initializeStorage() {
|
|
if (!this.container.volumeMounts) {
|
|
set(this.container, 'volumeMounts', []);
|
|
this.$emit('update:container', this.container);
|
|
}
|
|
},
|
|
|
|
getSelectedContainerVolumes() {
|
|
// Extract volume mounts to map storage volumes
|
|
const { volumeMounts = [] } = this.container;
|
|
const names = volumeMounts.map(({ name }) => name);
|
|
|
|
// Extract storage volumes to allow mutation, if matches mount map
|
|
return clone((this.value?.volumes || []).filter((volume) => names.includes(volume.name)));
|
|
},
|
|
|
|
/**
|
|
* Remove all mounts for given storage volume
|
|
*/
|
|
removeVolume(volume) {
|
|
const removeName = volume.row.value.name;
|
|
|
|
this.selectedContainerVolumes = this.selectedContainerVolumes.filter(({ name }) => name !== removeName);
|
|
},
|
|
|
|
selectVolume(event) {
|
|
const selectedVolume = (this.value?.volumes || []).find((vol) => vol.name === event.value);
|
|
|
|
this.selectedContainerVolumes.push(selectedVolume);
|
|
|
|
const { name } = selectedVolume;
|
|
|
|
this.container.volumeMounts.push(name);
|
|
this.$emit('update:container', this.container);
|
|
},
|
|
|
|
headerFor(value) {
|
|
const type = Object.keys(value).filter(
|
|
(key) => typeof value[key] === 'object'
|
|
)[0];
|
|
|
|
if (
|
|
this.$store.getters['i18n/exists'](`workload.storage.subtypes.${ type }`)
|
|
) {
|
|
return this.t(`workload.storage.subtypes.${ type }`);
|
|
} else {
|
|
return type;
|
|
}
|
|
},
|
|
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<!-- Storage Volumes -->
|
|
<ArrayListGrouped
|
|
:key="selectedContainerVolumes.length"
|
|
v-model:value="selectedContainerVolumes"
|
|
:add-allowed="false"
|
|
:mode="mode"
|
|
data-testid="container-storage-array-list"
|
|
@remove="removeVolume"
|
|
>
|
|
<!-- Custom/default storage volume form -->
|
|
<template #default="props">
|
|
<h3>{{ props.row.value.name }} ({{ headerFor(props.row.value) }})</h3>
|
|
<Mount
|
|
:container="container"
|
|
:name="props.row.value.name"
|
|
:mode="mode"
|
|
:data-testid="`container-storage-mount-${props.i}`"
|
|
/>
|
|
</template>
|
|
</ArrayListGrouped>
|
|
<ButtonDropdown
|
|
v-if="!isView"
|
|
id="add-volume"
|
|
:button-label="t('workload.storage.selectVolume')"
|
|
:dropdown-options="availableVolumeOptions"
|
|
size="sm"
|
|
data-testid="container-storage-add-button"
|
|
@click-action="e=>selectVolume(e)"
|
|
>
|
|
<template #no-options>
|
|
{{ t('workload.storage.noVolumes') }}
|
|
</template>
|
|
</ButtonDropdown>
|
|
</div>
|
|
</template>
|