blob: 0c545d0f2b007ef86afc91e34a8696d68f2af039 [file] [log] [blame]
Mateusz Gapski632de222020-07-09 09:21:33 +02001<template>
Mateusz Gapski96b37af2020-09-04 14:11:55 +02002 <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="hostStatusIcon" />
12 <span class="d-none d-md-inline"> {{ hostStatus }}</span>
13 </dd>
14 </dl>
15 </b-col>
16
Dixsie Wolmers30f11f82020-11-10 16:07:56 -060017 <b-col class="d-flex justify-content-end pr-1">
Mateusz Gapski96b37af2020-09-04 14:11:55 +020018 <b-button
19 v-if="isConnected"
20 variant="link"
21 type="button"
Mateusz Gapski96b37af2020-09-04 14:11:55 +020022 @click="sendCtrlAltDel"
23 >
Dixsie Wolmers30f11f82020-11-10 16:07:56 -060024 <icon-arrow-down />
Mateusz Gapski96b37af2020-09-04 14:11:55 +020025 {{ $t('pageKvm.buttonCtrlAltDelete') }}
26 </b-button>
27 <b-button
28 v-if="!isFullWindow"
29 variant="link"
30 type="button"
Mateusz Gapski96b37af2020-09-04 14:11:55 +020031 @click="openConsoleWindow()"
32 >
Dixsie Wolmers30f11f82020-11-10 16:07:56 -060033 <icon-launch />
34 {{ $t('pageKvm.openNewTab') }}
Mateusz Gapski96b37af2020-09-04 14:11:55 +020035 </b-button>
36 </b-col>
37 </b-row>
38 </div>
39 <div id="terminal-kvm" ref="panel" :class="terminalClass"></div>
Mateusz Gapski632de222020-07-09 09:21:33 +020040 </div>
41</template>
42
43<script>
44import RFB from '@novnc/novnc/core/rfb';
Mateusz Gapski96b37af2020-09-04 14:11:55 +020045import StatusIcon from '@/components/Global/StatusIcon';
46import IconLaunch from '@carbon/icons-vue/es/launch/20';
47import IconArrowDown from '@carbon/icons-vue/es/arrow--down/16';
48
49const Connecting = 0;
50const Connected = 1;
51const Disconnected = 2;
Mateusz Gapski632de222020-07-09 09:21:33 +020052
53export default {
54 name: 'KvmConsole',
Mateusz Gapski96b37af2020-09-04 14:11:55 +020055 components: { StatusIcon, IconLaunch, IconArrowDown },
56 props: {
57 isFullWindow: {
58 type: Boolean,
Derick Montague602e98a2020-10-21 16:20:00 -050059 default: true,
60 },
Mateusz Gapski96b37af2020-09-04 14:11:55 +020061 },
Mateusz Gapski632de222020-07-09 09:21:33 +020062 data() {
63 return {
64 rfb: null,
65 isConnected: false,
Mateusz Gapski96b37af2020-09-04 14:11:55 +020066 terminalClass: this.isFullWindow ? 'full-window' : '',
67 marginClass: this.isFullWindow ? 'margin-left-full-window' : '',
68 status: Connecting,
Derick Montague602e98a2020-10-21 16:20:00 -050069 convasRef: null,
Mateusz Gapski632de222020-07-09 09:21:33 +020070 };
71 },
Mateusz Gapski96b37af2020-09-04 14:11:55 +020072 computed: {
73 hostStatusIcon() {
74 if (this.status === Connected) {
75 return 'success';
76 } else if (this.status === Disconnected) {
77 return 'danger';
78 }
79 return 'secondary';
80 },
81 hostStatus() {
82 if (this.status === Connected) {
83 return this.$t('pageKvm.connected');
84 } else if (this.status === Disconnected) {
85 return this.$t('pageKvm.disconnected');
86 }
87 return this.$t('pageKvm.connecting');
Derick Montague602e98a2020-10-21 16:20:00 -050088 },
Mateusz Gapski96b37af2020-09-04 14:11:55 +020089 },
Mateusz Gapski632de222020-07-09 09:21:33 +020090 mounted() {
91 this.openTerminal();
92 },
93 methods: {
94 sendCtrlAltDel() {
95 this.rfb.sendCtrlAltDel();
96 },
97 openTerminal() {
98 const token = this.$store.getters['authentication/token'];
99 this.rfb = new RFB(
100 this.$refs.panel,
101 `wss://${window.location.host}/kvm/0`,
102 { wsProtocols: [token] }
103 );
104
105 this.rfb.scaleViewport = true;
Mateusz Gapski96b37af2020-09-04 14:11:55 +0200106 this.rfb.clipViewport = true;
Mateusz Gapski632de222020-07-09 09:21:33 +0200107 const that = this;
Mateusz Gapski96b37af2020-09-04 14:11:55 +0200108
109 window.addEventListener('resize', () => {
110 setTimeout(that.setWidthToolbar, 0);
111 });
112
Mateusz Gapski632de222020-07-09 09:21:33 +0200113 this.rfb.addEventListener('connect', () => {
114 that.isConnected = true;
Mateusz Gapski96b37af2020-09-04 14:11:55 +0200115 that.status = Connected;
116 that.setWidthToolbar();
Mateusz Gapski632de222020-07-09 09:21:33 +0200117 });
118
119 this.rfb.addEventListener('disconnect', () => {
Mateusz Gapski96b37af2020-09-04 14:11:55 +0200120 this.isConnected = false;
121 that.status = Disconnected;
Mateusz Gapski632de222020-07-09 09:21:33 +0200122 });
Mateusz Gapski96b37af2020-09-04 14:11:55 +0200123 },
124 setWidthToolbar() {
125 if (
126 this.$refs.panel.children &&
127 this.$refs.panel.children.length > 0 &&
128 this.$refs.panel.children[0].children.length > 0
129 ) {
130 this.$refs.toolbar.style.width =
131 this.$refs.panel.children[0].children[0].clientWidth - 10 + 'px';
132 }
133 },
134 openConsoleWindow() {
135 window.open(
136 '#/console/kvm',
137 '_blank',
138 'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=yes,width=700,height=550'
139 );
Derick Montague602e98a2020-10-21 16:20:00 -0500140 },
141 },
Mateusz Gapski632de222020-07-09 09:21:33 +0200142};
143</script>
144
145<style scoped lang="scss">
Mateusz Gapski632de222020-07-09 09:21:33 +0200146.button-ctrl-alt-delete {
147 float: right;
148}
149
150.kvm-status {
151 padding-top: $spacer / 2;
152 padding-left: $spacer / 4;
153 display: inline-block;
154}
Mateusz Gapski96b37af2020-09-04 14:11:55 +0200155
156.margin-left-full-window {
157 margin-left: 5px;
158}
Mateusz Gapski632de222020-07-09 09:21:33 +0200159</style>