diff --git a/guacamole/src/main/frontend/src/app/client/controllers/clientController.js b/guacamole/src/main/frontend/src/app/client/controllers/clientController.js index 89654b5d8..3a0df8c11 100644 --- a/guacamole/src/main/frontend/src/app/client/controllers/clientController.js +++ b/guacamole/src/main/frontend/src/app/client/controllers/clientController.js @@ -791,6 +791,24 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams ManagedClient.uploadFile($scope.filesystemMenuContents.client, files[i], $scope.filesystemMenuContents); }; + + /** + * Determines whether the attached client group has any associated client + * messages to display. + * + * @returns {Boolean} + * true if there are messages to display; otherwise false. + */ + $scope.hasMessages = function hasMessages() { + + // No client group means no messages + if (!$scope.clientGroup) + return false; + + // Otherwise, find messages within the clients in the group. + return _.findIndex($scope.clientGroup.clients, ManagedClient.hasMessages) !== -1; + + }; /** * Determines whether the attached client group has any associated file diff --git a/guacamole/src/main/frontend/src/app/client/directives/guacClientMessage.js b/guacamole/src/main/frontend/src/app/client/directives/guacClientMessage.js new file mode 100644 index 000000000..9e63edb18 --- /dev/null +++ b/guacamole/src/main/frontend/src/app/client/directives/guacClientMessage.js @@ -0,0 +1,42 @@ +/* + * 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. + */ + +/** + * Directive which displays a message for the client. + */ +angular.module('client').directive('guacClientMessage', [function guacClientMessage() { + + return { + restrict: 'E', + replace: true, + scope: { + + /** + * The message to display. + * + * @type String + */ + message : '=' + + }, + + templateUrl: 'app/client/templates/guacClientMessage.html' + + }; +}]); diff --git a/guacamole/src/main/frontend/src/app/client/directives/guacMessageDialog.js b/guacamole/src/main/frontend/src/app/client/directives/guacMessageDialog.js new file mode 100644 index 000000000..16ca81d4a --- /dev/null +++ b/guacamole/src/main/frontend/src/app/client/directives/guacMessageDialog.js @@ -0,0 +1,76 @@ +/* + * 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. + */ + +/** + * Directive which displays all client messages. + */ +angular.module('client').directive('guacMessageDialog', [function guacMessageDialog() { + + return { + restrict: 'E', + replace: true, + scope: { + + /** + * The client group whose messages should be managed by this + * directive. + * + * @type ManagedClientGroup + */ + clientGroup : '=' + + }, + + templateUrl: 'app/client/templates/guacMessageDialog.html', + controller: ['$scope', '$injector', function guacMessageDialogController($scope, $injector) { + + // Required types + const ManagedClient = $injector.get('ManagedClient'); + const ManagedClientGroup = $injector.get('ManagedClientGroup'); + + /** + * Removes all messages. + */ + $scope.clearAllMessages = function clearAllMessages() { + + // Nothing to clear if no client group attached + if (!$scope.clientGroup) + return; + + // Remove each client's messages + $scope.clientGroup.clients.forEach(client => { + client.messages = []; + }); + + }; + + /** + * @borrows ManagedClientGroup.hasMultipleClients + */ + $scope.hasMultipleClients = ManagedClientGroup.hasMultipleClients; + + /** + * @borrows ManagedClient.hasMessages + */ + $scope.hasMessages = ManagedClient.hasMessages; + + }] + + }; +}]); diff --git a/guacamole/src/main/frontend/src/app/client/styles/client-message.css b/guacamole/src/main/frontend/src/app/client/styles/client-message.css new file mode 100644 index 000000000..21b905672 --- /dev/null +++ b/guacamole/src/main/frontend/src/app/client/styles/client-message.css @@ -0,0 +1,23 @@ +/* + * 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. + */ + +p.client-message-text { + margin: 5px; +} + diff --git a/guacamole/src/main/frontend/src/app/client/styles/message-dialog.css b/guacamole/src/main/frontend/src/app/client/styles/message-dialog.css new file mode 100644 index 000000000..2a90c672d --- /dev/null +++ b/guacamole/src/main/frontend/src/app/client/styles/message-dialog.css @@ -0,0 +1,122 @@ +/* + * 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. + */ + +#message-dialog { + + position: absolute; + right: 0; + bottom: 0; + z-index: 20; + + font-size: 0.8em; + + width: 3in; + max-width: 100%; + max-height: 3in; + + background: white; + opacity: 0.75; + +} + +#message-dialog .message-dialog-box { + + /* IE10 */ + display: -ms-flexbox; + -ms-flex-align: stretch; + -ms-flex-direction: column; + + /* Ancient Mozilla */ + display: -moz-box; + -moz-box-align: stretch; + -moz-box-orient: vertical; + + /* Ancient WebKit */ + display: -webkit-box; + -webkit-box-align: stretch; + -webkit-box-orient: vertical; + + /* Old WebKit */ + display: -webkit-flex; + -webkit-align-items: stretch; + -webkit-flex-direction: column; + + /* W3C */ + display: flex; + align-items: stretch; + flex-direction: column; + + max-width: inherit; + max-height: inherit; + + border: 1px solid rgba(0, 0, 0, 0.5); + box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.25); + +} + +#message-dialog .message-dialog-box .header { + -ms-flex: 0 0 auto; + -moz-box-flex: 0; + -webkit-box-flex: 0; + -webkit-flex: 0 0 auto; + flex: 0 0 auto; + margin-bottom: 5px; +} + +#message-dialog .message-dialog-box .client-message-body { + + -ms-flex: 1 1 auto; + -moz-box-flex: 1; + -webkit-box-flex: 1; + -webkit-flex: 1 1 auto; + flex: 1 1 auto; + + overflow: auto; + +} + +/* + * Shrink maximum height if viewport is too small for default 3in dialog. + */ +@media all and (max-height: 3in) { + + #message-dialog { + max-height: 1.5in; + } + +} + +/* + * If viewport is too small for even the 1.5in dialog, fit all available space. + */ +@media all and (max-height: 1.5in) { + + #message-dialog { + height: 100%; + } + + #message-dialog .message-dialog-box { + position: absolute; + left: 0.5em; + top: 0.5em; + right: 0.5em; + bottom: 0.5em; + } + +} diff --git a/guacamole/src/main/frontend/src/app/client/templates/client.html b/guacamole/src/main/frontend/src/app/client/templates/client.html index d9c6684cb..7cf976c0a 100644 --- a/guacamole/src/main/frontend/src/app/client/templates/client.html +++ b/guacamole/src/main/frontend/src/app/client/templates/client.html @@ -44,6 +44,11 @@