From 149fba67370b130110b27bcc8ac03c5fa9c99207 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 1 Jul 2015 15:47:01 -0700 Subject: [PATCH] GUAC-1172: Implement navigation via breadcrumbs - no more tree. --- .../client/controllers/clientController.js | 40 ++++++++++++++++ .../app/client/directives/guacFileBrowser.js | 18 ++----- .../webapp/app/client/styles/file-browser.css | 10 ++-- .../app/client/styles/filesystem-menu.css | 23 +++++++++ .../webapp/app/client/templates/client.html | 6 +++ .../app/client/templates/guacFileBrowser.html | 27 ++++++----- .../app/client/types/ManagedFilesystem.js | 45 ++++++++++++++---- .../src/main/webapp/images/folder-up.png | Bin 0 -> 819 bytes 8 files changed, 131 insertions(+), 38 deletions(-) create mode 100644 guacamole/src/main/webapp/images/folder-up.png diff --git a/guacamole/src/main/webapp/app/client/controllers/clientController.js b/guacamole/src/main/webapp/app/client/controllers/clientController.js index ad55691c8..fbce5cc37 100644 --- a/guacamole/src/main/webapp/app/client/controllers/clientController.js +++ b/guacamole/src/main/webapp/app/client/controllers/clientController.js @@ -28,6 +28,7 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams // Required types var ManagedClientState = $injector.get('ManagedClientState'); + var ManagedFilesystem = $injector.get('ManagedFilesystem'); var ScrollState = $injector.get('ScrollState'); // Required services @@ -595,6 +596,45 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams return !!$scope.filesystemMenuContents && $scope.menu.shown; }; + /** + * Returns the full path to the given file as an ordered array of parent + * directories. + * + * @param {ManagedFilesystem.File} file + * The file whose full path should be retrieved. + * + * @returns {ManagedFilesystem.File[]} + * An array of directories which make up the hierarchy containing the + * given file, in order of increasing depth. + */ + $scope.getPath = function getPath(file) { + + var path = []; + + // Add all files to path in ascending order of depth + while (file && file.parent) { + path.unshift(file); + file = file.parent; + } + + return path; + + }; + + /** + * Changes the current directory of the given filesystem to the given + * directory. + * + * @param {ManagedFilesystem} filesystem + * The filesystem whose current directory should be changed. + * + * @param {ManagedFilesystem.File} file + * The directory to change to. + */ + $scope.changeDirectory = function changeDirectory(filesystem, file) { + ManagedFilesystem.changeDirectory(filesystem, file); + }; + // Clean up when view destroyed $scope.$on('$destroy', function clientViewDestroyed() { diff --git a/guacamole/src/main/webapp/app/client/directives/guacFileBrowser.js b/guacamole/src/main/webapp/app/client/directives/guacFileBrowser.js index 9e5e047cc..ba03a9e98 100644 --- a/guacamole/src/main/webapp/app/client/directives/guacFileBrowser.js +++ b/guacamole/src/main/webapp/app/client/directives/guacFileBrowser.js @@ -79,22 +79,14 @@ angular.module('client').directive('guacFileBrowser', [function guacFileBrowser( }; /** - * Toggles the expanded state of the given file between expanded - * and collapsed, showing or hiding the file's children. This is - * only applicable to directories. + * Changes the currently-displayed directory to the given + * directory. * * @param {ManagedFilesystem.File} file - * The file to expand or collapse. + * The directory to change to. */ - $scope.toggleExpanded = function toggleExpanded(file) { - - // Toggle expanded state - file.expanded = !file.expanded; - - // If now expanded, refresh contents - if (file.expanded) - ManagedFilesystem.refresh($scope.filesystem, file); - + $scope.changeDirectory = function changeDirectory(file) { + ManagedFilesystem.changeDirectory($scope.filesystem, file); }; /** diff --git a/guacamole/src/main/webapp/app/client/styles/file-browser.css b/guacamole/src/main/webapp/app/client/styles/file-browser.css index 2c6c923fb..73fce34ad 100644 --- a/guacamole/src/main/webapp/app/client/styles/file-browser.css +++ b/guacamole/src/main/webapp/app/client/styles/file-browser.css @@ -27,10 +27,8 @@ display: none; } -/* Show directory contents if expanded */ - -.file-browser .directory.expanded > .children { - display: block; +.file-browser .list-item .caption { + white-space: nowrap; } /* Directory / file icons */ @@ -43,6 +41,6 @@ background-image: url('images/folder-closed.png'); } -.file-browser .directory.expanded > .caption .icon { - background-image: url('images/folder-open.png'); +.file-browser .directory.previous > .caption .icon { + background-image: url('images/folder-up.png'); } diff --git a/guacamole/src/main/webapp/app/client/styles/filesystem-menu.css b/guacamole/src/main/webapp/app/client/styles/filesystem-menu.css index ce417e042..76ee72ff7 100644 --- a/guacamole/src/main/webapp/app/client/styles/filesystem-menu.css +++ b/guacamole/src/main/webapp/app/client/styles/filesystem-menu.css @@ -46,3 +46,26 @@ -webkit-align-items: center; align-items: center; } + +#filesystem-menu .menu-body { + padding: 0.25em; +} + +#filesystem-menu .header.breadcrumbs { + background: rgba(0,0,0,0.0125); + border-bottom: 1px solid rgba(0,0,0,0.05); + box-shadow: none; + margin-top: 0; + border-top: none; +} + +#filesystem-menu .header.breadcrumbs .breadcrumb { + padding: 0.5em; + font-size: 0.8em; + font-weight: bold; +} + +#filesystem-menu .header.breadcrumbs .breadcrumb:hover { + background-color: #CDA; + cursor: pointer; +} diff --git a/guacamole/src/main/webapp/app/client/templates/client.html b/guacamole/src/main/webapp/app/client/templates/client.html index 27ee14937..6493ffef2 100644 --- a/guacamole/src/main/webapp/app/client/templates/client.html +++ b/guacamole/src/main/webapp/app/client/templates/client.html @@ -174,6 +174,12 @@ + + + -
-
+
+
{{file.name}}
- - -
-
-
- +
+ + +
+ +
+ +
+
diff --git a/guacamole/src/main/webapp/app/client/types/ManagedFilesystem.js b/guacamole/src/main/webapp/app/client/types/ManagedFilesystem.js index 265721afb..65205def0 100644 --- a/guacamole/src/main/webapp/app/client/types/ManagedFilesystem.js +++ b/guacamole/src/main/webapp/app/client/types/ManagedFilesystem.js @@ -68,6 +68,14 @@ angular.module('client').factory('ManagedFilesystem', ['$rootScope', '$injector' */ this.root = template.root; + /** + * The current directory being viewed or manipulated within the + * filesystem. + * + * @type ManagedFilesystem.File + */ + this.currentDirectory = template.currentDirectory || template.root; + }; /** @@ -140,6 +148,7 @@ angular.module('client').factory('ManagedFilesystem', ['$rootScope', '$injector' mimetype : mimetypes[name], streamName : name, type : type, + parent : file, name : filename }); @@ -216,6 +225,26 @@ angular.module('client').factory('ManagedFilesystem', ['$rootScope', '$injector' }; + /** + * Changes the current directory of the given filesystem, automatically + * refreshing the contents of that directory. + * + * @param {ManagedFilesystem} filesystem + * The filesystem whose current directory should be changed. + * + * @param {ManagedFilesystem.File} file + * The directory to change to. + */ + ManagedFilesystem.changeDirectory = function changeDirectory(filesystem, file) { + + // Refresh contents + ManagedFilesystem.refresh(filesystem, file); + + // Set current directory + filesystem.currentDirectory = file; + + }; + /** * A file within a ManagedFilesystem. Each ManagedFilesystem.File provides * sufficient information for retrieval or replacement of the file's @@ -257,6 +286,14 @@ angular.module('client').factory('ManagedFilesystem', ['$rootScope', '$injector' */ this.name = template.name; + /** + * The parent directory of this file. In the case of the root + * directory, this will be null. + * + * @type ManagedFilesystem.File + */ + this.parent = template.parent; + /** * Map of all known files containined within this file by name. This is * only applicable to directories. @@ -265,14 +302,6 @@ angular.module('client').factory('ManagedFilesystem', ['$rootScope', '$injector' */ this.files = template.files || {}; - /** - * Whether this file is currently expanded, exposing any children - * within. This is only applicable to directories. - * - * @type Boolean - */ - this.expanded = template.expanded || false; - }; /** diff --git a/guacamole/src/main/webapp/images/folder-up.png b/guacamole/src/main/webapp/images/folder-up.png new file mode 100644 index 0000000000000000000000000000000000000000..5271b2eb8b3fe7c62a124188ab40cb9243167a7a GIT binary patch literal 819 zcmV-31I+x1P)u>7^n;&7`#EZ&*i^#z&KrQO ztu6BTyz4^uivxm-jNh&$}t13m*ke#i7W z9*?uUyzFvn=cojH2VP7)iay_fxAdi_P17WiNKAcFm4M9DBY4CFTEHiO)zwvBCY@1y z?)T5+GvFP-%F2o_69)E#Y&M%@vsq?lRC{F4{r$bNk7|cUo}m8`w(E4SHzfEbpjxex zOeX!BZen;&MGeD{-Q8Ug5lN*|lS*&LZBHX$Zf;Hv4i5fgW|0z*PN(Jc^z^UPG%^Af z78az{YWS;(MwX|c6;Lb|(huO zkl22&DwT@k(?3*az<|BIJ+7~>+27x1c6Qd$Ge<{9j;^Vk(r&jWHkKVqyX))g$_#Ko z5c2@f0st{hQ?9PAqALK9rKKg?DlifP0Lf%BL+=41BLMn0L1$-Y(G>vwyTHT4!{`ct z{%vrh(TJ{qL90|MVp&#n1pus=FXB0t1B_IrMz{oo| xRW;ZE3X_Y)cP!xJQwO2ZXfzs)Mx)ULkYC)&wuc