mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-23 22:50:09 +03:00
Co-authored-by: Tino Vázquez <cvazquez@opennebula.io> (cherry picked from commit 6cfc15a4c09505b78efc0624a6e427383d2986ea)
This commit is contained in:
parent
1b58d80838
commit
506a1eea65
@ -2612,7 +2612,6 @@ SUNSTONE_PUBLIC_IMAGES_FILES="src/sunstone/public/images/ajax-loader.gif \
|
||||
src/sunstone/public/images/opennebula-5.0.png \
|
||||
src/sunstone/public/images/opennebula-sunstone-v4.0.png \
|
||||
src/sunstone/public/images/opennebula-sunstone-v4.14-small.png \
|
||||
src/sunstone/public/images/one_small_logo.png \
|
||||
src/sunstone/public/images/panel.png \
|
||||
src/sunstone/public/images/panel_short.png \
|
||||
src/sunstone/public/images/pbar.gif \
|
||||
|
@ -15,24 +15,57 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
define(function(require) {
|
||||
require("jquery-ui");
|
||||
|
||||
var GuacController = require('utils/guacamole/controller');
|
||||
|
||||
try {
|
||||
var endpoint = new URL(window.location.href);
|
||||
var encoded_socket = endpoint.searchParams.get("socket");
|
||||
var socket_string = atob(encoded_socket);
|
||||
|
||||
var url = new URL(socket_string);
|
||||
var params = url.searchParams;
|
||||
var token = params.get("token");
|
||||
var info = params.get("info");
|
||||
|
||||
var controller = new GuacController();
|
||||
controller.setInformation(info);
|
||||
controller.setConnection(token);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
$('#guacamole-state').empty().text('Failed');
|
||||
var controller = new GuacController();
|
||||
var reconnectButton = document.getElementById('buttons__reconnect');
|
||||
|
||||
var endpoint = new URL(window.location.href);
|
||||
var encoded_socket = endpoint.searchParams.get("socket");
|
||||
var socket_string = atob(encoded_socket);
|
||||
|
||||
var url = new URL(socket_string);
|
||||
var params = url.searchParams;
|
||||
var token = params.get("token");
|
||||
var connectionType = params.get("type");
|
||||
var info = params.get("info");
|
||||
|
||||
controller.setInformation(info);
|
||||
|
||||
// Trigger first connect
|
||||
document.readyState !== 'loading'
|
||||
? connect()
|
||||
: document.addEventListener('DOMContentLoaded', connect);
|
||||
|
||||
window.onunload = disconnect;
|
||||
|
||||
|
||||
reconnectButton.onclick = function reconnect() {
|
||||
disconnect();
|
||||
|
||||
document.querySelector('.toolbar__state h5').innerHTML = "";
|
||||
document.querySelector('.toolbar__state .spinner').style.display = "block";
|
||||
|
||||
setTimeout(connect, 500)
|
||||
}
|
||||
|
||||
function connect() {
|
||||
try {
|
||||
controller && controller.setConnection(token, connectionType);
|
||||
} catch (error) {
|
||||
controller && controller.disconnect();
|
||||
document.querySelector('.toolbar__state h5').innerHTML = "Failed";
|
||||
}
|
||||
}
|
||||
|
||||
function disconnect() {
|
||||
try {
|
||||
controller && controller.disconnect();
|
||||
} catch (error) {
|
||||
document.querySelector('.toolbar__state h5').innerHTML = "Failed";
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -172,14 +172,14 @@ define(function(require) {
|
||||
}
|
||||
}
|
||||
},
|
||||
"logo": (_config["view"]["provision_logo"] || "images/one_small_logo.png"),
|
||||
"logo": (_config["view"]["provision_logo"] || "images/opennebula-5.0.png"),
|
||||
},
|
||||
|
||||
"tableOrder": _config["user_config"]["table_order"],
|
||||
"vncProxyPort": _config["system_config"]["vnc_client_port"] || _config["system_config"]["vnc_proxy_port"].split(":")[1] || _config["system_config"]["vnc_proxy_port"],
|
||||
"vncWSS": _config["user_config"]["vnc_wss"],
|
||||
"requestVNCPassword": _config["system_config"]["vnc_request_password"],
|
||||
"logo": (_config["view"]["small_logo"] || "images/one_small_logo.png"),
|
||||
"logo": (_config["view"]["small_logo"] || "images/opennebula-5.0.png"),
|
||||
"link_logo": (_config["view"]["link_logo"] || false),
|
||||
"text_link_logo": (_config["view"]["text_link_logo"] || false),
|
||||
"vmLogos": (_config["vm_logos"]),
|
||||
|
@ -371,10 +371,13 @@ define(function(require) {
|
||||
"VM.startguac_action" : {
|
||||
type: "single",
|
||||
call: OpenNebulaVM.guac,
|
||||
callback: function(_, response) {
|
||||
var link = RemoteActions.getLink(response, {
|
||||
callback: function(request, response) {
|
||||
var protocolConnection = request.request.data[0].extra_param;
|
||||
|
||||
var link = getLink(response, {
|
||||
connnection_type: 'guac',
|
||||
extra_path: '/fireedge/guacamole'
|
||||
extra_path: '/fireedge/guacamole',
|
||||
extra_params: ['type=' + protocolConnection]
|
||||
});
|
||||
// Open in a new tab the noVNC connection
|
||||
window.open(link);
|
||||
|
@ -16,53 +16,45 @@
|
||||
|
||||
define(function(require) {
|
||||
|
||||
require("guacamole-common-js")
|
||||
var ManagedClient = require("utils/guacamole/types/client");
|
||||
var ManagedClientState = require("utils/guacamole/types/client-state");
|
||||
var Utils = require("utils/guacamole/utils");
|
||||
var UtilsConnection = require("utils/info-connection/utils");
|
||||
require('guacamole-common-js')
|
||||
var ConnectionTypes = require('utils/guacamole/types/connection-types');
|
||||
var ManagedClient = require('utils/guacamole/types/client');
|
||||
var ManagedClientState = require('utils/guacamole/types/client-state');
|
||||
var Utils = require('utils/guacamole/utils');
|
||||
var UtilsConnection = require('utils/info-connection/utils');
|
||||
|
||||
var GuacButtons = require("utils/guacamole/directives/guacButtons");
|
||||
var GuacClipboard = require("utils/guacamole/directives/guacClipboard");
|
||||
var GuacKeyboard = require("utils/guacamole/directives/guacKeyboard");
|
||||
var GuacMouse = require("utils/guacamole/directives/guacMouse");
|
||||
var GuacOsk = require("utils/guacamole/directives/guacOsk");
|
||||
var GuacButtons = require('utils/guacamole/directives/guacButtons');
|
||||
var GuacClipboard = require('utils/guacamole/directives/guacClipboard');
|
||||
var GuacKeyboard = require('utils/guacamole/directives/guacKeyboard');
|
||||
var GuacMouse = require('utils/guacamole/directives/guacMouse');
|
||||
var GuacOsk = require('utils/guacamole/directives/guacOsk');
|
||||
|
||||
function GuacController() {
|
||||
var $guac = {};
|
||||
var $scope = {};
|
||||
var $elements = {
|
||||
main: document.getElementById('guacamole-main'),
|
||||
displayContainer: document.getElementById('guacamole-display'),
|
||||
main: document.querySelector('.wrapper__display'),
|
||||
displayContainer: document.getElementById('display'),
|
||||
osk: document.getElementById('osk'),
|
||||
closeOskButton: document.getElementById('osk-close'),
|
||||
closeOskButton: document.querySelector('.osk__header__buttons .close'),
|
||||
|
||||
/* Buttons */
|
||||
sendCtrlAltDelButton: document.getElementById('sendCtrlAltDelButton'),
|
||||
mouseButton: document.getElementById('mouseButton'),
|
||||
screenshotButton: document.getElementById('takeScreenshot'),
|
||||
oskButton: document.getElementById('oskButton'),
|
||||
sendCtrlAltDelButton: document.getElementById('buttons__sendctrlaltdel'),
|
||||
mouseButton: document.getElementById('buttons__mouse'),
|
||||
screenshotButton: document.getElementById('buttons__screenshot'),
|
||||
oskButton: document.getElementById('buttons__osk'),
|
||||
fullscreenButton: document.getElementById('buttons__fullscreen'),
|
||||
};
|
||||
|
||||
var throttleResizeFunction = Utils.throttle(containerResized, 250);
|
||||
window.addEventListener('resize', throttleResizeFunction);
|
||||
this.disconnect = disconnect;
|
||||
|
||||
this.disconnect = function() {
|
||||
if ($guac.client) $guac.client.disconnect();
|
||||
if ($guac.keyboard) GuacKeyboard.destroy();
|
||||
if ($guac.mouse) GuacMouse.destroy();
|
||||
if ($guac.osk) GuacOsk.destroy();
|
||||
this.setConnection = function(token, connectionType) {
|
||||
$scope.connectionType = String(connectionType).toUpperCase();
|
||||
|
||||
GuacButtons.destroy();
|
||||
GuacClipboard.destroy();
|
||||
window.removeEventListener('resize', throttleResizeFunction);
|
||||
$('#guacamole-state').text('');
|
||||
$scope.connectionType === ConnectionTypes.SSH
|
||||
? $elements.displayContainer.classList.add('ssh')
|
||||
: $elements.displayContainer.classList.remove('ssh');
|
||||
|
||||
$guac = {};
|
||||
$scope = {};
|
||||
}
|
||||
|
||||
this.setConnection = function(token) {
|
||||
var managedClient = ManagedClient.getInstance(token, undefined, $elements.displayContainer)
|
||||
|
||||
new GuacKeyboard($guac, $scope, $elements);
|
||||
@ -70,14 +62,16 @@ define(function(require) {
|
||||
new GuacOsk($guac, $scope, $elements);
|
||||
new GuacButtons($guac, $scope, $elements);
|
||||
new GuacClipboard($guac, $scope, $elements);
|
||||
window.addEventListener('resize', containerResized);
|
||||
document.addEventListener('fullscreenchange', containerResized)
|
||||
|
||||
// Remove any existing display
|
||||
$elements.displayContainer.innerHTML = "";
|
||||
$elements.displayContainer.innerHTML = '';
|
||||
|
||||
// Only proceed if a client is given
|
||||
if (!managedClient) return;
|
||||
$scope.client = managedClient;
|
||||
|
||||
|
||||
// Get Guacamole client instance
|
||||
$guac.client = managedClient.client;
|
||||
|
||||
@ -108,36 +102,40 @@ define(function(require) {
|
||||
}
|
||||
}).bind(this));
|
||||
|
||||
Utils.observe($scope, 'disableCursor', (function(disabled) {
|
||||
$elements.mouseButton.disabled = !!disabled;
|
||||
}).bind(this));
|
||||
|
||||
Utils.observe($scope.client.clientState, 'connectionState', (function(connectionState) {
|
||||
var isLoading = connectionState === ManagedClientState.ConnectionState.WAITING;
|
||||
|
||||
$('#guacamole-loading')[isLoading ? 'fadeIn' : 'fadeOut']('fast');
|
||||
$('#guacamole-state').text(connectionState).animate();
|
||||
}).bind(this));
|
||||
var isConnected = connectionState === ManagedClientState.ConnectionState.CONNECTED;
|
||||
var isDisconnected = connectionState === ManagedClientState.ConnectionState.DISCONNECTED;
|
||||
|
||||
Utils.observe($scope.client.clientProperties, 'scale', (function(scale) {
|
||||
scale = Math.max(scale, $scope.client.clientProperties.minScale);
|
||||
scale = Math.min(scale, $scope.client.clientProperties.maxScale);
|
||||
|
||||
// Apply scale if client attached
|
||||
if ($guac.display && scale !== 0) {
|
||||
$guac.display.scale(scale);
|
||||
$elements.displayContainer.style['min-height'] = $guac.display.getHeight() + "px";
|
||||
}
|
||||
isConnected && setTimeout(containerResized, 100);
|
||||
isDisconnected && disconnect();
|
||||
|
||||
if (scale !== $scope.client.clientProperties.scale) {
|
||||
$scope.client.clientProperties.scale = scale;
|
||||
}
|
||||
$('.spinner')[isLoading ? 'fadeIn' : 'fadeOut']('fast');
|
||||
$('.toolbar__state h5').text(connectionState).animate();
|
||||
}).bind(this));
|
||||
};
|
||||
|
||||
this.setInformation = function(information) {
|
||||
var info_decode = UtilsConnection.decodeInfoConnection(information);
|
||||
UtilsConnection.printInfoConnection($('.guacamole_info'), info_decode);
|
||||
UtilsConnection.printInfoConnection($('.information'), info_decode);
|
||||
}
|
||||
|
||||
function disconnect() {
|
||||
if ($guac.client) $guac.client.disconnect();
|
||||
if ($guac.keyboard) GuacKeyboard.destroy();
|
||||
if ($guac.mouse) GuacMouse.destroy();
|
||||
if ($guac.osk) GuacOsk.destroy();
|
||||
|
||||
GuacButtons.destroy();
|
||||
GuacClipboard.destroy();
|
||||
window.removeEventListener('resize', containerResized);
|
||||
document.removeEventListener('fullscreenchange', containerResized)
|
||||
|
||||
while($elements.displayContainer.firstChild)
|
||||
$elements.displayContainer.removeChild($elements.displayContainer.firstChild);
|
||||
|
||||
$guac = {};
|
||||
$scope = {};
|
||||
}
|
||||
|
||||
function containerResized() {
|
||||
@ -150,38 +148,37 @@ define(function(require) {
|
||||
if ($guac.display.getWidth() !== width || $guac.display.getHeight() !== height) {
|
||||
$guac.client.sendSize(width, height);
|
||||
}
|
||||
|
||||
if ($guac.osk) {
|
||||
var MAX_OSK_WIDTH = 1000;
|
||||
|
||||
$guac.osk.resize(Math.min(MAX_OSK_WIDTH, width));
|
||||
}
|
||||
// when type connection is SSH, display doesn't need scale
|
||||
$scope.connectionType !== ConnectionTypes.SSH && updateDisplayScale();
|
||||
}
|
||||
|
||||
updateDisplayScale();
|
||||
if ($guac.osk) {
|
||||
$guac.osk.resize(1000);
|
||||
}
|
||||
};
|
||||
|
||||
function updateDisplayScale() {
|
||||
if (!$guac.display) return;
|
||||
|
||||
// Calculate scale to fit screen
|
||||
$scope.client.clientProperties.minScale = Math.min(
|
||||
$elements.main.offsetWidth / Math.max($guac.display.getWidth(), 1),
|
||||
$elements.main.offsetHeight / Math.max($guac.display.getHeight(), 1)
|
||||
);
|
||||
// Get screen resolution.
|
||||
var origHeight = Math.max($guac.display.getHeight(), 1);
|
||||
var origWidth = Math.max($guac.display.getWidth(), 1);
|
||||
|
||||
var htmlWidth = window.innerWidth;
|
||||
var htmlHeight = window.innerHeight;
|
||||
|
||||
var xScale = htmlWidth / origWidth;
|
||||
var yScale = htmlHeight / origHeight;
|
||||
|
||||
// This is done to handle both X and Y axis
|
||||
var scale = Math.min(yScale, xScale);
|
||||
|
||||
// Calculate appropriate maximum zoom level
|
||||
$scope.client.clientProperties.maxScale = Math.max($scope.client.clientProperties.minScale, 3);
|
||||
// Limit to 1
|
||||
scale = Math.min(scale, 1);
|
||||
|
||||
// Clamp zoom level, maintain auto-fit
|
||||
if (
|
||||
$guac.display.getScale() < $scope.client.clientProperties.minScale ||
|
||||
$scope.client.clientProperties.autoFit
|
||||
) {
|
||||
$scope.client.clientProperties.scale = $scope.client.clientProperties.minScale;
|
||||
}
|
||||
else if ($guac.display.getScale() > $scope.client.clientProperties.maxScale) {
|
||||
$scope.client.clientProperties.scale = $scope.client.clientProperties.maxScale;
|
||||
if (scale !== 0) {
|
||||
$guac.display.scale(scale);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
define(function(require) {
|
||||
|
||||
var Files = require('utils/files');
|
||||
var ConnectionTypes = require("utils/guacamole/types/connection-types");
|
||||
|
||||
function GuacButtons($guac, $scope, $elements) {
|
||||
$elements.screenshotButton.onclick = function() {
|
||||
@ -45,7 +46,7 @@ define(function(require) {
|
||||
$elements.closeOskButton.onclick = function() {
|
||||
if (!$guac.client) return;
|
||||
|
||||
$('#osk-container').fadeToggle('fast');
|
||||
$('#osk__container').fadeToggle('fast');
|
||||
};
|
||||
|
||||
$elements.mouseButton.onclick = function() {
|
||||
@ -55,16 +56,25 @@ define(function(require) {
|
||||
$scope.localCursor = $elements.mouseButton.classList.contains('disabled');
|
||||
};
|
||||
|
||||
$elements.fullscreenButton.onclick = function() {
|
||||
// If the document is not in full screen mode make the video full screen
|
||||
if (!document.fullscreenElement && document.fullscreenEnabled) {
|
||||
$elements.main.requestFullscreen();
|
||||
} else if (document.exitFullscreen) {
|
||||
document.exitFullscreen();
|
||||
}
|
||||
};
|
||||
|
||||
GuacButtons.destroy = function() {
|
||||
// reset default state
|
||||
$('#osk-container').hide();
|
||||
$('#osk__container').hide();
|
||||
$elements.mouseButton.classList.remove('disabled');
|
||||
|
||||
$elements.sendCtrlAltDelButton =
|
||||
$elements.screenshotButton.onclick =
|
||||
$elements.mouseButton.onclick =
|
||||
$elements.oskButton.onclick =
|
||||
$elements.closeOskButton.onclick = null;
|
||||
$elements.sendCtrlAltDelButton.onclick =
|
||||
$elements.screenshotButton.onclick =
|
||||
$elements.mouseButton.onclick =
|
||||
$elements.oskButton.onclick =
|
||||
$elements.closeOskButton.onclick = null;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -30,9 +30,7 @@ define(function(require) {
|
||||
|
||||
// Forward mousemove events untouched
|
||||
mouse.onmousemove = function(mouseState) {
|
||||
mouseState.y = mouseState.y / $guac.display.getScale();
|
||||
mouseState.x = mouseState.x / $guac.display.getScale();
|
||||
handleMouseState(mouseState);
|
||||
handleMouseState(mouseState, true);
|
||||
}
|
||||
|
||||
// Hide software cursor when mouse leaves display
|
||||
@ -42,10 +40,15 @@ define(function(require) {
|
||||
$guac.display.showCursor(false);
|
||||
};
|
||||
|
||||
function handleMouseState(mouseState) {
|
||||
function handleMouseState(mouseState, scaleMouse = false) {
|
||||
// Do not attempt to handle mouse state changes if the client
|
||||
// or display are not yet available
|
||||
if (!$guac.client || !$guac.display) return;
|
||||
if (!$guac.client || !$guac.display || $scope.disabledMouse) return;
|
||||
|
||||
if (scaleMouse) {
|
||||
mouseState.y = mouseState.y / $guac.display.getScale();
|
||||
mouseState.x = mouseState.x / $guac.display.getScale();
|
||||
}
|
||||
|
||||
// Send mouse state, show cursor if necessary
|
||||
$guac.display.showCursor(!$scope.localCursor);
|
||||
|
@ -26,18 +26,21 @@ define(function(require) {
|
||||
loadLayouts();
|
||||
changeLayout(DEFAULT_LAYOUT);
|
||||
|
||||
// $('#osk-container').draggable();
|
||||
$('#osk__container').draggable({
|
||||
start: function() { $scope.disabledMouse = true; },
|
||||
stop: function() { $scope.disabledMouse = false; }
|
||||
});
|
||||
|
||||
function loadLayouts() {
|
||||
$('#osk-qwerty').empty();
|
||||
$('#select__qwerty').empty();
|
||||
|
||||
var enUsLayout = new Option(enUsQwerty.language, enUsQwerty.language);
|
||||
$('#osk-qwerty').append(enUsLayout);
|
||||
$('#select__qwerty').append(enUsLayout);
|
||||
|
||||
var esEsLayout = new Option(esEsQwerty.language, esEsQwerty.language);
|
||||
$('#osk-qwerty').append(esEsLayout);
|
||||
$('#select__qwerty').append(esEsLayout);
|
||||
|
||||
$('#osk-qwerty').off().on('change', function() {
|
||||
$('#select__qwerty').off().on('change', function() {
|
||||
changeLayout(this.value);
|
||||
})
|
||||
};
|
||||
|
@ -215,9 +215,15 @@ define(function(require) {
|
||||
function getConnectString(token, connectionParameters, display = window) {
|
||||
// Calculate optimal width/height for display
|
||||
var pixel_density = window.devicePixelRatio || 1;
|
||||
var optimal_width = display.innerWidth * pixel_density;
|
||||
var optimal_height = display.innerHeight * pixel_density;
|
||||
var optimal_dpi = pixel_density * 96;
|
||||
|
||||
var optimal_width = display instanceof Window
|
||||
? display.innerWidth * pixel_density
|
||||
: display.offsetWidth * pixel_density;
|
||||
|
||||
var optimal_height = display instanceof Window
|
||||
? display.innerHeight * pixel_density
|
||||
: display.offsetHeight * pixel_density;
|
||||
|
||||
// Build base connect string
|
||||
var connectString = [
|
||||
|
@ -0,0 +1,31 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2021, OpenNebula Project, OpenNebula Systems */
|
||||
/* */
|
||||
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
|
||||
/* not use this file except in compliance with the License. You may obtain */
|
||||
/* a copy of the License at */
|
||||
/* */
|
||||
/* http://www.apache.org/licenses/LICENSE-2.0 */
|
||||
/* */
|
||||
/* Unless required by applicable law or agreed to in writing, software */
|
||||
/* distributed under the License is distributed on an "AS IS" BASIS, */
|
||||
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
|
||||
/* See the License for the specific language governing permissions and */
|
||||
/* limitations under the License. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
define(function() {
|
||||
|
||||
/**
|
||||
* Valid connection type strings. Each type string represents a protocol.
|
||||
*/
|
||||
var ConnectionTypes = {
|
||||
SSH : "SSH",
|
||||
RDP : "RDP",
|
||||
VNC : "VNC",
|
||||
TELNET : "TELNET"
|
||||
}
|
||||
|
||||
return ConnectionTypes;
|
||||
|
||||
});
|
@ -1,87 +1,122 @@
|
||||
body {
|
||||
margin:0;
|
||||
padding:0;
|
||||
font-family: Helvetica;
|
||||
height:100%;
|
||||
}
|
||||
/*
|
||||
* CSS TABLE OF CONTENTS
|
||||
*
|
||||
* 1.0 - Globals
|
||||
* 2.0 - Header
|
||||
* 3.0 - Body
|
||||
* 3.1 - Guacamole display
|
||||
* 3.2 - Defaults classes by guacamole-common-js
|
||||
*/
|
||||
|
||||
/*** 1.0 - Globals ***/
|
||||
|
||||
html {
|
||||
height:100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.remote-buttons {
|
||||
white-space: nowrap;
|
||||
*, *:before, *:after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
.main {
|
||||
width: 100%;
|
||||
display: inline-flex;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
background-color: rgb(40, 40, 40);
|
||||
body {
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr;
|
||||
}
|
||||
|
||||
.guacamole-main{
|
||||
flex-grow: 1;
|
||||
h5 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.guacamole-status {
|
||||
text-align: center;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
/*** 2.0 - Header ***/
|
||||
|
||||
header {
|
||||
background: #f2f4f8;
|
||||
padding: 1em 1em 0.8em;
|
||||
box-shadow: 0px 2px 1px -1px rgb(0 0 0 / 20%),
|
||||
0px 1px 1px 0px rgb(0 0 0 / 14%), 0px 1px 3px 0px rgb(0 0 0 / 12%);
|
||||
}
|
||||
|
||||
.remote-logo{
|
||||
border-radius: 50%;
|
||||
background-color: #282828;
|
||||
padding: 0.4em;
|
||||
margin-right: 1em;
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
.header__wrapper {
|
||||
max-width: 1250px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.container{
|
||||
.toolbar {
|
||||
padding: 1em;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 2em;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.toolbar img {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.toolbar__state {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
gap: 1em;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.guacamole-state{
|
||||
white-space: nowrap;
|
||||
max-width: 20em;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
.toolbar__state img {
|
||||
width: 40px;
|
||||
background-color: #282828;
|
||||
border-radius: 50%;
|
||||
padding: 0.4em;
|
||||
}
|
||||
|
||||
.toolbar__buttons {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
/* left-align the status text on lower resolutions */
|
||||
@media screen and (max-width: 800px){
|
||||
.guacamole-status {
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
width: auto;
|
||||
float: left;
|
||||
@media (max-width: 768px) {
|
||||
.toolbar__state {
|
||||
justify-content: end;
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
.toolbar__buttons {
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.guacamole-main {
|
||||
width: 100%;
|
||||
height: fit-content;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
place-content: center;
|
||||
background-color: #282828;
|
||||
/*** 3.0 - Body ***/
|
||||
|
||||
main {
|
||||
background-color: #222431;
|
||||
}
|
||||
|
||||
.guacamole-main > div {
|
||||
main > div {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.guacamole-main .guacamole-display {
|
||||
/*** 3.1 - Guacamole display ***/
|
||||
|
||||
.wrapper__display {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
place-content: center;
|
||||
}
|
||||
|
||||
#display {
|
||||
overflow: hidden;
|
||||
cursor: none;
|
||||
}
|
||||
|
||||
.osk-container {
|
||||
#display.ssh {
|
||||
width: 100vw;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/*** 3.2 - Guacamole OSK ***/
|
||||
|
||||
.osk__container {
|
||||
z-index: 2;
|
||||
background: rgba(0, 0, 0, 0.59);
|
||||
position: absolute;
|
||||
@ -93,30 +128,24 @@ html {
|
||||
box-shadow: 0 0 20px #acacac;
|
||||
}
|
||||
|
||||
.osk-container-header {
|
||||
.osk__header {
|
||||
background: linear-gradient(to top, #ebebeb, #d5d5d5);
|
||||
color: #4d494d;
|
||||
font-size: 11pt;
|
||||
line-height: 20px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
height: 28px;
|
||||
|
||||
user-select: none;
|
||||
cursor: default;
|
||||
|
||||
border-top: 1px solid #f3f1f3;
|
||||
border-bottom: 1px solid #b1aeb1;
|
||||
border-top-left-radius: 6px;
|
||||
border-top-right-radius: 6px;
|
||||
|
||||
padding: 0.5em;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.osk-container-header .buttons {
|
||||
padding-left: 8px;
|
||||
padding-top: 3px;
|
||||
float: left;
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
.osk-container-header .buttons .close {
|
||||
.osk__header__buttons .close {
|
||||
background: #ff5c5c;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
@ -126,18 +155,17 @@ html {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.osk-container-header .layouts {
|
||||
padding-right: 8px;
|
||||
padding-top: 3px;
|
||||
float: right;
|
||||
line-height: 0;
|
||||
.osk__header select {
|
||||
width: auto;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/*** 3.2 Defaults classes by guacamole-common-js ***/
|
||||
|
||||
.guac-keyboard {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
|
||||
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
cursor: default;
|
||||
@ -159,20 +187,19 @@ html {
|
||||
}
|
||||
|
||||
.guac-keyboard .guac-keyboard-key {
|
||||
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
|
||||
background: #444;
|
||||
|
||||
border: 0.125em solid #666;
|
||||
-moz-border-radius: 0.25em;
|
||||
-moz-border-radius: 0.25em;
|
||||
-webkit-border-radius: 0.25em;
|
||||
-khtml-border-radius: 0.25em;
|
||||
border-radius: 0.25em;
|
||||
-khtml-border-radius: 0.25em;
|
||||
border-radius: 0.25em;
|
||||
|
||||
color: white;
|
||||
font-size: 40%;
|
||||
@ -180,11 +207,8 @@ html {
|
||||
text-align: center;
|
||||
white-space: pre;
|
||||
|
||||
text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.25),
|
||||
1px -1px 0 rgba(0, 0, 0, 0.25),
|
||||
-1px 1px 0 rgba(0, 0, 0, 0.25),
|
||||
-1px -1px 0 rgba(0, 0, 0, 0.25);
|
||||
|
||||
text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.25), 1px -1px 0 rgba(0, 0, 0, 0.25),
|
||||
-1px 1px 0 rgba(0, 0, 0, 0.25), -1px -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
.guac-keyboard .guac-keyboard-key:hover {
|
||||
@ -232,12 +256,12 @@ html {
|
||||
/* Active super */
|
||||
.guac-keyboard.guac-keyboard-modifier-super .guac-keyboard-key-super {
|
||||
background: #882;
|
||||
border-color: #DD4;
|
||||
border-color: #dd4;
|
||||
}
|
||||
|
||||
.guac-keyboard .guac-keyboard-key.guac-keyboard-pressed {
|
||||
background: #822;
|
||||
border-color: #D44;
|
||||
border-color: #d44;
|
||||
}
|
||||
|
||||
.guac-keyboard .guac-keyboard-group {
|
||||
@ -252,7 +276,6 @@ html {
|
||||
}
|
||||
|
||||
.guac-keyboard .guac-keyboard-group.guac-keyboard-main {
|
||||
|
||||
/* IE10 */
|
||||
display: -ms-flexbox;
|
||||
-ms-flex-align: stretch;
|
||||
@ -262,7 +285,7 @@ html {
|
||||
display: -moz-box;
|
||||
-moz-box-align: stretch;
|
||||
-moz-box-orient: horizontal;
|
||||
|
||||
|
||||
/* Ancient WebKit */
|
||||
display: -webkit-box;
|
||||
-webkit-box-align: stretch;
|
||||
@ -277,7 +300,6 @@ html {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
flex-direction: row;
|
||||
|
||||
}
|
||||
|
||||
.guac-keyboard .guac-keyboard-group.guac-keyboard-movement {
|
||||
@ -315,13 +337,11 @@ html {
|
||||
.guac-keyboard.guac-keyboard-modifier-alt-gr
|
||||
.guac-keyboard-key.guac-keyboard-uses-alt-gr
|
||||
.guac-keyboard-cap:not(.guac-keyboard-requires-alt-gr) {
|
||||
|
||||
display: none;
|
||||
|
||||
}
|
||||
|
||||
/* Fade out keys which do not use AltGr if AltGr is active */
|
||||
.guac-keyboard.guac-keyboard-modifier-alt-gr
|
||||
.guac-keyboard-key:not(.guac-keyboard-uses-alt-gr):not(.guac-keyboard-key-alt-gr) {
|
||||
.guac-keyboard-key:not(.guac-keyboard-uses-alt-gr):not(.guac-keyboard-key-alt-gr) {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,6 @@ $global-font-size: 13px;
|
||||
$global-width: rem-calc(1200);
|
||||
$global-lineheight: 1.5;
|
||||
$foundation-palette: (
|
||||
//primary: #2199e8,
|
||||
primary: #4DBBD3,
|
||||
secondary: #8a8a8a,
|
||||
success: #3adb76,
|
||||
|
@ -4,66 +4,64 @@
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||
<link rel="apple-touch-startup-image" href="images/screen_320x460.png" />
|
||||
<link rel="apple-touch-icon" href="images/screen_57x57.png">
|
||||
<link rel="icon" href="images/favicon.png">
|
||||
<!-- Stylesheets -->
|
||||
<link rel="stylesheet" type="text/css" href="css/app.css" title="plain">
|
||||
<link rel="stylesheet" type="text/css" href="css/guac-custom.css" title="plain">
|
||||
</head>
|
||||
<body>
|
||||
<div class="main">
|
||||
<div style="background: #f7f7f7; padding: 1.5em 1.5em 0.8em;">
|
||||
<div style="max-width: 1250px; margin: 0 auto;">
|
||||
<div style="display: flex; align-items: center;">
|
||||
<img src="images/one_small_logo.png" style="height:40px;">
|
||||
<h5 class="guacamole-status">
|
||||
<div class="container">
|
||||
<div class="remote-logo">
|
||||
<img src="images/remote_console/guacamole.png">
|
||||
</div>
|
||||
<div id="guacamole-state" class="guacamole-state">
|
||||
<span id="guacamole-loading">
|
||||
<i class="fas fa-spinner fa-spin"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</h5>
|
||||
<div class="remote-buttons">
|
||||
<button class="button alert" id="sendCtrlAltDelButton">
|
||||
Send CtrlAltDel
|
||||
</button>
|
||||
<button class="button primary" id="oskButton" style="display: none !important;">
|
||||
<i class="fas fa-keyboard fa-fw"></i>
|
||||
</button>
|
||||
<button class="button primary" id="mouseButton">
|
||||
<i class="fas fa-mouse-pointer fa-fw"></i>
|
||||
</button>
|
||||
<button class="button primary" id="takeScreenshot">
|
||||
<i class="fas fa-camera fa-fw" title="Take screenshot"></i>
|
||||
</button>
|
||||
</div>
|
||||
<header>
|
||||
<div class="header__wrapper">
|
||||
<div class="toolbar">
|
||||
<img src="images/opennebula-5.0.png">
|
||||
<div class="toolbar__state">
|
||||
<img src="images/remote_console/guacamole.png">
|
||||
<h5></h5>
|
||||
<span class="spinner">
|
||||
<i class="fas fa-spinner fa-spin"></i>
|
||||
</span>
|
||||
</div>
|
||||
<div class="toolbar__buttons">
|
||||
<button class="button alert" id="buttons__sendctrlaltdel">
|
||||
Send CtrlAltDel
|
||||
</button>
|
||||
<button class="button secondary" id="buttons__reconnect" title="Reconnect">
|
||||
<i class="fas fa-redo-alt fa-fw"></i>
|
||||
</button>
|
||||
<button class="button secondary" id="buttons__fullscreen" title="Fullscreen">
|
||||
<i class="fas fa-expand fa-fw"></i>
|
||||
</button>
|
||||
<button class="button primary" id="buttons__osk" title="Show keyboard">
|
||||
<i class="fas fa-keyboard fa-fw"></i>
|
||||
</button>
|
||||
<button class="button primary" id="buttons__mouse" title="Emulate mouse">
|
||||
<i class="fas fa-mouse-pointer fa-fw"></i>
|
||||
</button>
|
||||
<button class="button primary" id="buttons__screenshot" title="Take screenshot">
|
||||
<i class="fas fa-camera fa-fw"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="guacVNC_info"></div>
|
||||
</div>
|
||||
<div class="information"></div>
|
||||
</div>
|
||||
<div id="guacamole-main" class="guacamole-main">
|
||||
<div id="guacamole-display" class="guacamole-display"></div>
|
||||
</header>
|
||||
<main>
|
||||
<%### Guacamole display screen ###%>
|
||||
<div class="wrapper__display">
|
||||
<div id="display"></div>
|
||||
</div>
|
||||
<!-- On-screen keyboard -->
|
||||
<div class="osk-container" id="osk-container">
|
||||
<div class="osk-container-header" id="osk-container-header">
|
||||
<div class="buttons">
|
||||
<button class="close" id="osk-close">x</button>
|
||||
</div>
|
||||
<div class="layouts">
|
||||
<select id="osk-qwerty"></select>
|
||||
|
||||
<%### Guacamole on-screen keyboard ###%>
|
||||
<div class="osk__container" id="osk__container">
|
||||
<div class="osk__header">
|
||||
<div class="osk__header__buttons">
|
||||
<button class="close">x</button>
|
||||
</div>
|
||||
<select id="select__qwerty"></select>
|
||||
</div>
|
||||
<div class="osk" id="osk"></div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script src="dist/console/guacamole.js?v=<%= OpenNebula::VERSION %>"></script>
|
||||
<% view = $views_config.view(session[:user], session[:user_gname], session[:default_view]) %>
|
||||
|
@ -37,7 +37,7 @@
|
||||
<div style="background: #f7f7f7; padding: 1.5em 1.5em 0.8em;">
|
||||
<div style="max-width: 1250px; margin: 0 auto;">
|
||||
<div id="noVNC_status_bar" class="noVNC_status_bar" style="display: flex; align-items: center;">
|
||||
<img src="images/one_small_logo.png" style="height:40px;">
|
||||
<img src="images/opennebula-5.0.png" style="height:40px;">
|
||||
<h5 id="message-div" class="spice-message"></h5>
|
||||
</div>
|
||||
<div class="SPICE_info"></div>
|
||||
|
@ -72,7 +72,7 @@
|
||||
<div style="background: #f7f7f7; padding: 1.5em 1.5em 0.8em;">
|
||||
<div style="max-width: 1250px; margin: 0 auto;">
|
||||
<div id="VMRC_status_bar" class="noVNC_status_bar" style="display: flex; align-items: center;">
|
||||
<img src="images/one_small_logo.png" style="height:40px;">
|
||||
<img src="images/opennebula-5.0.png" style="height:40px;">
|
||||
|
||||
<h5 id="VMRC_status" style="position: relative;">
|
||||
<div class="container">
|
||||
|
@ -17,7 +17,7 @@
|
||||
<div style="background: #f7f7f7; padding: 1.5em 1.5em 0.8em;">
|
||||
<div style="max-width: 1250px; margin: 0 auto;">
|
||||
<div id="noVNC_status_bar" class="noVNC_status_bar" style="display: flex; align-items: center;">
|
||||
<img src="images/one_small_logo.png" style="height:40px;">
|
||||
<img src="images/opennebula-5.0.png" style="height:40px;">
|
||||
<h5 id="noVNC_status" style="position: relative;">
|
||||
<div class="container">
|
||||
<div class="remote_logo">
|
||||
|
Loading…
x
Reference in New Issue
Block a user