GUACAMOLE-723: Organize other active connections within collapsible panel.

This commit is contained in:
Michael Jumper
2019-03-22 16:15:41 -07:00
parent e7eb46b2a1
commit aa633c2a63
5 changed files with 162 additions and 17 deletions

View File

@@ -0,0 +1,87 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
/**
* A toolbar/panel which displays a list of active Guacamole connections. The
* panel is fixed to the bottom-right corner of its container and can be
* manually hidden/exposed by the user.
*/
angular.module('client').directive('guacClientPanel', [function guacClientPanel() {
return {
// Element only
restrict: 'E',
replace: true,
scope: {
/**
* The ManagedClient instances associated with the active
* connections to be displayed within this panel.
*
* @type ManagedClient[]
*/
clients : '='
},
templateUrl: 'app/client/templates/guacClientPanel.html',
controller: ['$scope', '$element', function guacClientPanelController($scope, $element) {
/**
* The DOM element containing the scrollable portion of the client
* panel.
*
* @type Element
*/
var scrollableArea = $element.find('.client-panel-connection-list')[0];
/**
* Whether the client panel is currently hidden. When hidden, the
* panel will be collapsed against the right side of the
* containiner.
*
* @type Boolean
*/
$scope.panelHidden = false;
/**
* Toggles whether the client panel is currently hidden.
*/
$scope.togglePanel = function togglePanel() {
$scope.panelHidden = !$scope.panelHidden;
};
// Override vertical scrolling, scrolling horizontally instead
scrollableArea.addEventListener('wheel', function reorientVerticalScroll(e) {
var deltaMultiplier = {
/* DOM_DELTA_PIXEL */ 0x00: 1,
/* DOM_DELTA_LINE */ 0x01: 15,
/* DOM_DELTA_PAGE */ 0x02: scrollableArea.offsetWidth
};
if (e.deltaY) {
this.scrollLeft += e.deltaY * (deltaMultiplier[e.deltaMode] || deltaMultiplier(0x01));
e.preventDefault();
}
});
}]
};
}]);

View File

@@ -19,22 +19,74 @@
#other-connections { #other-connections {
text-align: right;
position: absolute;
right: 0;
bottom: 0;
/* Render above modal status */ /* Render above modal status */
z-index: 20; z-index: 20;
} }
#other-connections .connection { #other-connections .client-panel {
position: absolute;
right: 0;
bottom: 0;
border: 1px solid rgba(255, 255, 255, 0.25);
background: rgba(0, 0, 0, 0.25);
max-width: 100%;
white-space: nowrap;
transition: max-width 0.125s, width 0.125s;
}
#other-connections .client-panel.hidden {
max-width: 16px;
}
#other-connections .client-panel-handle {
position: absolute;
left: 0;
bottom: 0;
height: 100%;
width: 16px;
z-index: 1;
background-color: white;
background-repeat: no-repeat;
background-size: contain;
background-position: center center;
background-image: url(images/arrows/right.png);
opacity: 0.5;
}
#other-connections .client-panel-handle:hover {
opacity: 0.75;
}
#other-connections .client-panel.hidden .client-panel-handle {
background-image: url(images/arrows/left.png);
}
#other-connections .client-panel-connection-list {
text-align: right;
margin: 0;
padding: 0;
padding-left: 16px;
overflow-x: auto;
overflow-y: hidden;
}
#other-connections .client-panel-connection {
display: inline-block; display: inline-block;
position: relative; position: relative;
margin: 1em; margin: 0.5em;
border: 1px solid white; border: 1px solid white;
background: black; background: black;
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.5); box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.5);
@@ -47,7 +99,7 @@
} }
#other-connections .connection .name { #other-connections .client-panel-connection .name {
position: absolute; position: absolute;
padding: 0.25em 0.5em; padding: 0.25em 0.5em;
@@ -67,6 +119,6 @@
} }
#other-connections .connection:hover { #other-connections .client-panel-connection:hover {
opacity: 1; opacity: 1;
} }

View File

@@ -13,14 +13,7 @@
<!-- All other active connections --> <!-- All other active connections -->
<div id="other-connections"> <div id="other-connections">
<div ng-repeat="otherClient in otherClients" class="connection"> <guac-client-panel clients="otherClients"></guac-client-panel>
<a href="#/client/{{otherClient.id}}">
<div class="thumbnail">
<guac-thumbnail client="otherClient"></guac-thumbnail>
</div>
<div class="name">{{ otherClient.title }}</div>
</a>
</div>
</div> </div>
</div> </div>

View File

@@ -0,0 +1,13 @@
<div class="client-panel" ng-class="{ 'hidden' : panelHidden }">
<div class="client-panel-handle" ng-click="togglePanel()"></div>
<ul class="client-panel-connection-list">
<li ng-repeat="client in clients" class="client-panel-connection">
<a href="#/client/{{client.id}}">
<div class="thumbnail">
<guac-thumbnail client="client"></guac-thumbnail>
</div>
<div class="name">{{ client.title }}</div>
</a>
</li>
</ul>
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B