1<template> 2 <div :class="isFullWindow ? 'full-window-container' : 'terminal-container'"> 3 <b-row class="d-flex"> 4 <b-col sm="4" md="6"> 5 <alert 6 v-if="connection ? false : true" 7 variant="warning" 8 :small="true" 9 class="mt-4" 10 > 11 <p class="col-form-label"> 12 {{ $t('pageSerialOverLan.alert.disconnectedAlertMessage') }} 13 </p> 14 </alert> 15 </b-col> 16 </b-row> 17 <b-row class="d-flex"> 18 <b-col class="d-flex flex-column justify-content-end"> 19 <dl class="mb-2" sm="6" md="6"> 20 <dt class="d-inline font-weight-bold mr-1"> 21 {{ $t('pageSerialOverLan.status') }}: 22 </dt> 23 <dd class="d-inline"> 24 <status-icon :status="serverStatusIcon" /> 25 {{ 26 connection 27 ? $t('pageSerialOverLan.connected') 28 : $t('pageSerialOverLan.disconnected') 29 }} 30 </dd> 31 </dl> 32 </b-col> 33 34 <b-col v-if="!isFullWindow" class="d-flex justify-content-end"> 35 <b-button variant="link" type="button" @click="openConsoleWindow()"> 36 <icon-launch /> 37 {{ $t('pageSerialOverLan.openNewTab') }} 38 </b-button> 39 </b-col> 40 </b-row> 41 <div id="terminal" ref="panel"></div> 42 </div> 43</template> 44 45<script> 46import Alert from '@/components/Global/Alert'; 47import { AttachAddon } from 'xterm-addon-attach'; 48import { FitAddon } from 'xterm-addon-fit'; 49import { Terminal } from 'xterm'; 50import { throttle } from 'lodash'; 51import IconLaunch from '@carbon/icons-vue/es/launch/20'; 52import StatusIcon from '@/components/Global/StatusIcon'; 53import { useI18n } from 'vue-i18n'; 54 55export default { 56 name: 'SerialOverLanConsole', 57 components: { 58 Alert, 59 IconLaunch, 60 StatusIcon, 61 }, 62 props: { 63 isFullWindow: { 64 type: Boolean, 65 default: true, 66 }, 67 }, 68 data() { 69 return { 70 $t: useI18n().t, 71 resizeConsoleWindow: null, 72 }; 73 }, 74 computed: { 75 serverStatus() { 76 return this.$store.getters['global/serverStatus']; 77 }, 78 connection() { 79 return this.serverStatus === 'off' ? false : true; 80 }, 81 serverStatusIcon() { 82 return this.connection ? 'success' : 'danger'; 83 }, 84 }, 85 created() { 86 this.$store.dispatch('global/getSystemInfo'); 87 }, 88 mounted() { 89 this.openTerminal(); 90 }, 91 beforeUnmount() { 92 window.removeEventListener('resize', this.resizeConsoleWindow); 93 this.closeTerminal(); 94 }, 95 methods: { 96 openTerminal() { 97 const token = this.$store.getters['authentication/token']; 98 this.ws = new WebSocket(`wss://${window.location.host}/console/default`, [ 99 token, 100 ]); 101 102 // Refer https://github.com/xtermjs/xterm.js/ for xterm implementation and addons. 103 104 this.term = new Terminal({ 105 fontSize: 15, 106 fontFamily: 107 'SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace', 108 }); 109 110 const attachAddon = new AttachAddon(this.ws); 111 this.term.loadAddon(attachAddon); 112 113 const fitAddon = new FitAddon(); 114 this.term.loadAddon(fitAddon); 115 116 const SOL_THEME = { 117 background: '#19273c', 118 cursor: 'rgba(83, 146, 255, .5)', 119 scrollbar: 'rgba(83, 146, 255, .5)', 120 }; 121 this.term.setOption('theme', SOL_THEME); 122 123 this.term.open(this.$refs.panel); 124 fitAddon.fit(); 125 126 this.resizeConsoleWindow = throttle(() => { 127 fitAddon.fit(); 128 }, 1000); 129 window.addEventListener('resize', this.resizeConsoleWindow); 130 131 try { 132 this.ws.onopen = function () { 133 console.log('websocket console/default opened'); 134 }; 135 this.ws.onclose = function (event) { 136 console.log( 137 'websocket console/default closed. code: ' + 138 event.code + 139 ' reason: ' + 140 event.reason, 141 ); 142 }; 143 } catch (error) { 144 console.log(error); 145 } 146 }, 147 closeTerminal() { 148 console.log('closeTerminal'); 149 this.term.dispose(); 150 this.term = null; 151 this.ws.close(); 152 this.ws = null; 153 }, 154 openConsoleWindow() { 155 window.open( 156 '#/console/serial-over-lan-console', 157 '_blank', 158 'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=yes,width=600,height=550', 159 ); 160 }, 161 }, 162}; 163</script> 164 165<style lang="scss" scoped> 166@import '~xterm/css/xterm.css'; 167 168#terminal { 169 overflow: auto; 170} 171 172.full-window-container { 173 width: 97%; 174 margin: 1.5%; 175} 176</style> 177