1<template> 2 <div :class="marginClass"> 3 <div ref="toolbar" class="kvm-toolbar"> 4 <b-row class="d-flex"> 5 <b-col class="d-flex flex-column justify-content-end" cols="4"> 6 <dl class="mb-2" sm="2" md="2"> 7 <dt class="d-inline font-weight-bold mr-1"> 8 {{ $t('pageKvm.status') }}: 9 </dt> 10 <dd class="d-inline"> 11 <status-icon :status="serverStatusIcon" /> 12 <span class="d-none d-md-inline"> {{ serverStatus }}</span> 13 </dd> 14 </dl> 15 </b-col> 16 17 <b-col class="d-flex justify-content-end pr-1"> 18 <b-button 19 v-if="isConnected" 20 variant="link" 21 type="button" 22 @click="sendCtrlAltDel" 23 > 24 <icon-arrow-down /> 25 {{ $t('pageKvm.buttonCtrlAltDelete') }} 26 </b-button> 27 <b-button 28 v-if="!isFullWindow" 29 variant="link" 30 type="button" 31 @click="openConsoleWindow()" 32 > 33 <icon-launch /> 34 {{ $t('pageKvm.openNewTab') }} 35 </b-button> 36 </b-col> 37 </b-row> 38 </div> 39 <div id="terminal-kvm" ref="panel" :class="terminalClass"></div> 40 </div> 41</template> 42 43<script> 44import RFB from '@novnc/novnc/core/rfb'; 45import StatusIcon from '@/components/Global/StatusIcon'; 46import IconLaunch from '@carbon/icons-vue/es/launch/20'; 47import IconArrowDown from '@carbon/icons-vue/es/arrow--down/16'; 48import { throttle } from 'lodash'; 49 50const Connecting = 0; 51const Connected = 1; 52const Disconnected = 2; 53 54export default { 55 name: 'KvmConsole', 56 components: { StatusIcon, IconLaunch, IconArrowDown }, 57 props: { 58 isFullWindow: { 59 type: Boolean, 60 default: true, 61 }, 62 }, 63 data() { 64 return { 65 rfb: null, 66 isConnected: false, 67 terminalClass: this.isFullWindow ? 'full-window' : '', 68 marginClass: this.isFullWindow ? 'margin-left-full-window' : '', 69 status: Connecting, 70 convasRef: null, 71 resizeKvmWindow: null, 72 }; 73 }, 74 computed: { 75 serverStatusIcon() { 76 if (this.status === Connected) { 77 return 'success'; 78 } else if (this.status === Disconnected) { 79 return 'danger'; 80 } 81 return 'secondary'; 82 }, 83 serverStatus() { 84 if (this.status === Connected) { 85 return this.$t('pageKvm.connected'); 86 } else if (this.status === Disconnected) { 87 return this.$t('pageKvm.disconnected'); 88 } 89 return this.$t('pageKvm.connecting'); 90 }, 91 }, 92 created() { 93 this.$store.dispatch('global/getSystemInfo'); 94 }, 95 mounted() { 96 this.openTerminal(); 97 }, 98 beforeDestroy() { 99 window.removeEventListener('resize', this.resizeKvmWindow); 100 this.closeTerminal(); 101 }, 102 methods: { 103 sendCtrlAltDel() { 104 this.rfb.sendCtrlAltDel(); 105 }, 106 closeTerminal() { 107 this.rfb.disconnect(); 108 this.rfb = null; 109 }, 110 openTerminal() { 111 const token = this.$store.getters['authentication/token']; 112 this.rfb = new RFB( 113 this.$refs.panel, 114 `wss://${window.location.host}/kvm/0`, 115 { wsProtocols: [token] }, 116 ); 117 118 this.rfb.scaleViewport = true; 119 this.rfb.clipViewport = true; 120 const that = this; 121 122 this.resizeKvmWindow = throttle(() => { 123 setTimeout(that.setWidthToolbar, 0); 124 }, 1000); 125 window.addEventListener('resize', this.resizeKvmWindow); 126 127 this.rfb.addEventListener('connect', () => { 128 that.isConnected = true; 129 that.status = Connected; 130 that.setWidthToolbar(); 131 }); 132 133 this.rfb.addEventListener('disconnect', () => { 134 this.isConnected = false; 135 that.status = Disconnected; 136 }); 137 }, 138 setWidthToolbar() { 139 if ( 140 this.$refs.panel.children && 141 this.$refs.panel.children.length > 0 && 142 this.$refs.panel.children[0].children.length > 0 143 ) { 144 this.$refs.toolbar.style.width = 145 this.$refs.panel.children[0].children[0].clientWidth - 10 + 'px'; 146 } 147 }, 148 openConsoleWindow() { 149 // If consoleWindow is not null 150 // Check the newly opened window is closed or not 151 if (this.$eventBus.$consoleWindow) { 152 // If window is not closed set focus to new window 153 // If window is closed, do open new window 154 if (!this.$eventBus.$consoleWindow.closed) { 155 this.$eventBus.$consoleWindow.focus(); 156 return; 157 } else { 158 this.openNewWindow(); 159 } 160 } else { 161 // If consoleWindow is null, open new window 162 this.openNewWindow(); 163 } 164 }, 165 openNewWindow() { 166 this.$eventBus.$consoleWindow = window.open( 167 '#/console/kvm', 168 'kvmConsoleWindow', 169 'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=yes,width=700,height=550', 170 ); 171 }, 172 }, 173}; 174</script> 175 176<style scoped lang="scss"> 177.button-ctrl-alt-delete { 178 float: right; 179} 180 181.kvm-status { 182 padding-top: $spacer / 2; 183 padding-left: $spacer / 4; 184 display: inline-block; 185} 186 187.margin-left-full-window { 188 margin-left: 5px; 189} 190</style> 191