mirror of
				https://github.com/gyurix1968/guacamole-client.git
				synced 2025-10-30 16:43:22 +00:00 
			
		
		
		
	GUAC-586: Implement generic and hierarchical page tabbed page lists.
This commit is contained in:
		| @@ -353,11 +353,11 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto | ||||
|             var linked = dataSource in users; | ||||
|  | ||||
|             // Add page entry | ||||
|             $scope.accountPages.push(new PageDefinition( | ||||
|                 translationStringService.canonicalize('DATA_SOURCE_' + dataSource) + '.NAME', | ||||
|                 '/manage/' + encodeURIComponent(dataSource) + '/users/' + encodeURIComponent(username), | ||||
|                 linked ? 'linked' : 'unlinked' | ||||
|             )); | ||||
|             $scope.accountPages.push(new PageDefinition({ | ||||
|                 name      : translationStringService.canonicalize('DATA_SOURCE_' + dataSource) + '.NAME', | ||||
|                 url       : '/manage/' + encodeURIComponent(dataSource) + '/users/' + encodeURIComponent(username), | ||||
|                 className : linked ? 'linked' : 'unlinked' | ||||
|             })); | ||||
|  | ||||
|         }); | ||||
|  | ||||
|   | ||||
| @@ -28,14 +28,14 @@ | ||||
|     text-transform: none; | ||||
| } | ||||
|  | ||||
| .manage-user .settings-tabs .page-list li.unlinked a[href], | ||||
| .manage-user .settings-tabs .page-list li.linked   a[href] { | ||||
| .manage-user .page-tabs .page-list li.unlinked a[href], | ||||
| .manage-user .page-tabs .page-list li.linked   a[href] { | ||||
|     padding-right: 2.5em; | ||||
|     position: relative; | ||||
| } | ||||
|  | ||||
| .manage-user .settings-tabs .page-list li.unlinked a[href]:before, | ||||
| .manage-user .settings-tabs .page-list li.linked   a[href]:before { | ||||
| .manage-user .page-tabs .page-list li.unlinked a[href]:before, | ||||
| .manage-user .page-tabs .page-list li.linked   a[href]:before { | ||||
|     content: ' '; | ||||
|     position: absolute; | ||||
|     right: 0; | ||||
| @@ -47,19 +47,19 @@ | ||||
|     background-position: center; | ||||
| } | ||||
|  | ||||
| .manage-user .settings-tabs .page-list li.unlinked a[href]:before { | ||||
| .manage-user .page-tabs .page-list li.unlinked a[href]:before { | ||||
|     background-image: url('images/plus.png'); | ||||
| } | ||||
|  | ||||
| .manage-user .settings-tabs .page-list li.unlinked a[href] { | ||||
| .manage-user .page-tabs .page-list li.unlinked a[href] { | ||||
|     opacity: 0.5; | ||||
| } | ||||
|  | ||||
| .manage-user .settings-tabs .page-list li.unlinked a[href]:hover, | ||||
| .manage-user .settings-tabs .page-list li.unlinked a[href].current { | ||||
| .manage-user .page-tabs .page-list li.unlinked a[href]:hover, | ||||
| .manage-user .page-tabs .page-list li.unlinked a[href].current { | ||||
|     opacity: 1; | ||||
| } | ||||
|  | ||||
| .manage-user .settings-tabs .page-list li.linked a[href]:before { | ||||
| .manage-user .page-tabs .page-list li.linked a[href]:before { | ||||
|     background-image: url('images/checkmark.png'); | ||||
| } | ||||
|   | ||||
| @@ -27,7 +27,7 @@ THE SOFTWARE. | ||||
|         <h2>{{user.username}}</h2> | ||||
|         <guac-user-menu></guac-user-menu> | ||||
|     </div> | ||||
|     <div class="settings-tabs"> | ||||
|     <div class="page-tabs"> | ||||
|         <guac-page-list pages="accountPages" ng-show="showAccountTabs()"></guac-page-list> | ||||
|     </div> | ||||
|  | ||||
|   | ||||
| @@ -33,7 +33,7 @@ angular.module('navigation').directive('guacPageList', [function guacPageList() | ||||
|             /** | ||||
|              * The array of pages to display. | ||||
|              * | ||||
|              * @type Page[] | ||||
|              * @type PageDefinition[] | ||||
|              */ | ||||
|             pages : '=' | ||||
|  | ||||
| @@ -42,13 +42,119 @@ angular.module('navigation').directive('guacPageList', [function guacPageList() | ||||
|         templateUrl: 'app/navigation/templates/guacPageList.html', | ||||
|         controller: ['$scope', '$injector', function guacPageListController($scope, $injector) { | ||||
|  | ||||
|             // Get required services | ||||
|             // Required types | ||||
|             var PageDefinition = $injector.get('PageDefinition'); | ||||
|  | ||||
|             // Required services | ||||
|             var $location = $injector.get('$location'); | ||||
|  | ||||
|             /** | ||||
|              * The URL of the currently-displayed page. | ||||
|              * | ||||
|              * @type String | ||||
|              */ | ||||
|             var currentURL = $location.url(); | ||||
|  | ||||
|             /** | ||||
|              * The names associated with the current page, if the current page | ||||
|              * is known. The value of this property corresponds to the value of | ||||
|              * PageDefinition.name. Though PageDefinition.name may be a String, | ||||
|              * this will always be an Array. | ||||
|              * | ||||
|              * @type String[] | ||||
|              */ | ||||
|             var currentPageName = []; | ||||
|  | ||||
|             /** | ||||
|              * Array of each level of the page list, where a level is defined | ||||
|              * by a mapping of names (translation strings) to the | ||||
|              * PageDefinitions corresponding to those names. | ||||
|              * | ||||
|              * @type Object.<String, PageDefinition>[] | ||||
|              */ | ||||
|             $scope.levels = []; | ||||
|  | ||||
|             /** | ||||
|              * Returns the names associated with the given page, in | ||||
|              * hierarchical order. If the page is only associated with a single | ||||
|              * name, and that name is not stored as an array, it will be still | ||||
|              * be returned as an array containing a single item. | ||||
|              * | ||||
|              * @param {PageDefinition} page | ||||
|              *     The page to return the names of. | ||||
|              * | ||||
|              * @return {String[]} | ||||
|              *     An array of all names associated with the given page, in | ||||
|              *     hierarchical order. | ||||
|              */ | ||||
|             var getPageNames = function getPageNames(page) { | ||||
|  | ||||
|                 // If already an array, simply return the name | ||||
|                 if (angular.isArray(page.name)) | ||||
|                     return page.name; | ||||
|  | ||||
|                 // Otherwise, transform into array | ||||
|                 return [page.name]; | ||||
|  | ||||
|             }; | ||||
|  | ||||
|             /** | ||||
|              * Adds the given PageDefinition to the overall set of pages | ||||
|              * displayed by this guacPageList, automatically updating the | ||||
|              * available levels ($scope.levels) and the contents of those | ||||
|              * levels. | ||||
|              * | ||||
|              * @param {PageDefinition} page | ||||
|              *     The PageDefinition to add. | ||||
|              * | ||||
|              * @param {Number} weight | ||||
|              *     The sorting weight to use for the page if it does not | ||||
|              *     already have an associated weight. | ||||
|              */ | ||||
|             var addPage = function addPage(page, weight) { | ||||
|  | ||||
|                 // Pull all names for page | ||||
|                 var names = getPageNames(page); | ||||
|  | ||||
|                 // Copy the hierarchy of this page into the displayed levels | ||||
|                 // as far as is relevant for the currently-displayed page | ||||
|                 for (var i = 0; i < names.length; i++) { | ||||
|  | ||||
|                     // Create current level, if it doesn't yet exist | ||||
|                     var pages = $scope.levels[i]; | ||||
|                     if (!pages) | ||||
|                         pages = $scope.levels[i] = {}; | ||||
|  | ||||
|                     // Get the name at the current level | ||||
|                     var name = names[i]; | ||||
|  | ||||
|                     // Determine whether this page definition is part of the | ||||
|                     // hierarchy containing the current page | ||||
|                     var isCurrentPage = (currentPageName[i] === name); | ||||
|  | ||||
|                     // Store new page if it doesn't yet exist at this level | ||||
|                     if (!pages[name]) { | ||||
|                         pages[name] = new PageDefinition({ | ||||
|                             name      : name, | ||||
|                             url       : isCurrentPage ? currentURL : page.url, | ||||
|                             className : page.className, | ||||
|                             weight    : page.weight || weight | ||||
|                         }); | ||||
|                     } | ||||
|  | ||||
|                     // If the name at this level no longer matches the | ||||
|                     // hierarchy of the current page, do not go any deeper | ||||
|                     if (currentPageName[i] !== name) | ||||
|                         break; | ||||
|  | ||||
|                 } | ||||
|  | ||||
|             }; | ||||
|  | ||||
|             /** | ||||
|              * Navigate to the given page. | ||||
|              *  | ||||
|              * @param {Page} page | ||||
|              * @param {PageDefinition} page | ||||
|              *     The page to navigate to. | ||||
|              */ | ||||
|             $scope.navigateToPage = function navigateToPage(page) { | ||||
| @@ -58,16 +164,67 @@ angular.module('navigation').directive('guacPageList', [function guacPageList() | ||||
|             /** | ||||
|              * Tests whether the given page is the page currently being viewed. | ||||
|              * | ||||
|              * @param {Page} page | ||||
|              * @param {PageDefinition} page | ||||
|              *     The page to test. | ||||
|              * | ||||
|              * @returns {Boolean} | ||||
|              *     true if the given page is the current page, false otherwise. | ||||
|              */ | ||||
|             $scope.isCurrentPage = function isCurrentPage(page) { | ||||
|                 return $location.url() === page.url; | ||||
|                 return currentURL === page.url; | ||||
|             }; | ||||
|  | ||||
|             /** | ||||
|              * Given an arbitrary map of PageDefinitions, returns an array of | ||||
|              * those PageDefinitions, sorted by weight. | ||||
|              * | ||||
|              * @param {Object.<*, PageDefinition>} level | ||||
|              *     A map of PageDefinitions with arbitrary keys. The value of | ||||
|              *     each key is ignored. | ||||
|              * | ||||
|              * @returns {PageDefinition[]} | ||||
|              *     An array of all PageDefinitions in the given map, sorted by | ||||
|              *     weight. | ||||
|              */ | ||||
|             $scope.getPages = function getPages(level) { | ||||
|  | ||||
|                 var pages = []; | ||||
|  | ||||
|                 // Convert contents of level to a flat array of pages | ||||
|                 angular.forEach(level, function addPageFromLevel(page) { | ||||
|                     pages.push(page); | ||||
|                 }); | ||||
|  | ||||
|                 // Sort page array by weight | ||||
|                 pages.sort(function comparePages(a, b) { | ||||
|                     return a.weight - b.weight; | ||||
|                 }); | ||||
|  | ||||
|                 return pages; | ||||
|  | ||||
|             }; | ||||
|  | ||||
|             // Update page levels whenever pages changes | ||||
|             $scope.$watch('pages', function setPages(pages) { | ||||
|  | ||||
|                 // Determine current page name | ||||
|                 currentPageName = []; | ||||
|                 angular.forEach(pages, function findCurrentPageName(page) { | ||||
|  | ||||
|                     // If page is current page, store its names | ||||
|                     if ($scope.isCurrentPage(page)) | ||||
|                         currentPageName = getPageNames(page); | ||||
|  | ||||
|                 }); | ||||
|  | ||||
|                 // Reset contents of levels | ||||
|                 $scope.levels = []; | ||||
|  | ||||
|                 // Add all page definitions | ||||
|                 angular.forEach(pages, addPage); | ||||
|  | ||||
|             }); | ||||
|  | ||||
|         }] // end controller | ||||
|  | ||||
|     }; | ||||
|   | ||||
| @@ -41,31 +41,16 @@ angular.module('navigation').factory('userPageService', ['$injector', | ||||
|      | ||||
|     var service = {}; | ||||
|      | ||||
|     /** | ||||
|      * Construct a new PageDefinition object with the given name and url. | ||||
|      * | ||||
|      * @constructor | ||||
|      * @param {String} name | ||||
|      *     The i18n key for the name of the page. | ||||
|      *  | ||||
|      * @param {String} url | ||||
|      *     The URL of the page. | ||||
|      */ | ||||
|     var PageDefinition = function PageDefinition(name, url) { | ||||
|         this.name = name; | ||||
|         this.url  = url; | ||||
|     }; | ||||
|              | ||||
|     /** | ||||
|      * The home page to assign to a user if they can navigate to more than one | ||||
|      * page. | ||||
|      *  | ||||
|      * @type PageDefinition | ||||
|      */ | ||||
|     var SYSTEM_HOME_PAGE = new PageDefinition( | ||||
|         'USER_MENU.ACTION_NAVIGATE_HOME', | ||||
|         '/' | ||||
|     ); | ||||
|     var SYSTEM_HOME_PAGE = new PageDefinition({ | ||||
|         name : 'USER_MENU.ACTION_NAVIGATE_HOME', | ||||
|         url  : '/' | ||||
|     }); | ||||
|  | ||||
|     /** | ||||
|      * Returns an appropriate home page for the current user. | ||||
| @@ -101,14 +86,14 @@ angular.module('navigation').factory('userPageService', ['$injector', | ||||
|  | ||||
|                 // Only one connection present, use as home page | ||||
|                 if (connection) { | ||||
|                     homePage = new PageDefinition( | ||||
|                         connection.name, | ||||
|                         '/client/' + ClientIdentifier.toString({ | ||||
|                     homePage = new PageDefinition({ | ||||
|                         name : connection.name, | ||||
|                         url  : '/client/' + ClientIdentifier.toString({ | ||||
|                             dataSource : dataSource, | ||||
|                             type       : ClientIdentifier.Types.CONNECTION, | ||||
|                             id         : connection.identifier | ||||
|                         }) | ||||
|                     ); | ||||
|                     }); | ||||
|                 } | ||||
|  | ||||
|                 // Only one balancing group present, use as home page | ||||
| @@ -116,14 +101,14 @@ angular.module('navigation').factory('userPageService', ['$injector', | ||||
|                         && connectionGroup.type === ConnectionGroup.Type.BALANCING | ||||
|                         && _.isEmpty(connectionGroup.childConnections) | ||||
|                         && _.isEmpty(connectionGroup.childConnectionGroups)) { | ||||
|                     homePage = new PageDefinition( | ||||
|                         connectionGroup.name, | ||||
|                         '/client/' + ClientIdentifier.toString({ | ||||
|                     homePage = new PageDefinition({ | ||||
|                         name : connectionGroup.name, | ||||
|                         url  : '/client/' + ClientIdentifier.toString({ | ||||
|                             dataSource : dataSource, | ||||
|                             type       : ClientIdentifier.Types.CONNECTION_GROUP, | ||||
|                             id         : connectionGroup.identifier | ||||
|                         }) | ||||
|                     ); | ||||
|                     }); | ||||
|                 } | ||||
|  | ||||
|             } | ||||
| @@ -247,33 +232,33 @@ angular.module('navigation').factory('userPageService', ['$injector', | ||||
|  | ||||
|         // If user can manage sessions, add link to sessions management page | ||||
|         if (canManageSessions) { | ||||
|             pages.push(new PageDefinition( | ||||
|                 'USER_MENU.ACTION_MANAGE_SESSIONS', | ||||
|                 '/settings/sessions' | ||||
|             )); | ||||
|             pages.push(new PageDefinition({ | ||||
|                 name : 'USER_MENU.ACTION_MANAGE_SESSIONS', | ||||
|                 url  : '/settings/sessions' | ||||
|             })); | ||||
|         } | ||||
|          | ||||
|         // If user can manage users, add link to user management page | ||||
|         if (canManageUsers) { | ||||
|             pages.push(new PageDefinition( | ||||
|                 'USER_MENU.ACTION_MANAGE_USERS', | ||||
|                 '/settings/users' | ||||
|             )); | ||||
|             pages.push(new PageDefinition({ | ||||
|                 name : 'USER_MENU.ACTION_MANAGE_USERS', | ||||
|                 url  : '/settings/users' | ||||
|             })); | ||||
|         } | ||||
|  | ||||
|         // If user can manage connections, add link to connections management page | ||||
|         if (canManageConnections) { | ||||
|             pages.push(new PageDefinition( | ||||
|                 'USER_MENU.ACTION_MANAGE_CONNECTIONS', | ||||
|                 '/settings/connections' | ||||
|             )); | ||||
|             pages.push(new PageDefinition({ | ||||
|                 name : 'USER_MENU.ACTION_MANAGE_CONNECTIONS', | ||||
|                 url  : '/settings/connections' | ||||
|             })); | ||||
|         } | ||||
|  | ||||
|         // Add link to user preferences (always accessible) | ||||
|         pages.push(new PageDefinition( | ||||
|             'USER_MENU.ACTION_MANAGE_PREFERENCES', | ||||
|             '/settings/preferences' | ||||
|         )); | ||||
|         pages.push(new PageDefinition({ | ||||
|             name : 'USER_MENU.ACTION_MANAGE_PREFERENCES', | ||||
|             url  : '/settings/preferences' | ||||
|         })); | ||||
|  | ||||
|         return pages; | ||||
|     }; | ||||
| @@ -338,10 +323,10 @@ angular.module('navigation').factory('userPageService', ['$injector', | ||||
|  | ||||
|         // Add generic link to the first-available settings page | ||||
|         if (settingsPages.length) { | ||||
|             pages.push(new PageDefinition( | ||||
|                 'USER_MENU.ACTION_MANAGE_SETTINGS', | ||||
|                 settingsPages[0].url | ||||
|             )); | ||||
|             pages.push(new PageDefinition({ | ||||
|                 name : 'USER_MENU.ACTION_MANAGE_SETTINGS', | ||||
|                 url  : settingsPages[0].url | ||||
|             })); | ||||
|         } | ||||
|          | ||||
|         return pages; | ||||
|   | ||||
| @@ -0,0 +1,58 @@ | ||||
| /* | ||||
|  * Copyright (C) 2015 Glyptodon LLC | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
|  * THE SOFTWARE. | ||||
|  */ | ||||
|  | ||||
| .page-tabs .page-list ul { | ||||
|     margin: 0; | ||||
|     padding: 0; | ||||
|     background: rgba(0, 0, 0, 0.0125); | ||||
|     border-bottom: 1px solid rgba(0, 0, 0, 0.05); | ||||
| } | ||||
|  | ||||
| .page-tabs .page-list ul + ul { | ||||
|     font-size: 0.75em; | ||||
| } | ||||
|  | ||||
| .page-tabs .page-list li { | ||||
|     display: inline-block; | ||||
|     list-style: none; | ||||
| } | ||||
|  | ||||
| .page-tabs .page-list li a[href] { | ||||
|     display: block; | ||||
|     color: black; | ||||
|     text-decoration: none; | ||||
|     padding: 0.75em 1em; | ||||
| } | ||||
|  | ||||
| .page-tabs .page-list li a[href]:visited { | ||||
|     color: black; | ||||
| } | ||||
|  | ||||
| .page-tabs .page-list li a[href]:hover { | ||||
|     background-color: #CDA; | ||||
| } | ||||
|  | ||||
| .page-tabs .page-list li a[href].current, | ||||
| .page-tabs .page-list li a[href].current:hover { | ||||
|     background: rgba(0,0,0,0.3); | ||||
|     cursor: default; | ||||
| } | ||||
| @@ -1,4 +1,4 @@ | ||||
| <ul class="page-list"> | ||||
| <div class="page-list"> | ||||
|     <!-- | ||||
|        Copyright (C) 2015 Glyptodon LLC | ||||
|  | ||||
| @@ -22,11 +22,13 @@ | ||||
|     --> | ||||
|  | ||||
|     <!-- Navigation links --> | ||||
|     <li ng-repeat="page in pages" class="{{page.className}}"> | ||||
|         <a class="home" ng-click="navigateToPage(page)" | ||||
|            ng-class="{current: isCurrentPage(page)}" href="#{{page.url}}"> | ||||
|             {{page.name | translate}} | ||||
|         </a> | ||||
|     </li> | ||||
|     <ul class="page-list-level" ng-repeat="level in levels track by $index"> | ||||
|         <li ng-repeat="page in getPages(level)" class="{{page.className}}"> | ||||
|             <a class="home" ng-click="navigateToPage(page)" | ||||
|                ng-class="{current: isCurrentPage(page)}" href="#{{page.url}}"> | ||||
|                 {{page.name | translate}} | ||||
|             </a> | ||||
|         </li> | ||||
|     </ul> | ||||
|  | ||||
| </ul> | ||||
| </div> | ||||
|   | ||||
| @@ -30,37 +30,46 @@ angular.module('navigation').factory('PageDefinition', [function definePageDefin | ||||
|      * an arbitrary, human-readable name. | ||||
|      * | ||||
|      * @constructor | ||||
|      * @param {String} name | ||||
|      *     The the name of the page, which should be a translation table key. | ||||
|      * | ||||
|      * @param {String} url | ||||
|      *     The URL of the page. | ||||
|      *  | ||||
|      * @param {String} [className=''] | ||||
|      *     The CSS class name to associate with this page, if any. | ||||
|      * @param {PageDefinition|Object} template | ||||
|      *     The object whose properties should be copied within the new | ||||
|      *     PageDefinition. | ||||
|      */ | ||||
|     var PageDefinition = function PageDefinition(name, url, className) { | ||||
|     var PageDefinition = function PageDefinition(template) { | ||||
|  | ||||
|         /** | ||||
|          * The the name of the page, which should be a translation table key. | ||||
|          * Alternatively, this may also be a list of names, where the final | ||||
|          * name represents the page and earlier names represent categorization. | ||||
|          * Those categorical names may be rendered hierarchically as a system | ||||
|          * of menus, tabs, etc. | ||||
|          * | ||||
|          * @type String | ||||
|          * @type String|String[] | ||||
|          */ | ||||
|         this.name = name; | ||||
|         this.name = template.name; | ||||
|  | ||||
|         /** | ||||
|          * The URL of the page. | ||||
|          * | ||||
|          * @type String | ||||
|          */ | ||||
|         this.url = url; | ||||
|         this.url = template.url; | ||||
|  | ||||
|         /** | ||||
|          * The CSS class name to associate with this page, if any. | ||||
|          * The CSS class name to associate with this page, if any. This will be | ||||
|          * an empty string by default. | ||||
|          * | ||||
|          * @type String | ||||
|          */ | ||||
|         this.className = className || ''; | ||||
|         this.className = template.className || ''; | ||||
|  | ||||
|         /** | ||||
|          * A numeric value denoting the relative sort order when compared to | ||||
|          * other sibling PageDefinitions. If unspecified, sort order is | ||||
|          * determined by the system using the PageDefinition. | ||||
|          * | ||||
|          * @type Number | ||||
|          */ | ||||
|         this.weight = template.weight; | ||||
|  | ||||
|     }; | ||||
|  | ||||
|   | ||||
| @@ -34,36 +34,3 @@ | ||||
|     text-align: center; | ||||
|     margin: 1em 0; | ||||
| } | ||||
|  | ||||
| .settings-tabs .page-list { | ||||
|     margin: 0; | ||||
|     padding: 0; | ||||
|     background: rgba(0, 0, 0, 0.0125); | ||||
|     border-bottom: 1px solid rgba(0, 0, 0, 0.05); | ||||
| } | ||||
|  | ||||
| .settings-tabs .page-list li { | ||||
|     display: inline-block; | ||||
|     list-style: none; | ||||
| } | ||||
|  | ||||
| .settings-tabs .page-list li a[href] { | ||||
|     display: block; | ||||
|     color: black; | ||||
|     text-decoration: none; | ||||
|     padding: 0.75em 1em; | ||||
| } | ||||
|  | ||||
| .settings-tabs .page-list li a[href]:visited { | ||||
|     color: black; | ||||
| } | ||||
|  | ||||
| .settings-tabs .page-list li a[href]:hover { | ||||
|     background-color: #CDA; | ||||
| } | ||||
|  | ||||
| .settings-tabs .page-list li a[href].current, | ||||
| .settings-tabs .page-list li a[href].current:hover { | ||||
|     background: rgba(0,0,0,0.3); | ||||
|     cursor: default; | ||||
| } | ||||
|   | ||||
| @@ -28,7 +28,7 @@ THE SOFTWARE. | ||||
|     </div> | ||||
|  | ||||
|     <!-- Available tabs --> | ||||
|     <div class="settings-tabs"> | ||||
|     <div class="page-tabs"> | ||||
|         <guac-page-list pages="settingsPages" ng-show="showAvailableTabs()"></guac-page-list> | ||||
|     </div> | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user