mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-07 13:41:21 +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;
|
var linked = dataSource in users;
|
||||||
|
|
||||||
// Add page entry
|
// Add page entry
|
||||||
$scope.accountPages.push(new PageDefinition(
|
$scope.accountPages.push(new PageDefinition({
|
||||||
translationStringService.canonicalize('DATA_SOURCE_' + dataSource) + '.NAME',
|
name : translationStringService.canonicalize('DATA_SOURCE_' + dataSource) + '.NAME',
|
||||||
'/manage/' + encodeURIComponent(dataSource) + '/users/' + encodeURIComponent(username),
|
url : '/manage/' + encodeURIComponent(dataSource) + '/users/' + encodeURIComponent(username),
|
||||||
linked ? 'linked' : 'unlinked'
|
className : linked ? 'linked' : 'unlinked'
|
||||||
));
|
}));
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -28,14 +28,14 @@
|
|||||||
text-transform: none;
|
text-transform: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.manage-user .settings-tabs .page-list li.unlinked a[href],
|
.manage-user .page-tabs .page-list li.unlinked a[href],
|
||||||
.manage-user .settings-tabs .page-list li.linked a[href] {
|
.manage-user .page-tabs .page-list li.linked a[href] {
|
||||||
padding-right: 2.5em;
|
padding-right: 2.5em;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.manage-user .settings-tabs .page-list li.unlinked a[href]:before,
|
.manage-user .page-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.linked a[href]:before {
|
||||||
content: ' ';
|
content: ' ';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
@@ -47,19 +47,19 @@
|
|||||||
background-position: center;
|
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');
|
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;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.manage-user .settings-tabs .page-list li.unlinked a[href]:hover,
|
.manage-user .page-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].current {
|
||||||
opacity: 1;
|
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');
|
background-image: url('images/checkmark.png');
|
||||||
}
|
}
|
||||||
|
@@ -27,7 +27,7 @@ THE SOFTWARE.
|
|||||||
<h2>{{user.username}}</h2>
|
<h2>{{user.username}}</h2>
|
||||||
<guac-user-menu></guac-user-menu>
|
<guac-user-menu></guac-user-menu>
|
||||||
</div>
|
</div>
|
||||||
<div class="settings-tabs">
|
<div class="page-tabs">
|
||||||
<guac-page-list pages="accountPages" ng-show="showAccountTabs()"></guac-page-list>
|
<guac-page-list pages="accountPages" ng-show="showAccountTabs()"></guac-page-list>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@@ -33,7 +33,7 @@ angular.module('navigation').directive('guacPageList', [function guacPageList()
|
|||||||
/**
|
/**
|
||||||
* The array of pages to display.
|
* The array of pages to display.
|
||||||
*
|
*
|
||||||
* @type Page[]
|
* @type PageDefinition[]
|
||||||
*/
|
*/
|
||||||
pages : '='
|
pages : '='
|
||||||
|
|
||||||
@@ -42,13 +42,119 @@ angular.module('navigation').directive('guacPageList', [function guacPageList()
|
|||||||
templateUrl: 'app/navigation/templates/guacPageList.html',
|
templateUrl: 'app/navigation/templates/guacPageList.html',
|
||||||
controller: ['$scope', '$injector', function guacPageListController($scope, $injector) {
|
controller: ['$scope', '$injector', function guacPageListController($scope, $injector) {
|
||||||
|
|
||||||
// Get required services
|
// Required types
|
||||||
|
var PageDefinition = $injector.get('PageDefinition');
|
||||||
|
|
||||||
|
// Required services
|
||||||
var $location = $injector.get('$location');
|
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.
|
* Navigate to the given page.
|
||||||
*
|
*
|
||||||
* @param {Page} page
|
* @param {PageDefinition} page
|
||||||
* The page to navigate to.
|
* The page to navigate to.
|
||||||
*/
|
*/
|
||||||
$scope.navigateToPage = function navigateToPage(page) {
|
$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.
|
* Tests whether the given page is the page currently being viewed.
|
||||||
*
|
*
|
||||||
* @param {Page} page
|
* @param {PageDefinition} page
|
||||||
* The page to test.
|
* The page to test.
|
||||||
*
|
*
|
||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
* true if the given page is the current page, false otherwise.
|
* true if the given page is the current page, false otherwise.
|
||||||
*/
|
*/
|
||||||
$scope.isCurrentPage = function isCurrentPage(page) {
|
$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
|
}] // end controller
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@@ -41,31 +41,16 @@ angular.module('navigation').factory('userPageService', ['$injector',
|
|||||||
|
|
||||||
var service = {};
|
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
|
* The home page to assign to a user if they can navigate to more than one
|
||||||
* page.
|
* page.
|
||||||
*
|
*
|
||||||
* @type PageDefinition
|
* @type PageDefinition
|
||||||
*/
|
*/
|
||||||
var SYSTEM_HOME_PAGE = new PageDefinition(
|
var SYSTEM_HOME_PAGE = new PageDefinition({
|
||||||
'USER_MENU.ACTION_NAVIGATE_HOME',
|
name : 'USER_MENU.ACTION_NAVIGATE_HOME',
|
||||||
'/'
|
url : '/'
|
||||||
);
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an appropriate home page for the current user.
|
* 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
|
// Only one connection present, use as home page
|
||||||
if (connection) {
|
if (connection) {
|
||||||
homePage = new PageDefinition(
|
homePage = new PageDefinition({
|
||||||
connection.name,
|
name : connection.name,
|
||||||
'/client/' + ClientIdentifier.toString({
|
url : '/client/' + ClientIdentifier.toString({
|
||||||
dataSource : dataSource,
|
dataSource : dataSource,
|
||||||
type : ClientIdentifier.Types.CONNECTION,
|
type : ClientIdentifier.Types.CONNECTION,
|
||||||
id : connection.identifier
|
id : connection.identifier
|
||||||
})
|
})
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only one balancing group present, use as home page
|
// Only one balancing group present, use as home page
|
||||||
@@ -116,14 +101,14 @@ angular.module('navigation').factory('userPageService', ['$injector',
|
|||||||
&& connectionGroup.type === ConnectionGroup.Type.BALANCING
|
&& connectionGroup.type === ConnectionGroup.Type.BALANCING
|
||||||
&& _.isEmpty(connectionGroup.childConnections)
|
&& _.isEmpty(connectionGroup.childConnections)
|
||||||
&& _.isEmpty(connectionGroup.childConnectionGroups)) {
|
&& _.isEmpty(connectionGroup.childConnectionGroups)) {
|
||||||
homePage = new PageDefinition(
|
homePage = new PageDefinition({
|
||||||
connectionGroup.name,
|
name : connectionGroup.name,
|
||||||
'/client/' + ClientIdentifier.toString({
|
url : '/client/' + ClientIdentifier.toString({
|
||||||
dataSource : dataSource,
|
dataSource : dataSource,
|
||||||
type : ClientIdentifier.Types.CONNECTION_GROUP,
|
type : ClientIdentifier.Types.CONNECTION_GROUP,
|
||||||
id : connectionGroup.identifier
|
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 user can manage sessions, add link to sessions management page
|
||||||
if (canManageSessions) {
|
if (canManageSessions) {
|
||||||
pages.push(new PageDefinition(
|
pages.push(new PageDefinition({
|
||||||
'USER_MENU.ACTION_MANAGE_SESSIONS',
|
name : 'USER_MENU.ACTION_MANAGE_SESSIONS',
|
||||||
'/settings/sessions'
|
url : '/settings/sessions'
|
||||||
));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If user can manage users, add link to user management page
|
// If user can manage users, add link to user management page
|
||||||
if (canManageUsers) {
|
if (canManageUsers) {
|
||||||
pages.push(new PageDefinition(
|
pages.push(new PageDefinition({
|
||||||
'USER_MENU.ACTION_MANAGE_USERS',
|
name : 'USER_MENU.ACTION_MANAGE_USERS',
|
||||||
'/settings/users'
|
url : '/settings/users'
|
||||||
));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If user can manage connections, add link to connections management page
|
// If user can manage connections, add link to connections management page
|
||||||
if (canManageConnections) {
|
if (canManageConnections) {
|
||||||
pages.push(new PageDefinition(
|
pages.push(new PageDefinition({
|
||||||
'USER_MENU.ACTION_MANAGE_CONNECTIONS',
|
name : 'USER_MENU.ACTION_MANAGE_CONNECTIONS',
|
||||||
'/settings/connections'
|
url : '/settings/connections'
|
||||||
));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add link to user preferences (always accessible)
|
// Add link to user preferences (always accessible)
|
||||||
pages.push(new PageDefinition(
|
pages.push(new PageDefinition({
|
||||||
'USER_MENU.ACTION_MANAGE_PREFERENCES',
|
name : 'USER_MENU.ACTION_MANAGE_PREFERENCES',
|
||||||
'/settings/preferences'
|
url : '/settings/preferences'
|
||||||
));
|
}));
|
||||||
|
|
||||||
return pages;
|
return pages;
|
||||||
};
|
};
|
||||||
@@ -338,10 +323,10 @@ angular.module('navigation').factory('userPageService', ['$injector',
|
|||||||
|
|
||||||
// Add generic link to the first-available settings page
|
// Add generic link to the first-available settings page
|
||||||
if (settingsPages.length) {
|
if (settingsPages.length) {
|
||||||
pages.push(new PageDefinition(
|
pages.push(new PageDefinition({
|
||||||
'USER_MENU.ACTION_MANAGE_SETTINGS',
|
name : 'USER_MENU.ACTION_MANAGE_SETTINGS',
|
||||||
settingsPages[0].url
|
url : settingsPages[0].url
|
||||||
));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
return pages;
|
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
|
Copyright (C) 2015 Glyptodon LLC
|
||||||
|
|
||||||
@@ -22,11 +22,13 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- Navigation links -->
|
<!-- Navigation links -->
|
||||||
<li ng-repeat="page in pages" class="{{page.className}}">
|
<ul class="page-list-level" ng-repeat="level in levels track by $index">
|
||||||
<a class="home" ng-click="navigateToPage(page)"
|
<li ng-repeat="page in getPages(level)" class="{{page.className}}">
|
||||||
ng-class="{current: isCurrentPage(page)}" href="#{{page.url}}">
|
<a class="home" ng-click="navigateToPage(page)"
|
||||||
{{page.name | translate}}
|
ng-class="{current: isCurrentPage(page)}" href="#{{page.url}}">
|
||||||
</a>
|
{{page.name | translate}}
|
||||||
</li>
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
</ul>
|
</div>
|
||||||
|
@@ -30,37 +30,46 @@ angular.module('navigation').factory('PageDefinition', [function definePageDefin
|
|||||||
* an arbitrary, human-readable name.
|
* an arbitrary, human-readable name.
|
||||||
*
|
*
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {String} name
|
* @param {PageDefinition|Object} template
|
||||||
* The the name of the page, which should be a translation table key.
|
* The object whose properties should be copied within the new
|
||||||
*
|
* PageDefinition.
|
||||||
* @param {String} url
|
|
||||||
* The URL of the page.
|
|
||||||
*
|
|
||||||
* @param {String} [className='']
|
|
||||||
* The CSS class name to associate with this page, if any.
|
|
||||||
*/
|
*/
|
||||||
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.
|
* 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.
|
* The URL of the page.
|
||||||
*
|
*
|
||||||
* @type String
|
* @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
|
* @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;
|
text-align: center;
|
||||||
margin: 1em 0;
|
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>
|
</div>
|
||||||
|
|
||||||
<!-- Available tabs -->
|
<!-- Available tabs -->
|
||||||
<div class="settings-tabs">
|
<div class="page-tabs">
|
||||||
<guac-page-list pages="settingsPages" ng-show="showAvailableTabs()"></guac-page-list>
|
<guac-page-list pages="settingsPages" ng-show="showAvailableTabs()"></guac-page-list>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user