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'; 53 54export default { 55 name: 'SerialOverLanConsole', 56 components: { 57 Alert, 58 IconLaunch, 59 StatusIcon, 60 }, 61 props: { 62 isFullWindow: { 63 type: Boolean, 64 default: true, 65 }, 66 }, 67 data() { 68 return { 69 resizeConsoleWindow: null, 70 }; 71 }, 72 computed: { 73 serverStatus() { 74 return this.$store.getters['global/serverStatus']; 75 }, 76 connection() { 77 return this.serverStatus === 'off' ? false : true; 78 }, 79 serverStatusIcon() { 80 return this.connection ? 'success' : 'danger'; 81 }, 82 }, 83 created() { 84 this.$store.dispatch('global/getSystemInfo'); 85 }, 86 mounted() { 87 this.openTerminal(); 88 }, 89 beforeDestroy() { 90 window.removeEventListener('resize', this.resizeConsoleWindow); 91 this.closeTerminal(); 92 }, 93 methods: { 94 openTerminal() { 95 const token = this.$store.getters['authentication/token']; 96 97 this.ws = new WebSocket(`wss://${window.location.host}/console0`, [ 98 token, 99 ]); 100 101 // Refer https://github.com/xtermjs/xterm.js/ for xterm implementation and addons. 102 103 this.term = new Terminal({ 104 fontSize: 15, 105 fontFamily: 106 'SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace', 107 }); 108 109 const attachAddon = new AttachAddon(this.ws); 110 this.term.loadAddon(attachAddon); 111 112 const fitAddon = new FitAddon(); 113 this.term.loadAddon(fitAddon); 114 115 const SOL_THEME = { 116 background: '#19273c', 117 cursor: 'rgba(83, 146, 255, .5)', 118 scrollbar: 'rgba(83, 146, 255, .5)', 119 }; 120 this.term.setOption('theme', SOL_THEME); 121 122 this.term.open(this.$refs.panel); 123 fitAddon.fit(); 124 125 this.resizeConsoleWindow = throttle(() => { 126 fitAddon.fit(); 127 }, 1000); 128 window.addEventListener('resize', this.resizeConsoleWindow); 129 130 try { 131 this.ws.onopen = function () { 132 console.log('websocket console0/ opened'); 133 }; 134 this.ws.onclose = function (event) { 135 console.log( 136 'websocket console0/ closed. code: ' + 137 event.code + 138 ' reason: ' + 139 event.reason 140 ); 141 }; 142 } catch (error) { 143 console.log(error); 144 } 145 }, 146 closeTerminal() { 147 console.log('closeTerminal'); 148 this.term.dispose(); 149 this.term = null; 150 this.ws.close(); 151 this.ws = null; 152 }, 153 openConsoleWindow() { 154 window.open( 155 '#/console/serial-over-lan-console', 156 '_blank', 157 'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=yes,width=600,height=550' 158 ); 159 }, 160 }, 161}; 162</script> 163 164<style lang="scss" scoped> 165@import '~xterm/css/xterm.css'; 166 167#terminal { 168 overflow: auto; 169} 170 171.full-window-container { 172 width: 97%; 173 margin: 1.5%; 174} 175</style> 176