diff options
author | Andrey V.Kosteltsev <AKosteltsev@IBS.RU> | 2022-07-04 23:11:28 +0300 |
---|---|---|
committer | Andrey V.Kosteltsev <AKosteltsev@IBS.RU> | 2022-07-04 23:11:28 +0300 |
commit | 3f4094d08b873e17464a51c817ea7d41177f848d (patch) | |
tree | 8880a0e7c8c0ac07ed298ce719cfab3278f2aa12 /src/views/_ibs/Operations/VirtualMedia | |
parent | f5c8dbfa6fb3812a3b3a2aafd3538fbdf8b8c668 (diff) | |
download | webui-vue-3f4094d08b873e17464a51c817ea7d41177f848d.tar.xz |
IBS: _ibs UI Theme
Diffstat (limited to 'src/views/_ibs/Operations/VirtualMedia')
3 files changed, 382 insertions, 0 deletions
diff --git a/src/views/_ibs/Operations/VirtualMedia/ModalConfigureConnection.vue b/src/views/_ibs/Operations/VirtualMedia/ModalConfigureConnection.vue new file mode 100644 index 00000000..b0bcfb2b --- /dev/null +++ b/src/views/_ibs/Operations/VirtualMedia/ModalConfigureConnection.vue @@ -0,0 +1,145 @@ +<template> + <b-modal + id="configure-connection" + ref="modal" + @ok="onOk" + @hidden="resetForm" + @show="initModal" + > + <template #modal-title> + {{ $t('pageVirtualMedia.modal.title') }} + </template> + <b-form> + <b-form-group + :label="$t('pageVirtualMedia.modal.serverUri')" + label-for="serverUri" + > + <b-form-input + id="serverUri" + v-model="form.serverUri" + type="text" + :state="getValidationState($v.form.serverUri)" + data-test-id="configureConnection-input-serverUri" + @input="$v.form.serverUri.$touch()" + /> + <b-form-invalid-feedback role="alert"> + <template v-if="!$v.form.serverUri.required"> + {{ $t('global.form.fieldRequired') }} + </template> + </b-form-invalid-feedback> + </b-form-group> + <b-form-group + :label="$t('pageVirtualMedia.modal.username')" + label-for="username" + > + <b-form-input + id="username" + v-model="form.username" + type="text" + data-test-id="configureConnection-input-username" + /> + </b-form-group> + <b-form-group + :label="$t('pageVirtualMedia.modal.password')" + label-for="password" + > + <b-form-input + id="password" + v-model="form.password" + type="password" + data-test-id="configureConnection-input-password" + /> + </b-form-group> + <b-form-group> + <b-form-checkbox + v-model="form.isRW" + data-test-id="configureConnection-input-isRW" + name="check-button" + > + RW + </b-form-checkbox> + </b-form-group> + </b-form> + <template #modal-ok> + {{ $t('global.action.save') }} + </template> + <template #modal-cancel> + {{ $t('global.action.cancel') }} + </template> + </b-modal> +</template> + +<script> +import { required } from 'vuelidate/lib/validators'; +import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js'; + +export default { + mixins: [VuelidateMixin], + props: { + connection: { + type: Object, + default: null, + validator: (prop) => { + console.log(prop); + return true; + }, + }, + }, + data() { + return { + form: { + serverUri: null, + username: null, + password: null, + isRW: false, + }, + }; + }, + watch: { + connection: function (value) { + if (value === null) return; + Object.assign(this.form, value); + }, + }, + validations() { + return { + form: { + serverUri: { + required, + }, + }, + }; + }, + methods: { + handleSubmit() { + this.$v.$touch(); + if (this.$v.$invalid) return; + let connectionData = {}; + Object.assign(connectionData, this.form); + this.$emit('ok', connectionData); + this.closeModal(); + }, + initModal() { + if (this.connection) { + Object.assign(this.form, this.connection); + } + }, + closeModal() { + this.$nextTick(() => { + this.$refs.modal.hide(); + }); + }, + resetForm() { + this.form.serverUri = null; + this.form.username = null; + this.form.password = null; + this.form.isRW = false; + this.$v.$reset(); + }, + onOk(bvModalEvt) { + bvModalEvt.preventDefault(); + this.handleSubmit(); + }, + }, +}; +</script> diff --git a/src/views/_ibs/Operations/VirtualMedia/VirtualMedia.vue b/src/views/_ibs/Operations/VirtualMedia/VirtualMedia.vue new file mode 100644 index 00000000..fc8369d4 --- /dev/null +++ b/src/views/_ibs/Operations/VirtualMedia/VirtualMedia.vue @@ -0,0 +1,235 @@ +<template> + <b-container fluid="xl"> + <page-title /> + <b-row class="mb-4"> + <b-col md="12"> + <page-section + :section-title="$t('pageVirtualMedia.virtualMediaSubTitleFirst')" + > + <b-row> + <b-col v-for="(dev, $index) in proxyDevices" :key="$index" md="6"> + <div class="media-buttons-group"> + <div class="media-start"> + <b-form-group :label="dev.id" label-class="bold"> + <form-file + v-if="!dev.isActive" + :id="concatId(dev.id)" + v-model="dev.file" + > + <template #invalid> + <b-form-invalid-feedback role="alert"> + {{ $t('global.form.required') }} + </b-form-invalid-feedback> + </template> + </form-file> + </b-form-group> + </div> + <div class="media-stop"> + <b-button + v-if="!dev.isActive" + variant="primary" + :disabled="!dev.file" + @click="startVM(dev)" + > + {{ $t('pageVirtualMedia.start') }} + </b-button> + <b-button + v-if="dev.isActive" + variant="primary" + :disabled="!dev.file" + @click="stopVM(dev)" + > + {{ $t('pageVirtualMedia.stop') }} + </b-button> + </div> + </div> + </b-col> + </b-row> + </page-section> + </b-col> + </b-row> + <b-row v-if="loadImageFromExternalServer" class="mb-4"> + <b-col md="12"> + <page-section + :section-title="$t('pageVirtualMedia.virtualMediaSubTitleSecond')" + > + <b-row> + <b-col + v-for="(device, $index) in legacyDevices" + :key="$index" + md="6" + > + <div class="media-legacy"> + <b-form-group + :label="device.id" + :label-for="device.id" + label-class="bold" + > + <div class="media-legacy-buttons-group"> + <div class="media-legacy-configure"> + <b-button + variant="primary" + :disabled="device.isActive" + @click="configureConnection(device)" + > + {{ $t('pageVirtualMedia.configureConnection') }} + </b-button> + </div> + + <div class="media-legacy-start"> + <b-button + v-if="!device.isActive" + variant="primary" + class="float-right" + :disabled="!device.serverUri" + @click="startLegacy(device)" + > + {{ $t('pageVirtualMedia.start') }} + </b-button> + <b-button + v-if="device.isActive" + variant="primary" + class="float-right" + @click="stopLegacy(device)" + > + {{ $t('pageVirtualMedia.stop') }} + </b-button> + </div> + </div> + </b-form-group> + </div> + </b-col> + </b-row> + </page-section> + </b-col> + </b-row> + <modal-configure-connection + :connection="modalConfigureConnection" + @ok="saveConnection" + /> + </b-container> +</template> + +<script> +import PageTitle from '@/components/Global/PageTitle'; +import PageSection from '@/components/Global/PageSection'; +import BVToastMixin from '@/components/Mixins/BVToastMixin'; +import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin'; +import ModalConfigureConnection from './ModalConfigureConnection'; +import NbdServer from '@/utilities/NBDServer'; +import FormFile from '@/components/Global/FormFile'; + +export default { + name: 'VirtualMedia', + components: { PageTitle, PageSection, ModalConfigureConnection, FormFile }, + mixins: [BVToastMixin, LoadingBarMixin], + data() { + return { + modalConfigureConnection: null, + loadImageFromExternalServer: + process.env.VUE_APP_VIRTUAL_MEDIA_LIST_ENABLED === 'true' + ? true + : false, + }; + }, + computed: { + proxyDevices() { + return this.$store.getters['virtualMedia/proxyDevices']; + }, + legacyDevices() { + return this.$store.getters['virtualMedia/legacyDevices']; + }, + }, + created() { + if (this.proxyDevices.length > 0 || this.legacyDevices.length > 0) return; + this.startLoader(); + this.$store + .dispatch('virtualMedia/getData') + .finally(() => this.endLoader()); + }, + methods: { + startVM(device) { + const token = this.$store.getters['authentication/token']; + device.nbd = new NbdServer( + `wss://${window.location.host}${device.websocket}`, + device.file, + device.id, + token + ); + device.nbd.socketStarted = () => + this.successToast(this.$t('pageVirtualMedia.toast.serverRunning')); + device.nbd.errorReadingFile = () => + this.errorToast(this.$t('pageVirtualMedia.toast.errorReadingFile')); + device.nbd.socketClosed = (code) => { + if (code === 1000) + this.successToast( + this.$t('pageVirtualMedia.toast.serverClosedSuccessfully') + ); + else + this.errorToast( + this.$t('pageVirtualMedia.toast.serverClosedWithErrors') + ); + device.file = null; + device.isActive = false; + }; + + device.nbd.start(); + device.isActive = true; + }, + stopVM(device) { + device.nbd.stop(); + }, + startLegacy(connectionData) { + var data = {}; + data.Image = connectionData.serverUri; + data.UserName = connectionData.username; + data.Password = connectionData.password; + data.WriteProtected = !connectionData.isRW; + this.startLoader(); + this.$store + .dispatch('virtualMedia/mountImage', { + id: connectionData.id, + data: data, + }) + .then(() => { + this.successToast( + this.$t('pageVirtualMedia.toast.serverConnectionEstablished') + ); + connectionData.isActive = true; + }) + .catch(() => { + this.errorToast(this.$t('pageVirtualMedia.toast.errorMounting')); + this.isActive = false; + }) + .finally(() => this.endLoader()); + }, + stopLegacy(connectionData) { + this.$store + .dispatch('virtualMedia/unmountImage', connectionData.id) + .then(() => { + this.successToast( + this.$t('pageVirtualMedia.toast.serverClosedSuccessfully') + ); + connectionData.isActive = false; + }) + .catch(() => + this.errorToast(this.$t('pageVirtualMedia.toast.errorUnmounting')) + ) + .finally(() => this.endLoader()); + }, + saveConnection(connectionData) { + this.modalConfigureConnection.serverUri = connectionData.serverUri; + this.modalConfigureConnection.username = connectionData.username; + this.modalConfigureConnection.password = connectionData.password; + this.modalConfigureConnection.isRW = connectionData.isRW; + }, + configureConnection(connectionData) { + this.modalConfigureConnection = connectionData; + this.$bvModal.show('configure-connection'); + }, + concatId(val) { + return val.split(' ').join('_').toLowerCase(); + }, + }, +}; +</script> diff --git a/src/views/_ibs/Operations/VirtualMedia/index.js b/src/views/_ibs/Operations/VirtualMedia/index.js new file mode 100644 index 00000000..4573e865 --- /dev/null +++ b/src/views/_ibs/Operations/VirtualMedia/index.js @@ -0,0 +1,2 @@ +import VirtualMedia from './VirtualMedia.vue'; +export default VirtualMedia; |