mirror of https://github.com/rancher/ui.git
Merge pull request #1079 from loganhz/master
upgrade xterm and make container shell larger
This commit is contained in:
commit
6fbca89320
|
|
@ -1,22 +1,50 @@
|
|||
import Ember from 'ember';
|
||||
import { alternateLabel } from 'ui/utils/platform';
|
||||
import ThrottledResize from 'ui/mixins/throttled-resize';
|
||||
import Terminal from 'npm:xterm';
|
||||
import { proposeGeometry } from 'ui/utils/xterm-fit-addon';
|
||||
|
||||
const DEFAULT_COMMAND = ["/bin/sh","-c",'TERM=xterm-256color; export TERM; [ -x /bin/bash ] && ([ -x /usr/bin/script ] && /usr/bin/script -q -c "/bin/bash" /dev/null || exec /bin/bash) || exec /bin/sh'];
|
||||
|
||||
export default Ember.Component.extend({
|
||||
export default Ember.Component.extend(ThrottledResize, {
|
||||
instance: null,
|
||||
command: null,
|
||||
cols: 80,
|
||||
rows: 24,
|
||||
alternateLabel: alternateLabel,
|
||||
showProtip: true,
|
||||
contenteditable: false,
|
||||
|
||||
status: 'connecting',
|
||||
error: null,
|
||||
socket: null,
|
||||
term: null,
|
||||
|
||||
actions: {
|
||||
contextMenuHandler() {
|
||||
// fix for no paste button in firefox context menu on Windows
|
||||
this.set('contenteditable', true);
|
||||
setTimeout(()=> {
|
||||
this.set('contenteditable', false);
|
||||
}, 20);
|
||||
}
|
||||
},
|
||||
|
||||
fit() {
|
||||
var term = this.get('term');
|
||||
var socket = this.get('socket');
|
||||
if (term && socket)
|
||||
{
|
||||
var geometry = proposeGeometry(term);
|
||||
socket.send(`:resizeTTY:${geometry.cols},${geometry.rows}`);
|
||||
term.resize(geometry.cols, geometry.rows);
|
||||
}
|
||||
},
|
||||
|
||||
onResize: function () {
|
||||
this.fit();
|
||||
},
|
||||
|
||||
didInsertElement: function() {
|
||||
this._super();
|
||||
Ember.run.next(this, 'exec');
|
||||
|
|
@ -53,8 +81,6 @@ export default Ember.Component.extend({
|
|||
this.set('status','initializing');
|
||||
|
||||
var term = new Terminal({
|
||||
cols: this.get('cols'),
|
||||
rows: this.get('rows'),
|
||||
useStyle: true,
|
||||
screenKeys: true,
|
||||
cursorBlink: false
|
||||
|
|
@ -67,7 +93,7 @@ export default Ember.Component.extend({
|
|||
});
|
||||
|
||||
term.open(this.$('.shell-body')[0]);
|
||||
|
||||
this.fit();
|
||||
socket.onmessage = (message) => {
|
||||
this.set('status','connected');
|
||||
this.sendAction('connected');
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<hr>
|
||||
{{/if}}
|
||||
<h2 class='mb-10'><i class="icon icon-terminal"></i> {{t 'modalShell.title' instanceName=instance.displayName}}</h2>
|
||||
<div class="shell-body">
|
||||
<div class="shell-body" contenteditable="{{contenteditable}}" oncontextmenu={{action "contextMenuHandler"}}>
|
||||
</div>
|
||||
<div class="footer-actions">
|
||||
<div class="console-status text-muted">{{t (concat-str 'containerShell.status' status character='.') error=error}}</div>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import Ember from 'ember';
|
|||
import ModalBase from 'ui/mixins/modal-base';
|
||||
|
||||
export default Ember.Component.extend(ModalBase, {
|
||||
classNames: ['modal-container', 'large-modal', 'modal-shell'],
|
||||
classNames: ['modal-container', 'large-modal', 'fullscreen-modal', 'modal-shell'],
|
||||
originalModel: Ember.computed.alias('modalService.modalOpts.model'),
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,5 @@
|
|||
dismiss=(action "cancel")
|
||||
disconncted=(action "cancel")
|
||||
}}
|
||||
<button {{action "cancel"}} class="btn bg-primary">{{t 'consolePage.closeButton'}}</button>
|
||||
{{/container-shell}}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ var Container = Instance.extend({
|
|||
let proj = this.get('projects.current.id');
|
||||
let id = this.get('id');
|
||||
Ember.run.later(() => {
|
||||
window.open(`//${window.location.host}/env/${proj}/infra/console?instanceId=${id}&isPopup=true`, '_blank', "toolbars=0,width=717,height=590,left=200,top=200");
|
||||
window.open(`//${window.location.host}/env/${proj}/infra/console?instanceId=${id}&isPopup=true`, '_blank', "toolbars=0,width=900,height=700,left=200,top=200");
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,28 @@
|
|||
.shell-body {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
height: calc(100vh - 260px);
|
||||
margin: 0 auto;
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.terminal {
|
||||
margin: 0 auto;
|
||||
font-size: 12px;
|
||||
font-family: "Lucida Console", Monaco, "Courier New", monospace;
|
||||
}
|
||||
.shell-body .terminal {
|
||||
margin: 0 auto;
|
||||
font-size: 12px;
|
||||
font-family: "Lucida Console", Monaco, "Courier New", monospace;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.fullscreen-modal {
|
||||
max-width: none !important;
|
||||
}
|
||||
|
||||
.terminal .xterm-viewport {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.shell-popup .shell-body{
|
||||
height: calc(100vh - 100px);
|
||||
}
|
||||
|
||||
.shell-status {
|
||||
|
|
@ -14,7 +31,11 @@
|
|||
}
|
||||
|
||||
.shell-popup {
|
||||
padding: 20px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.shell-popup .footer-actions {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.xterm-rows {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
export function proposeGeometry(term) {
|
||||
if (!term.element.parentElement) {
|
||||
return null;
|
||||
}
|
||||
var parentElementStyle = window.getComputedStyle(term.element.parentElement),
|
||||
parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height')),
|
||||
parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')) - 17),
|
||||
elementStyle = window.getComputedStyle(term.element),
|
||||
elementPaddingVer = parseInt(elementStyle.getPropertyValue('padding-top')) + parseInt(elementStyle.getPropertyValue('padding-bottom')),
|
||||
elementPaddingHor = parseInt(elementStyle.getPropertyValue('padding-right')) + parseInt(elementStyle.getPropertyValue('padding-left')),
|
||||
availableHeight = parentElementHeight - elementPaddingVer,
|
||||
availableWidth = parentElementWidth - elementPaddingHor,
|
||||
subjectRow = term.rowContainer.firstElementChild,
|
||||
contentBuffer = subjectRow.innerHTML,
|
||||
characterHeight,
|
||||
rows,
|
||||
characterWidth,
|
||||
cols,
|
||||
geometry;
|
||||
|
||||
subjectRow.style.display = 'inline';
|
||||
subjectRow.innerHTML = 'W'; // Common character for measuring width, although on monospace
|
||||
characterWidth = subjectRow.getBoundingClientRect().width;
|
||||
subjectRow.style.display = ''; // Revert style before calculating height, since they differ.
|
||||
characterHeight = parseInt(subjectRow.offsetHeight);
|
||||
subjectRow.innerHTML = contentBuffer;
|
||||
|
||||
rows = Math.floor(availableHeight / characterHeight);
|
||||
cols = Math.floor(availableWidth / characterWidth);
|
||||
|
||||
geometry = { cols: cols, rows: rows };
|
||||
return geometry;
|
||||
}
|
||||
|
|
@ -36,7 +36,7 @@ module.exports = function(defaults) {
|
|||
},
|
||||
nodeAssets: {
|
||||
'xterm': {
|
||||
import: ['src/xterm.css']
|
||||
import: ['dist/xterm.css']
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@
|
|||
"postcss-scss": "^0.4.0",
|
||||
"semver": "^5.3.0",
|
||||
"shell-quote": "^1.4.3",
|
||||
"xterm": "1.0.0",
|
||||
"xterm": "2.4.0",
|
||||
"yamljs": "^0.2.7"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
|
|||
Loading…
Reference in New Issue