Update pankow which now has Dropdown replaced with SingleSelect

This commit is contained in:
Johannes Zellner
2025-04-02 15:02:31 +02:00
parent 5527926508
commit 2104df5a83
15 changed files with 78 additions and 75 deletions
+3 -3
View File
@@ -5,7 +5,7 @@ const i18n = useI18n();
const t = i18n.t;
import { ref, onMounted, useTemplateRef } from 'vue';
import { Button, ButtonGroup, InputGroup, FormGroup, TextInput, Dropdown, TableView, InputDialog, Dialog } from 'pankow';
import { Button, ButtonGroup, InputGroup, FormGroup, TextInput, SingleSelect, TableView, InputDialog, Dialog } from 'pankow';
import { prettyLongDate } from 'pankow/utils';
import { API_ORIGIN, SECRET_PLACEHOLDER } from '../constants.js';
import Section from '../components/Section.vue';
@@ -263,7 +263,7 @@ onMounted(async () => {
<label for="locationInput">{{ $t('app.cloneDialog.location') }}</label>
<InputGroup>
<TextInput id="locationInput" ref="locationInput" v-model="restoreLocation" style="flex-grow: 1;" />
<Dropdown v-model="restoreDomain" :options="domains" option-label="domain" option-key="domain" />
<SingleSelect v-model="restoreDomain" :options="domains" option-label="domain" option-key="domain" />
</InputGroup>
</FormGroup>
@@ -272,7 +272,7 @@ onMounted(async () => {
<small>{{ domain.description }}</small>
<InputGroup>
<TextInput :id="'secondaryDomainInput-' + key" v-model="domain.subdomain" :placeholder="$t('appstore.installDialog.locationPlaceholder')" style="flex-grow: 1;" />
<Dropdown v-model="domain.domain" :options="domains" option-label="domain" option-key="domain" />
<SingleSelect v-model="domain.domain" :options="domains" option-label="domain" option-key="domain" />
</InputGroup>
</FormGroup>
+13 -7
View File
@@ -2,7 +2,7 @@
import { ref, computed, useTemplateRef, onMounted } from 'vue';
import { marked } from 'marked';
import { Button, Dialog, Dropdown, FormGroup, TextInput, InputGroup } from 'pankow';
import { Button, Dialog, SingleSelect, FormGroup, TextInput, InputGroup } from 'pankow';
import { prettyDate, prettyFileSize } from 'pankow/utils';
import AccessControl from './AccessControl.vue';
import PortBindings from './PortBindings.vue';
@@ -53,19 +53,25 @@ function setStep(newStep) {
const location = ref('');
const accessRestrictionOption = ref(ACL_OPTIONS.ANY);
const accessRestrictionAcl = ref({ users: [], groups: [] });
const domain = ref({});
const domain = ref('');
const domainProvider = ref('');
const tcpPorts = ref({});
const udpPorts = ref({});
const secondaryDomains = ref({});
const upstreamUri = ref('');
function onDomainChange() {
const tmp = domains.value.find(d => d.domain === domain.value);
domainProvider.value = tmp ? tmp.provider : '';
}
async function submit() {
formError.value = {};
busy.value = true;
const config = {
subdomain: location.value,
domain: domain.value.domain,
domain: domain.value,
accessRestriction: accessRestrictionOption.value === ACL_OPTIONS.ANY ? null : (accessRestrictionOption.value === ACL_OPTIONS.NOSSO ? null : accessRestrictionAcl.value)
};
@@ -127,7 +133,7 @@ onMounted(async () => {
if (error) return console.error(error);
// preselect with dashboard domain
domain.value = domains.value.find(d => d.domain === result.adminDomain) || domains.value[0];
domain.value = (domains.value.find(d => d.domain === result.adminDomain) || domains.value[0]).domain;
});
defineExpose({
@@ -193,19 +199,19 @@ defineExpose({
<label for="location">{{ $t('appstore.installDialog.location') }}</label>
<InputGroup>
<TextInput id="location" ref="locationInput" v-model="location" style="flex-grow: 1"/>
<Dropdown v-model="domain" :options="domains" option-label="domain" />
<SingleSelect v-model="domain" :options="domains" option-label="domain" option-key="domain" @select="onDomainChange()"/>
</InputGroup>
<div class="text-danger" v-if="formError.location">{{ formError.location }}</div>
</FormGroup>
<p class="text-small text-warning" v-show="domain.provider === 'noop' || domain.provider === 'manual'" v-html="$t('appstore.installDialog.manualWarning', { location: ((location ? location + '.' : '') + domain.domain) })"></p>
<p class="text-small text-warning" v-show="domainProvider === 'noop' || domainProvider === 'manual'" v-html="$t('appstore.installDialog.manualWarning', { location: ((location ? location + '.' : '') + domain) })"></p>
<FormGroup v-for="(port, key) in secondaryDomains" :key="key">
<label :for="'secondaryDomainInput' + key">{{ port.title }}</label>
<small>{{ port.description }}</small>
<InputGroup>
<TextInput :id="'secondaryDomainInput' + key" v-model="port.value" :placeholder="$t('appstore.installDialog.locationPlaceholder')" style="flex-grow: 1"/>
<Dropdown v-model="port.domain" :options="domains" option-label="domain" option-key="domain" />
<SingleSelect v-model="port.domain" :options="domains" option-label="domain" option-key="domain" />
</InputGroup>
</FormGroup>
+2 -2
View File
@@ -6,7 +6,7 @@ const t = i18n.t;
import moment from 'moment-timezone';
import { ref, onMounted, useTemplateRef, computed } from 'vue';
import { Button, Dialog, Dropdown, FormGroup, TextInput, TableView, InputDialog } from 'pankow';
import { Button, Dialog, SingleSelect, FormGroup, TextInput, TableView, InputDialog } from 'pankow';
import { prettyLongDate, copyToClipboard } from 'pankow/utils';
import Section from './Section.vue';
import AppPasswordsModel from '../models/AppPasswordsModel.js';
@@ -173,7 +173,7 @@ onMounted(async () => {
<FormGroup>
<label>{{ $t('profile.createAppPassword.app') }}</label>
<Dropdown outline v-model="identifier" :options="identifiers" option-label="label" option-key="id" /> {{ dropdownValueWithKey }}
<SingleSelect outline v-model="identifier" :options="identifiers" option-label="label" option-key="id" />
</FormGroup>
</form>
</div>
+14 -14
View File
@@ -1,7 +1,7 @@
<script setup>
import { ref, useTemplateRef, onMounted, computed, watch } from 'vue';
import { Button, InputGroup, Dialog, Dropdown, FormGroup, TextInput, Checkbox, PasswordInput, NumberInput } from 'pankow';
import { Button, InputGroup, Dialog, SingleSelect, FormGroup, TextInput, Checkbox, PasswordInput, NumberInput } from 'pankow';
import { prettyBinarySize } from 'pankow/utils';
import { BACKUP_FORMATS, STORAGE_PROVIDERS, REGIONS_CONTABO, REGIONS_VULTR, REGIONS_UPCLOUD, REGIONS_IONOS, REGIONS_OVH, REGIONS_LINODE, REGIONS_SCALEWAY, REGIONS_EXOSCALE, REGIONS_DIGITALOCEAN, REGIONS_HETZNER, REGIONS_WASABI, REGIONS_S3 } from '../constants.js';
import BackupsModel from '../models/BackupsModel.js';
@@ -342,7 +342,7 @@ defineExpose({
<FormGroup>
<label for="providerInput">{{ $t('backups.configureBackupStorage.provider') }} <sup><a href="https://docs.cloudron.io/backups/#storage-providers" class="help" target="_blank"><i class="fa fa-question-circle"></i></a></sup></label>
<p class="small text-info" v-show="config.provider !== provider">Backups in the old storage location have to be removed manually.</p>
<Dropdown id="providerInput" v-model="provider" :options="storageProviders" option-key="value" option-label="name" />
<SingleSelect id="providerInput" v-model="provider" :options="storageProviders" option-key="value" option-label="name" />
</FormGroup>
<!-- Noop -->
@@ -391,7 +391,7 @@ defineExpose({
<!-- Disk -->
<FormGroup v-if="provider === 'disk'">
<label class="control-label">{{ $t('backups.configureBackupStorage.diskPath') }}</label>
<Dropdown v-model="disk" :options="blockDevices" option-label="label" option-key="path" required />
<SingleSelect v-model="disk" :options="blockDevices" option-label="label" option-key="path" required />
</FormGroup>
<!-- SSHFS -->
@@ -461,17 +461,17 @@ defineExpose({
"
>
<label for="regionInput">{{ $t('backups.configureBackupStorage.region') }}</label>
<Dropdown id="regionInput" v-if="provider === 's3'" v-model="region" :options="REGIONS_S3" option-label="name" option-key="value" required />
<Dropdown id="regionInput" v-if="provider === 'digitalocean-spaces'" v-model="endpoint" :options="REGIONS_DIGITALOCEAN" option-label="name" option-key="value" required />
<Dropdown id="regionInput" v-if="provider === 'hetzner-objectstorage'" v-model="endpoint" :options="REGIONS_HETZNER" option-label="name" option-key="value" required />
<Dropdown id="regionInput" v-if="provider === 'exoscale-sos'" v-model="endpoint" :options="REGIONS_EXOSCALE" option-label="name" option-key="value" required />
<Dropdown id="regionInput" v-if="provider === 'wasabi'" v-model="endpoint" :options="REGIONS_WASABI" option-label="name" option-key="value" required />
<Dropdown id="regionInput" v-if="provider === 'scaleway-objectstorage'" v-model="endpoint" :options="REGIONS_SCALEWAY" option-label="name" option-key="value" required />
<Dropdown id="regionInput" v-if="provider === 'linode-objectstorage'" v-model="endpoint" :options="REGIONS_LINODE" option-label="name" option-key="value" required />
<Dropdown id="regionInput" v-if="provider === 'ovh-objectstorage'" v-model="endpoint" :options="REGIONS_OVH" option-label="name" option-key="value" required />
<Dropdown id="regionInput" v-if="provider === 'ionos-objectstorage'" v-model="endpoint" :options="REGIONS_IONOS" option-label="name" option-key="value" required />
<Dropdown id="regionInput" v-if="provider === 'vultr-objectstorage'" v-model="endpoint" :options="REGIONS_VULTR" option-label="name" option-key="value" required />
<Dropdown id="regionInput" v-if="provider === 'contabo-objectstorage'" v-model="endpoint" :options="REGIONS_CONTABO" option-label="name" option-key="value" required />
<SingleSelect id="regionInput" v-if="provider === 's3'" v-model="region" :options="REGIONS_S3" option-label="name" option-key="value" required />
<SingleSelect id="regionInput" v-if="provider === 'digitalocean-spaces'" v-model="endpoint" :options="REGIONS_DIGITALOCEAN" option-label="name" option-key="value" required />
<SingleSelect id="regionInput" v-if="provider === 'hetzner-objectstorage'" v-model="endpoint" :options="REGIONS_HETZNER" option-label="name" option-key="value" required />
<SingleSelect id="regionInput" v-if="provider === 'exoscale-sos'" v-model="endpoint" :options="REGIONS_EXOSCALE" option-label="name" option-key="value" required />
<SingleSelect id="regionInput" v-if="provider === 'wasabi'" v-model="endpoint" :options="REGIONS_WASABI" option-label="name" option-key="value" required />
<SingleSelect id="regionInput" v-if="provider === 'scaleway-objectstorage'" v-model="endpoint" :options="REGIONS_SCALEWAY" option-label="name" option-key="value" required />
<SingleSelect id="regionInput" v-if="provider === 'linode-objectstorage'" v-model="endpoint" :options="REGIONS_LINODE" option-label="name" option-key="value" required />
<SingleSelect id="regionInput" v-if="provider === 'ovh-objectstorage'" v-model="endpoint" :options="REGIONS_OVH" option-label="name" option-key="value" required />
<SingleSelect id="regionInput" v-if="provider === 'ionos-objectstorage'" v-model="endpoint" :options="REGIONS_IONOS" option-label="name" option-key="value" required />
<SingleSelect id="regionInput" v-if="provider === 'vultr-objectstorage'" v-model="endpoint" :options="REGIONS_VULTR" option-label="name" option-key="value" required />
<SingleSelect id="regionInput" v-if="provider === 'contabo-objectstorage'" v-model="endpoint" :options="REGIONS_CONTABO" option-label="name" option-key="value" required />
</FormGroup>
<FormGroup v-if="provider === 's3-v4-compat'">
+2 -2
View File
@@ -1,7 +1,7 @@
<script setup>
import { ref, useTemplateRef, onMounted, computed } from 'vue';
import { Dialog, Button, Icon, FormGroup, Dropdown, Checkbox, TextInput, ProgressBar } from 'pankow';
import { Dialog, Button, Icon, FormGroup, SingleSelect, Checkbox, TextInput, ProgressBar } from 'pankow';
import { prettyLongDate } from 'pankow/utils';
import Section from './Section.vue';
import UserDirectoryModel from '../models/UserDirectoryModel.js';
@@ -236,7 +236,7 @@ onMounted(async () => {
<FormGroup>
<label for="ldapProvider">{{ $t('users.externalLdap.provider') }} <sup><a href="https://docs.cloudron.io/user-directory/#external-directory" target="_blank"><i class="fa fa-question-circle"></i></a></sup></label>
<Dropdown id="ldapProvider" v-model="provider" :options="availableProviders" option-key="value" option-label="name" />
<SingleSelect id="ldapProvider" v-model="provider" :options="availableProviders" option-key="value" option-label="name" />
</FormGroup>
<p class="text-small text-warning" v-show="provider === 'noop' && config.provider !== 'noop'">{{ $t('users.externalLdap.disableWarning') }}</p>
+2 -3
View File
@@ -1,7 +1,7 @@
<script setup>
import { ref, onMounted, useTemplateRef, computed } from 'vue';
import { Button, Dialog, Dropdown, FormGroup, TextInput } from 'pankow';
import { Button, Dialog, SingleSelect, FormGroup, TextInput } from 'pankow';
import Section from '../components/Section.vue';
import NetworkModel from '../models/NetworkModel.js';
@@ -110,8 +110,7 @@ onMounted(async () => {
<FormGroup>
<label for="providerInput">{{ $t('network.ip.provider') }} <sup><a href="https://docs.cloudron.io/networking/#ipv4" class="help" target="_blank"><i class="fa fa-question-circle"></i></a></sup></label>
<!-- <select v-model="sysinfo.newProvider" :options="a.value as a.name for a in sysinfoProvider"></select> -->
<Dropdown id="providerInput" v-model="editProvider" :options="providers" option-key="value" option-label="name"/>
<SingleSelect id="providerInput" v-model="editProvider" :options="providers" option-key="value" option-label="name"/>
<p class="has-error" v-show="editError.generic">{{ editError.generic }}</p>
</FormGroup>
+2 -3
View File
@@ -1,7 +1,7 @@
<script setup>
import { ref, onMounted, useTemplateRef, computed } from 'vue';
import { Button, Dialog, Dropdown, FormGroup, TextInput } from 'pankow';
import { Button, Dialog, SingleSelect, FormGroup, TextInput } from 'pankow';
import Section from '../components/Section.vue';
import NetworkModel from '../models/NetworkModel.js';
@@ -110,8 +110,7 @@ onMounted(async () => {
<FormGroup>
<label for="providerInput">{{ $t('network.ip.provider') }} <sup><a href="https://docs.cloudron.io/networking/#ipv4" class="help" target="_blank"><i class="fa fa-question-circle"></i></a></sup></label>
<!-- <select v-model="sysinfo.newProvider" :options="a.value as a.name for a in sysinfoProvider"></select> -->
<Dropdown id="providerInput" v-model="editProvider" :options="providers" option-key="value" option-label="name"/>
<SingleSelect id="providerInput" v-model="editProvider" :options="providers" option-key="value" option-label="name"/>
<p class="has-error" v-show="editError.generic">{{ editError.generic }}</p>
</FormGroup>
+2 -2
View File
@@ -5,7 +5,7 @@ const i18n = useI18n();
const t = i18n.t;
import { ref, useTemplateRef, onMounted, computed } from 'vue';
import { Button, Dialog, FormGroup, PasswordInput, TextInput, Dropdown } from 'pankow';
import { Button, Dialog, FormGroup, PasswordInput, TextInput, SingleSelect } from 'pankow';
import { isValidDomainOrURL } from 'pankow/utils';
import Section from '../components/Section.vue';
import CloudronModel from '../models/CloudronModel.js';
@@ -128,7 +128,7 @@ onMounted(async () => {
<FormGroup>
<label for="providerInput">{{ $t('settings.registryConfig.provider') }} <sup><a href="https://docs.cloudron.io/settings/#private-docker-registry" class="help" target="_blank"><i class="fa fa-question-circle"></i></a></sup></label>
<Dropdown id="providerInput" v-model="configureProvider" :options="providers" option-key="value" option-label="name" />
<SingleSelect id="providerInput" v-model="configureProvider" :options="providers" option-key="value" option-label="name" />
</FormGroup>
<FormGroup v-if="configureProvider !== 'noop'">
+4 -4
View File
@@ -1,7 +1,7 @@
<script setup>
import { ref, computed, useTemplateRef, onMounted, onUnmounted } from 'vue';
import { Button, ButtonGroup, Dropdown, Icon, TableView, TextInput } from 'pankow';
import { Button, ButtonGroup, SingleSelect, Icon, TableView, TextInput } from 'pankow';
import { API_ORIGIN, APP_TYPES, HSTATES, ISTATES, RSTATES } from '../constants.js';
import AppsModel from '../models/AppsModel.js';
import ApplinksModel from '../models/ApplinksModel.js';
@@ -219,9 +219,9 @@ onUnmounted(() => {
{{ $t('apps.title') }}
<div style="display: flex; gap: 4px; flex-wrap: wrap; margin-top: 10px;">
<TextInput v-model="filter" :placeholder="$t('apps.searchPlaceholder')" />
<Dropdown class="pankow-no-mobile" outline tool v-if="profile.isAtLeastAdmin" :options="tagFilterOptions" option-key="id" option-label="name" v-model="tagFilter"></Dropdown>
<Dropdown class="pankow-no-mobile" outline tool v-if="profile.isAtLeastAdmin" :options="stateFilterOptions" option-key="id" v-model="stateFilter"></Dropdown>
<Dropdown class="pankow-no-mobile" outline tool v-if="profile.isAtLeastAdmin" :options="domainFilterOptions" option-key="id" option-label="domain" v-model="domainFilter"></Dropdown>
<SingleSelect class="pankow-no-mobile" v-if="profile.isAtLeastAdmin" :options="tagFilterOptions" option-key="id" option-label="name" v-model="tagFilter" />
<SingleSelect class="pankow-no-mobile" v-if="profile.isAtLeastAdmin" :options="stateFilterOptions" option-key="id" v-model="stateFilter" />
<SingleSelect class="pankow-no-mobile" v-if="profile.isAtLeastAdmin" :options="domainFilterOptions" option-key="id" option-label="domain" v-model="domainFilter" />
<Button tool @click="toggleView()" :icon="viewType === VIEW_TYPE.GRID ? 'fas fa-list' : 'fas fa-grip'"></Button>
</div>
</h1>
+2 -2
View File
@@ -5,7 +5,7 @@ const i18n = useI18n();
const t = i18n.t;
import { ref, reactive, onMounted, watch } from 'vue';
import { Button, ButtonGroup, Dropdown, Spinner, TextInput, MultiSelect } from 'pankow';
import { Button, ButtonGroup, SingleSelect, Spinner, TextInput, MultiSelect } from 'pankow';
import { useDebouncedRef, prettyDate, prettyLongDate, prettyEmailAddresses } from 'pankow/utils';
import Section from '../components/Section.vue';
import MailModel from '../models/MailModel.js';
@@ -91,7 +91,7 @@ onMounted(async () => {
<!-- TODO replace with fetch more on scroll -->
<div class="eventlog-filter">
<Dropdown v-model="perPage" :options="perPageOptions" option-key="value" option-label="name"/>
<SingleSelect v-model="perPage" :options="perPageOptions" option-key="value" option-label="name"/>
<ButtonGroup>
<Button tool secondary @click="onPrevPage()" :disabled="busy || page <= 1" icon="fa-solid fa-angle-double-left" v-tooltip="$t('main.pagination.prev')" />
+2 -3
View File
@@ -5,7 +5,7 @@ const i18n = useI18n();
const t = i18n.t;
import { ref, onMounted, useTemplateRef } from 'vue';
import { Button, Dropdown, Dialog, InputDialog, TextInput, InputGroup } from 'pankow';
import { Button, SingleSelect, Dialog, InputDialog, TextInput, InputGroup } from 'pankow';
import { TOKEN_TYPES } from '../constants.js';
import AppPasswords from '../components/AppPasswords.vue';
import SettingsItem from '../components/SettingsItem.vue';
@@ -338,12 +338,11 @@ onMounted(async () => {
<div style="font-weight: bold">{{ $t('profile.language') }}</div>
</div>
<div style="display: flex; align-items: center">
<Dropdown small tool outline v-model="language" :options="languages" option-label="display" option-key="id" @select="onSelectLanguage"/>
<SingleSelect v-model="language" :options="languages" option-label="display" option-key="id" @select="onSelectLanguage"/>
</div>
</SettingsItem>
<div style="display: flex; gap: 10px;">
<!-- <Button tool @click="onPasswordReset()">{{ $t('profile.passwordResetAction') }}</Button> -->
<Button tool @click="onPasswordChange()">{{ $t('profile.changePasswordAction') }}</Button>
<Button tool v-show="!user.source && !config.external2FA" @click="user.twoFactorAuthenticationEnabled ? onTwoFADisable() : onOpenTwoFASetupDialog()">{{ $t(user.twoFactorAuthenticationEnabled ? 'profile.disable2FAAction' : 'profile.enable2FAAction') }}</Button>
</div>
+2 -2
View File
@@ -5,7 +5,7 @@ const i18n = useI18n();
const t = i18n.t;
import { ref, onMounted, computed, useTemplateRef } from 'vue';
import { Button, ButtonGroup, TextInput, Dropdown, TableView, InputDialog } from 'pankow';
import { Button, ButtonGroup, TextInput, SingleSelect, TableView, InputDialog } from 'pankow';
import { ROLES } from '../constants.js';
import Section from '../components/Section.vue';
import UserDialog from '../components/UserDialog.vue';
@@ -225,7 +225,7 @@ onMounted(async () => {
<Section :title="$t('main.navbar.users')">
<template #header-buttons>
<TextInput v-model="search" placeholder="Search ..." />
<Dropdown outline tool :options="filterOptions" option-key="id" option-label="name" v-model="filter"></Dropdown>
<SingleSelect :options="filterOptions" option-key="id" option-label="name" v-model="filter" />
<Button icon="fa-solid fa-user-plus" @click="onEditOrAddUser()">{{ $t('users.newUserAction') }}</Button>
</template>
+4 -4
View File
@@ -5,7 +5,7 @@ const i18n = useI18n();
const t = i18n.t;
import { computed, ref, useTemplateRef, onMounted } from 'vue';
import { Button, ButtonGroup, Checkbox, Dialog, Dropdown, FormGroup, InputDialog, NumberInput, PasswordInput, TableView, TextInput } from 'pankow';
import { Button, ButtonGroup, Checkbox, Dialog, SingleSelect, FormGroup, InputDialog, NumberInput, PasswordInput, TableView, TextInput } from 'pankow';
import Section from '../components/Section.vue';
import StateLED from '../components/StateLED.vue';
import VolumesModel from '../models/VolumesModel.js';
@@ -232,7 +232,7 @@ onMounted(async () =>{
<FormGroup>
<label for="volumeMountType">{{ $t('volumes.mountType') }}</label>
<Dropdown id="volumeMountType" v-model="volumeDialogData.mountType" :options="mountTypeOptions" option-label="name" option-key="value" :disabled="volumeDialogData.mode === 'edit'"/>
<SingleSelect id="volumeMountType" v-model="volumeDialogData.mountType" :options="mountTypeOptions" option-label="name" option-key="value" :disabled="volumeDialogData.mode === 'edit'"/>
</FormGroup>
<FormGroup v-if="volumeDialogData.mountType === 'filesystem' || volumeDialogData.mountType === 'mountpoint'">
@@ -242,8 +242,8 @@ onMounted(async () =>{
<FormGroup v-if="volumeDialogData.mountType === 'ext4' || volumeDialogData.mountType === 'xfs'">
<label for="volumeDiskPath">{{ $t('volumes.addVolumeDialog.diskPath') }}</label>
<Dropdown id="volumeMountType" v-if="volumeDialogData.mountType === 'ext4'" v-model="volumeDialogData.diskPath" :options="volumeDialogData.ext4BlockDevices" option-label="label" option-key="path" :disabled="volumeDialogData.mode === 'edit'"/>
<Dropdown id="volumeMountType" v-if="volumeDialogData.mountType === 'xfs'" v-model="volumeDialogData.diskPath" :options="volumeDialogData.xfsBlockDevices" option-label="label" option-key="path" :disabled="volumeDialogData.mode === 'edit'"/>
<SingleSelect id="volumeMountType" v-if="volumeDialogData.mountType === 'ext4'" v-model="volumeDialogData.diskPath" :options="volumeDialogData.ext4BlockDevices" option-label="label" option-key="path" :disabled="volumeDialogData.mode === 'edit'"/>
<SingleSelect id="volumeMountType" v-if="volumeDialogData.mountType === 'xfs'" v-model="volumeDialogData.diskPath" :options="volumeDialogData.xfsBlockDevices" option-label="label" option-key="path" :disabled="volumeDialogData.mode === 'edit'"/>
</FormGroup>
<FormGroup v-if="volumeDialogData.mountType === 'cifs' || volumeDialogData.mountType === 'nfs' || volumeDialogData.mountType === 'sshfs'">