| <template> |
| <div :class="marginClass"> |
| <div ref="toolbar" class="kvm-toolbar"> |
| <b-row class="d-flex"> |
| <b-col class="d-flex flex-column justify-content-end" cols="4"> |
| <dl class="mb-2" sm="2" md="2"> |
| <dt class="d-inline font-weight-bold mr-1"> |
| {{ $t('pageKvm.status') }}: |
| </dt> |
| <dd class="d-inline"> |
| <status-icon :status="serverStatusIcon" /> |
| <span class="d-none d-md-inline"> {{ serverStatus }}</span> |
| </dd> |
| </dl> |
| </b-col> |
| |
| <b-col class="d-flex justify-content-end pr-1"> |
| <b-button |
| v-if="isConnected" |
| variant="link" |
| type="button" |
| @click="sendCtrlAltDel" |
| > |
| <icon-arrow-down /> |
| {{ $t('pageKvm.buttonCtrlAltDelete') }} |
| </b-button> |
| <b-button |
| v-if="!isFullWindow" |
| variant="link" |
| type="button" |
| @click="openConsoleWindow()" |
| > |
| <icon-launch /> |
| {{ $t('pageKvm.openNewTab') }} |
| </b-button> |
| </b-col> |
| </b-row> |
| </div> |
| <div id="terminal-kvm" ref="panel" :class="terminalClass"></div> |
| </div> |
| </template> |
| |
| <script> |
| import RFB from '@novnc/novnc/core/rfb'; |
| import StatusIcon from '@/components/Global/StatusIcon'; |
| import IconLaunch from '@carbon/icons-vue/es/launch/20'; |
| import IconArrowDown from '@carbon/icons-vue/es/arrow--down/16'; |
| import { throttle } from 'lodash'; |
| import { useI18n } from 'vue-i18n'; |
| import i18n from '@/i18n'; |
| |
| const Connecting = 0; |
| const Connected = 1; |
| const Disconnected = 2; |
| |
| export default { |
| name: 'KvmConsole', |
| components: { StatusIcon, IconLaunch, IconArrowDown }, |
| props: { |
| isFullWindow: { |
| type: Boolean, |
| default: true, |
| }, |
| }, |
| data() { |
| return { |
| $t: useI18n().t, |
| rfb: null, |
| isConnected: false, |
| terminalClass: this.isFullWindow ? 'full-window' : '', |
| marginClass: this.isFullWindow ? 'margin-left-full-window' : '', |
| status: Connecting, |
| convasRef: null, |
| resizeKvmWindow: null, |
| }; |
| }, |
| computed: { |
| serverStatusIcon() { |
| if (this.status === Connected) { |
| return 'success'; |
| } else if (this.status === Disconnected) { |
| return 'danger'; |
| } |
| return 'secondary'; |
| }, |
| serverStatus() { |
| if (this.status === Connected) { |
| return i18n.global.t('pageKvm.connected'); |
| } else if (this.status === Disconnected) { |
| return i18n.global.t('pageKvm.disconnected'); |
| } |
| return i18n.global.t('pageKvm.connecting'); |
| }, |
| }, |
| created() { |
| this.$store.dispatch('global/getSystemInfo'); |
| }, |
| mounted() { |
| this.openTerminal(); |
| }, |
| beforeUnmount() { |
| window.removeEventListener('resize', this.resizeKvmWindow); |
| this.closeTerminal(); |
| }, |
| methods: { |
| sendCtrlAltDel() { |
| this.rfb.sendCtrlAltDel(); |
| }, |
| closeTerminal() { |
| this.rfb.disconnect(); |
| this.rfb = null; |
| }, |
| openTerminal() { |
| const token = this.$store.getters['authentication/token']; |
| this.rfb = new RFB( |
| this.$refs.panel, |
| `wss://${window.location.host}/kvm/0`, |
| { wsProtocols: [token] }, |
| ); |
| |
| this.rfb.scaleViewport = true; |
| this.rfb.clipViewport = true; |
| const that = this; |
| |
| this.resizeKvmWindow = throttle(() => { |
| setTimeout(that.setWidthToolbar, 0); |
| }, 1000); |
| window.addEventListener('resize', this.resizeKvmWindow); |
| |
| this.rfb.addEventListener('connect', () => { |
| that.isConnected = true; |
| that.status = Connected; |
| that.setWidthToolbar(); |
| }); |
| |
| this.rfb.addEventListener('disconnect', () => { |
| this.isConnected = false; |
| that.status = Disconnected; |
| }); |
| }, |
| setWidthToolbar() { |
| if ( |
| this.$refs.panel.children && |
| this.$refs.panel.children.length > 0 && |
| this.$refs.panel.children[0].children.length > 0 |
| ) { |
| this.$refs.toolbar.style.width = |
| this.$refs.panel.children[0].children[0].clientWidth - 10 + 'px'; |
| } |
| }, |
| openConsoleWindow() { |
| // If consoleWindow is not null |
| // Check the newly opened window is closed or not |
| if (this.$eventBus.$consoleWindow) { |
| // If window is not closed set focus to new window |
| // If window is closed, do open new window |
| if (!this.$eventBus.$consoleWindow.closed) { |
| this.$eventBus.$consoleWindow.focus(); |
| return; |
| } else { |
| this.openNewWindow(); |
| } |
| } else { |
| // If consoleWindow is null, open new window |
| this.openNewWindow(); |
| } |
| }, |
| openNewWindow() { |
| this.$eventBus.$consoleWindow = window.open( |
| '#/console/kvm', |
| 'kvmConsoleWindow', |
| 'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=yes,width=700,height=550', |
| ); |
| }, |
| }, |
| }; |
| </script> |
| |
| <style lang="scss" scoped> |
| @import '@/assets/styles/bmc/helpers/_index.scss'; |
| @import '@/assets/styles/bootstrap/_helpers.scss'; |
| |
| .button-ctrl-alt-delete { |
| float: right; |
| } |
| |
| .kvm-status { |
| padding-top: $spacer / 2; |
| padding-left: $spacer / 4; |
| display: inline-block; |
| } |
| |
| .margin-left-full-window { |
| margin-left: 5px; |
| } |
| </style> |