Port volumes view to composition style

This commit is contained in:
Johannes Zellner
2025-02-02 22:44:08 +01:00
parent 4ef7195d38
commit dffef6f839
+103 -111
View File
@@ -1,30 +1,46 @@
<script> <script setup>
import { useI18n } from 'vue-i18n';
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, Dropdown, FormGroup, InputDialog, NumberInput, PasswordInput, TableView, TextInput } from 'pankow';
import Section from '../components/Section.vue'; import Section from '../components/Section.vue';
import VolumesModel from '../models/VolumesModel.js'; import VolumesModel from '../models/VolumesModel.js';
const volumesModel = VolumesModel.create(); const volumesModel = VolumesModel.create();
export default { const mountTypeOptions = [
name: 'VolumesView', { name: 'CIFS', value: 'cifs' },
components: { { name: 'EXT4', value: 'ext4' },
Button, { name: 'Filesystem', value: 'filesystem' },
ButtonGroup, { name: 'Filesystem (Mountpoint)', value: 'mountpoint' },
Section, { name: 'NFS', value: 'nfs' },
Checkbox, { name: 'SSHFS', value: 'sshfs' },
Dialog, { name: 'XFS', value: 'xfs' },
Dropdown, ];
FormGroup,
InputDialog, const columns = {
NumberInput, status: {},
PasswordInput, name: { label: 'Name', sort: true },
TableView, mountType: { label: 'Type', sort: true },
TextInput, target: { label: 'Target', sort: true },
}, actions: {}
computed: { };
volumeDialogValid() {
const data = this.volumeDialogData; const busy = ref(true);
const volumes = ref([]);
const volumeDialogData = ref({
error: null,
busy: false,
mode: '', // edit or new
name: '',
// dynamic extra props from openVolumeDialog
});
const volumeDialogValid = computed(() => {
const data = volumeDialogData.value;
if (data.mode === 'new') { if (data.mode === 'new') {
if (!data.name) return false; if (!data.name) return false;
@@ -43,18 +59,18 @@ export default {
break; break;
case 'nfs': case 'nfs':
if (!data.host) return false; if (!data.host) return false;
if (!data.remoteDirectory) return false; if (!data.remoteDir) return false;
break; break;
case 'sshfs': case 'sshfs':
if (!data.host) return false; if (!data.host) return false;
if (!data.remoteDirectory) return false; if (!data.remoteDir) return false;
if (!data.post) return false; if (!data.post) return false;
if (!data.user) return false; if (!data.user) return false;
if (!data.privateKey) return false; if (!data.privateKey) return false;
break; break;
case 'cifs': case 'cifs':
if (!data.host) return false; if (!data.host) return false;
if (!data.remoteDirectory) return false; if (!data.remoteDir) return false;
if (!data.username) return false; if (!data.username) return false;
if (!data.password) return false; if (!data.password) return false;
break; break;
@@ -63,63 +79,37 @@ export default {
} }
return true; return true;
} });
},
data() {
return {
busy: true,
mountTypeOptions: [
{ name: 'CIFS', value: 'cifs' },
{ name: 'EXT4', value: 'ext4' },
{ name: 'Filesystem', value: 'filesystem' },
{ name: 'Filesystem (Mountpoint)', value: 'mountpoint' },
{ name: 'NFS', value: 'nfs' },
{ name: 'SSHFS', value: 'sshfs' },
{ name: 'XFS', value: 'xfs' },
],
columns: {
status: {},
name: { label: 'Name', sort: true },
mountType: { label: 'Type', sort: true },
target: { label: 'Target', sort: true },
actions: {}
},
volumes: [],
volumeDialogData: {
error: null,
busy: false,
mode: '', // edit or new
name: '',
// dynamic extra props from openVolumeDialog
},
};
},
methods: {
async refresh() {
this.busy = true;
this.volumes = await volumesModel.list();
this.busy = false;
for (const v of this.volumes) { async function refresh() {
busy.value = true;
volumes.value = await volumesModel.list();
busy.value = false;
for (const v of volumes.value) {
const status = await volumesModel.getStatus(v.id); const status = await volumesModel.getStatus(v.id);
v.state = status.state; v.state = status.state;
v.message = status.message; v.message = status.message;
} }
}, };
async openVolumeDialog(volume) {
this.volumeDialogData.error = null; const volumeDialog = useTemplateRef('volumeDialog');
this.volumeDialogData.mode = volume ? 'edit' : 'new'; const inputDialog = useTemplateRef('inputDialog');
this.volumeDialogData.id = volume ? volume.id : '';
this.volumeDialogData.name = volume ? volume.name : ''; async function openVolumeDialog(volume) {
this.volumeDialogData.mountType = volume ? volume.mountType : ''; volumeDialogData.value.error = null;
this.volumeDialogData.host = volume ? volume.mountOptions.host : ''; volumeDialogData.value.mode = volume ? 'edit' : 'new';
this.volumeDialogData.seal = volume ? volume.mountOptions.seal : false; volumeDialogData.value.id = volume ? volume.id : '';
this.volumeDialogData.port = volume ? volume.mountOptions.port : 0; volumeDialogData.value.name = volume ? volume.name : '';
this.volumeDialogData.remoteDir = volume ? volume.mountOptions.remoteDir : ''; volumeDialogData.value.mountType = volume ? volume.mountType : '';
this.volumeDialogData.username = volume ? volume.mountOptions.username : ''; volumeDialogData.value.host = volume ? volume.mountOptions.host : '';
this.volumeDialogData.password = volume ? volume.mountOptions.password : ''; volumeDialogData.value.seal = volume ? volume.mountOptions.seal : false;
this.volumeDialogData.diskPath = volume ? volume.mountOptions.diskPath : ''; volumeDialogData.value.port = volume ? volume.mountOptions.port : 0;
this.volumeDialogData.hostPath = volume ? volume.mountOptions.hostPath : ''; volumeDialogData.value.remoteDir = volume ? volume.mountOptions.remoteDir : '';
volumeDialogData.value.username = volume ? volume.mountOptions.username : '';
volumeDialogData.value.password = volume ? volume.mountOptions.password : '';
volumeDialogData.value.diskPath = volume ? volume.mountOptions.diskPath : '';
volumeDialogData.value.hostPath = volume ? volume.mountOptions.hostPath : '';
let blockDevices = await volumesModel.getBlockDevices(); let blockDevices = await volumesModel.getBlockDevices();
@@ -129,57 +119,60 @@ export default {
// amend label for UI // amend label for UI
blockDevices.forEach(d => d.label = d.path); blockDevices.forEach(d => d.label = d.path);
this.volumeDialogData.ext4BlockDevices = blockDevices.filter(d => d.type === 'ext4'); volumeDialogData.value.ext4BlockDevices = blockDevices.filter(d => d.type === 'ext4');
this.volumeDialogData.xfsBlockDevices = blockDevices.filter(d => d.type === 'xfs'); volumeDialogData.value.xfsBlockDevices = blockDevices.filter(d => d.type === 'xfs');
this.$refs.volumeDialog.open(); volumeDialog.value.open();
}, }
async submitVolumeDialog() {
this.volumeDialogData.busy = true; async function submitVolumeDialog() {
volumeDialogData.value.busy = true;
const mountOptions = { const mountOptions = {
host: this.volumeDialogData.host, host: volumeDialogData.value.host,
seal: this.volumeDialogData.seal, seal: volumeDialogData.value.seal,
port: this.volumeDialogData.port, port: volumeDialogData.value.port,
remoteDir: this.volumeDialogData.remoteDir, remoteDir: volumeDialogData.value.remoteDir,
username: this.volumeDialogData.username, username: volumeDialogData.value.username,
password: this.volumeDialogData.password, password: volumeDialogData.value.password,
diskPath: this.volumeDialogData.diskPath, diskPath: volumeDialogData.value.diskPath,
hostPath: this.volumeDialogData.hostPath, hostPath: volumeDialogData.value.hostPath,
}; };
try { try {
if (this.volumeDialogData.mode === 'new') { if (volumeDialogData.value.mode === 'new') {
await volumesModel.add(this.volumeDialogData.name, this.volumeDialogData.mountType, mountOptions); await volumesModel.add(volumeDialogData.value.name, volumeDialogData.value.mountType, mountOptions);
} else { } else {
await volumesModel.update(this.volumeDialogData.id, mountOptions); await volumesModel.update(volumeDialogData.value.id, mountOptions);
} }
} catch (error) { } catch (error) {
this.volumeDialogData.error = error.body ? error.body.message : 'Internal error'; volumeDialogData.value.error = error.body ? error.body.message : 'Internal error';
this.volumeDialogData.busy = false; volumeDialogData.value.busy = false;
console.error(error); console.error(error);
return; return;
} }
await this.refresh(); await refresh();
this.$refs.volumeDialog.close(); volumeDialog.value.close();
this.volumeDialogData.busy = false; volumeDialogData.value.busy = false;
}, }
async onRemove(volume) {
const yes = await this.$refs.inputDialog.confirm({ async function onRemove(volume) {
const yes = await inputDialog.value.confirm({
message: `Really remove volume ${volume.name}?`, message: `Really remove volume ${volume.name}?`,
confirmStyle: 'danger', confirmStyle: 'danger',
confirmLabel: this.$t('volumes.removeVolumeDialog.removeAction'), confirmLabel: t('volumes.removeVolumeDialog.removeAction'),
rejectLabel: this.$t('main.dialog.cancel') rejectLabel: t('main.dialog.cancel')
}); });
if (!yes) return; if (!yes) return;
await volumesModel.remove(volume.id); await volumesModel.remove(volume.id);
await this.refresh(); await refresh();
}, }
async remount(volume) {
async function remount(volume) {
await volumesModel.remount(volume.id); await volumesModel.remount(volume.id);
const status = await volumesModel.getStatus(volume.id); const status = await volumesModel.getStatus(volume.id);
@@ -188,11 +181,10 @@ export default {
window.pankow.notify('Remount attempt finished'); window.pankow.notify('Remount attempt finished');
} }
},
async mounted() { onMounted(async () =>{
await this.refresh(); await refresh();
} });
};
</script> </script>
@@ -203,8 +195,8 @@ export default {
<Dialog ref="volumeDialog" <Dialog ref="volumeDialog"
:title="volumeDialogData.mode === 'edit' ? $t('volumes.editVolumeDialog.title', { name: volumeDialogData.name }) : $t('volumes.addVolumeDialog.title')" :title="volumeDialogData.mode === 'edit' ? $t('volumes.editVolumeDialog.title', { name: volumeDialogData.name }) : $t('volumes.addVolumeDialog.title')"
:reject-label="$t('main.dialog.cancel')" :reject-label="$t('main.dialog.cancel')"
reject-style="secondary"
:confirm-label="$t('main.dialog.save')" :confirm-label="$t('main.dialog.save')"
confirm-style="success"
:confirm-active="volumeDialogValid" :confirm-active="volumeDialogValid"
:confirm-busy="volumeDialogData.busy" :confirm-busy="volumeDialogData.busy"
@confirm="submitVolumeDialog()" @confirm="submitVolumeDialog()"