From 3b9280c97477ae1f5fc0e856c9e21c31e2ad070e Mon Sep 17 00:00:00 2001 From: Petr Vobornik Date: Thu, 7 Nov 2013 18:03:38 +0100 Subject: RCUE Header https://fedorahosted.org/freeipa/ticket/3902 --- install/ui/src/freeipa/widgets/App.js | 155 +++++++++++------ install/ui/src/freeipa/widgets/DropdownWidget.js | 211 +++++++++++++++++++++++ 2 files changed, 312 insertions(+), 54 deletions(-) create mode 100644 install/ui/src/freeipa/widgets/DropdownWidget.js (limited to 'install/ui/src/freeipa/widgets') diff --git a/install/ui/src/freeipa/widgets/App.js b/install/ui/src/freeipa/widgets/App.js index e89d4cc61..42705649f 100644 --- a/install/ui/src/freeipa/widgets/App.js +++ b/install/ui/src/freeipa/widgets/App.js @@ -31,10 +31,11 @@ define(['dojo/_base/declare', 'dojo/Evented', 'dojo/Stateful', './Menu', + './DropdownWidget', 'dojo/NodeList-dom' ], function(declare, lang, array, dom, construct, prop, dom_class, - dom_style, query, on, Stateful, Evented, Menu) { + dom_style, query, on, Stateful, Evented, Menu, DropdownWidget) { /** * Main application widget @@ -59,14 +60,8 @@ define(['dojo/_base/declare', password_expires_node: null, - logged_nodes: null, - logged_user_node: null, - logged_user_link_node: null, - - logout_link_node: null, - menu_node: null, content_node: null, @@ -77,9 +72,7 @@ define(['dojo/_base/declare', _loggedSetter: function(value) { this.logged = value; - if (this.logged_nodes) { - this.logged_nodes.style('visibility', value ? 'visible' : 'hidden'); - } + //TODO show/hide menu }, fullname: '', @@ -92,8 +85,6 @@ define(['dojo/_base/declare', }, render: function() { - // TODO: this method may be split into several components - this.domNode = construct.create('div', { id: this.app_id, @@ -106,9 +97,6 @@ define(['dojo/_base/declare', this._render_header(); - this.menu_node = this.menu_widget.render(); - construct.place(this.menu_node, this.header_node); - this.content_node = construct.create('div', { 'class': 'content' }, this.domNode); @@ -117,57 +105,116 @@ define(['dojo/_base/declare', _render_header: function() { this.header_node = construct.create('div', { 'class': 'header rcue' - }, this.domNode); + }); - // logo - construct.place(''+ - '', this.header_node); - - // right part - construct.place(''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - '', this.header_node); - - - this.password_expires_node = query('.header-passwordexpires', this.header_node)[0]; - this.logged_nodes = query('.header-loggedinas', this.header_node); - this.logged_header_node = query('.login_header')[0]; - this.logged_user_node = query('.loggedinas .login', this.header_node)[0]; - this.logged_user_link_node = query('.loggedinas a', this.header_node)[0]; - this.logout_link_node = query('.logout')[0]; - - on(this.logout_link_node, 'click', lang.hitch(this,this.on_logout)); - on(this.logged_user_link_node, 'click', lang.hitch(this,this.on_profile)); + this._render_nav_util(); + construct.place(this.nav_util_node, this.header_node); + + this.menu_node = this.menu_widget.render(); + construct.place(this.menu_node, this.header_node); construct.place(this.header_node, this.domNode); }, - on_profile: function(event) { - event.preventDefault(); - this.emit('profile-click'); + _render_nav_util: function() { + this.nav_util_node = construct.create('div', { + 'class': 'navbar utility' + }); + + this.nav_util_inner_node = construct.create('div', { + 'class': 'navbar-inner' + }, this.nav_util_node); + + this._render_brand(); + construct.place(this.brand_node, this.nav_util_inner_node); + + this.nav_util_tool_node = construct.create('ul', { + 'class': 'nav pull-right' + }, this.nav_util_inner_node); + + this.password_expires_node = construct.create('li', { + 'class': 'header-passwordexpires' + }, this.nav_util_tool_node); + + var network_activity = construct.create('li', { + 'class': 'header-network-activity-indicator network-activity-indicator' + }, this.nav_util_tool_node); + + construct.create('img', { + 'src': 'images/spinner-header.gif' + }, network_activity); + + var user_toggle = this._render_user_toggle_nodes(); + this.user_menu.set('toggle_content', user_toggle); + construct.place(this.user_menu.render(), this.nav_util_tool_node); + + return this.nav_util_node; + }, + + _render_brand: function() { + this.brand_node = construct.create('a', { + 'class': 'brand', + href: '#' + }); + + construct.create('img', { + src: 'images/header-logo.png', + alt: 'FreeIPA' // TODO: replace with configuration value + }, this.brand_node); + + return this.brand_node; }, - on_logout: function(event) { - event.preventDefault(); - this.emit('logout-click'); + _render_user_toggle_nodes: function() { + + var nodes = []; + + nodes.push(construct.create('span', { + 'class': 'icon-user icon-white' + })); + + this.logged_user_node = construct.create('span', { + 'class': 'loggedinas' + }); + nodes.push(this.logged_user_node); + + nodes.push(construct.create('b', { + 'class': 'caret' + })); + + return nodes; + }, + + on_user_menu_click: function(item) { + + if (item.name === 'profile') { + this.emit('profile-click'); + } else if (item.name === 'logout') { + this.emit('logout-click'); + } }, constructor: function(spec) { spec = spec || {}; this.menu_widget = new Menu(); + this.user_menu = new DropdownWidget({ + el_type: 'li', + name: 'profile-menu', + items: [ + { + name: 'profile', + label: 'Profile' + }, + { + 'class': 'divider' + }, + { + name: 'logout', + label: 'Logout' + } + ] + }); + on(this.user_menu, 'item-click', lang.hitch(this, this.on_user_menu_click)); } }); diff --git a/install/ui/src/freeipa/widgets/DropdownWidget.js b/install/ui/src/freeipa/widgets/DropdownWidget.js new file mode 100644 index 000000000..992bcf378 --- /dev/null +++ b/install/ui/src/freeipa/widgets/DropdownWidget.js @@ -0,0 +1,211 @@ +/* Authors: + * Petr Vobornik + * + * Copyright (C) 2013 Red Hat + * see file 'COPYING' for use and warranty information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ +define(['dojo/_base/declare', + 'dojo/_base/array', + 'dojo/_base/lang', + 'dojo/dom', + 'dojo/dom-construct', + 'dojo/dom-prop', + 'dojo/dom-class', + 'dojo/dom-style', + 'dojo/dom-attr', + 'dojo/query', + 'dojo/Evented', + 'dojo/Stateful', + 'dojo/on', + '../jquery', + '../ipa'], function(declare, array, lang, dom, construct, prop, dom_class, + dom_style, attr, query, Evented, Stateful, on, $, IPA) { + + return declare([Stateful, Evented], { + /** + * Represents and creates a dropdown widget. It can contain multiple + * levels. + * + * @class widgets.DropdownWidget + */ + + /** + * Raised when menu item is clicked + * @event item-click + */ + + /** + * Dropdown name + * @property {string} + */ + name: '', + + /** + * Element type + * @property {string} + */ + el_type: 'div', + + /** + * Element class + * @property {string} + */ + 'class': 'dropdown', + + /** + * Submenu class + */ + submenu_class: 'dropdown-submenu', + + /** + * Toggle button text + * @property {string} + */ + toggle_text: '', + + /** + * Toggle button content. Replaces toggle button text if set. Can be + * use for more complex toggle buttons. + * @property {HTMLElement|HTMLElement[]} + */ + toggle_content: null, + + /** + * Array of dropdown items to display. Item can have `items` field + * with an array of child items. + * @property {Array} + */ + items: [], + + /** + * domNode of this widget + * @property {HTMLElement} + */ + dom_node: null, + + render: function() { + if (this.dom_node) { + construct.empty(this.dom_node); + + } else { + this.dom_node = construct.create(this.el_type, { + name: this.name || '', + 'class': this['class'] + }); + } + + this._render_toggle(this.dom_node); + this._render_items(this.items, this.dom_node); + + return this.dom_node; + }, + + _render_toggle: function(container) { + + this.toggle_node = construct.create('a', { + 'class': 'dropdown-toggle', + 'data-toggle': 'dropdown', + href: '#' + }); + + this._update_toggle(); + if (container) { + construct.place(this.toggle_node, container); + } + return this.toggle_node; + }, + + _update_toggle: function() { + if (!this.toggle_node) return; + if (this.toggle_content) { + if (lang.isArray(this.toggle_content)) { + array.forEach(this.toggle_content, function(item) { + construct.place(item, this.toggle_node); + }, this); + } else { + construct.place(this.toggle_content, this.toggle_node); + } + } else { + prop.set(this.toggle_node, 'textContent', this.toggle_text); + } + }, + + _toggle_textSetter: function(value) { + this.toggle_text = value; + this._update_toggle(); + }, + + _toggle_contentSetter: function(value) { + this.toggle_content = value; + this._update_toggle(); + }, + + _render_items: function(items, container) { + var ul = construct.create('ul', { + 'class': 'dropdown-menu' + }); + + array.forEach(items, function(item) { + this._render_item(item, ul); + }, this); + + if (container) { + construct.place(ul, container); + } + return ul; + }, + + _render_item: function(item, container) { + + var li = construct.create('li', { + 'data-name': item.name || '' + }); + var a = construct.create('a', { + 'href': '#' + item.name || '', + innerHTML: item.label || '' + }, li); + + if (item['class']) { + dom_class.add(li, item['class']); + } + + if (item.items && item.items.length > 0) { + dom_class.add(li, 'dropdown-submenu'); + this._render_items(item.items, li); + } else { + on(a, 'click', lang.hitch(this, function(event) { + this.on_item_click(event, item); + event.preventDefault(); + })); + } + + if (container) { + construct.place(li, container); + } + return li; + }, + + on_item_click: function(event, item) { + + if (item.click) item.click(); + this.emit('item-click', item); + }, + + constructor: function(spec) { + declare.safeMixin(this, spec); + } + }); +}); -- cgit