blob: 62dd47ad1329cccb367420e33138d5de5b0acb90 [file] [log] [blame]
<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';
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 {
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 this.$t('pageKvm.connected');
} else if (this.status === Disconnected) {
return this.$t('pageKvm.disconnected');
}
return this.$t('pageKvm.connecting');
},
},
created() {
this.$store.dispatch('global/getSystemInfo');
},
mounted() {
this.openTerminal();
},
beforeDestroy() {
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 scoped lang="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>