webui: change navigation from RCUE to PatternFly

Mainly html and css changes.

Second level menus are absolutely positioned and so they don't adjust container
size making other elements to overlap.

side effect partially fixes:
https://fedorahosted.org/freeipa/ticket/3435

Reviewed-By: Endi Sukma Dewata <edewata@redhat.com>
This commit is contained in:
Petr Vobornik 2014-04-01 12:09:44 +02:00
parent 0e15a282e8
commit 3eaa69a686
4 changed files with 119 additions and 52 deletions

View File

@ -318,7 +318,7 @@ var IPA = function () {
*/
that.display_activity_icon = function() {
that.network_call_count++;
$('.network-activity-indicator').css('visibility', 'visible');
$('.network-activity-indicator').css('display', '');
if (that.network_call_count === 1) {
topic.publish('network-activity-start');
}
@ -333,7 +333,7 @@ var IPA = function () {
that.network_call_count--;
if (0 === that.network_call_count) {
$('.network-activity-indicator').css('visibility', 'hidden');
$('.network-activity-indicator').css('display', 'none');
topic.publish('network-activity-end');
}
};
@ -583,14 +583,14 @@ IPA.reset_password = function(username, old_password, new_password) {
*/
IPA.update_password_expiration = function() {
var now, expires, notify_days, diff, message, container;
var now, expires, notify_days, diff, message, container, notify;
expires = IPA.whoami.krbpasswordexpiration;
expires = expires ? datetime.parse(expires[0]) : null;
notify_days = IPA.server_config.ipapwdexpadvnotify;
notify_days = notify_days ? notify_days[0] : 0;
notify = false;
now = new Date();
container = $('.header-passwordexpires');
@ -602,11 +602,13 @@ IPA.update_password_expiration = function() {
diff = Math.floor(diff / 86400000);
if (diff <= notify_days) {
notify = true;
message = text.get('@i18n:password.expires_in');
message = message.replace('${days}', diff);
container.append(message);
}
}
container.toggle(notify);
};
/**

View File

@ -92,42 +92,71 @@ define(['dojo/_base/declare',
construct.place(this.dom_node, this.container_node);
}
this._render_header();
this._render_navigation();
this.content_node = construct.create('div', {
'class': 'content'
}, this.dom_node);
},
_render_header: function() {
this.header_node = construct.create('div', {
'class': 'header rcue'
_render_navigation: function() {
this.nav_node = construct.create('nav', {
'class': 'navbar navbar-default navbar-pf',
role: 'navigation'
});
this._render_nav_header();
construct.place(this.header_node, this.nav_node);
this._render_nav_util();
construct.place(this.nav_util_node, this.header_node);
construct.place(this.nav_util_node, this.nav_node);
this.menu_node = this.menu_widget.render();
construct.place(this.menu_node, this.header_node);
construct.place(this.menu_node, this.nav_util_node);
construct.place(this.header_node, this.dom_node);
construct.place(this.nav_node, this.dom_node);
},
_render_nav_header: function() {
this.header_node = construct.create('div', {
'class': 'navbar-header'
}, this.nav_node);
var button = construct.create('button', {
'class': 'navbar-toggle',
'data-toggle': 'collapse',
'data-target': '.navbar-collapse-21'
});
construct.create('span', {
'class': 'sr-only',
innerHTML: 'Toggle navigation'
}, button);
construct.create('span', { 'class': 'icon-bar' }, button);
construct.create('span', { 'class': 'icon-bar' }, button);
construct.create('span', { 'class': 'icon-bar' }, button);
construct.place(button, this.header_node);
this._render_brand();
construct.place(this.brand_node, this.header_node);
return this.header_node;
},
_render_nav_util: function() {
this.nav_util_node = construct.create('div', {
'class': 'navbar utility'
});
'class': 'collapse navbar-collapse navbar-collapse-21'
}, this.nav_node);
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);
'class': 'nav navbar-nav navbar-utility'
}, this.nav_util_node);
this.password_expires_node = construct.create('li', {
'class': 'header-passwordexpires'
@ -150,7 +179,7 @@ define(['dojo/_base/declare',
_render_brand: function() {
this.brand_node = construct.create('a', {
'class': 'brand',
'class': 'navbar-brand',
href: '#'
});
@ -182,6 +211,19 @@ define(['dojo/_base/declare',
return nodes;
},
collapse_menu: function() {
if (this.nav_util_node) {
var $nav = $(this.nav_util_node);
if ($nav.hasClass('in')) {
$nav.collapse('hide');
}
}
},
on_menu_item_click: function(item) {
this.collapse_menu();
},
on_user_menu_click: function(item) {
if (item.name === 'profile') {
@ -193,6 +235,7 @@ define(['dojo/_base/declare',
} else if (item.name == 'about') {
this.emit('about-click');
}
this.collapse_menu();
},
constructor: function(spec) {
@ -231,6 +274,7 @@ define(['dojo/_base/declare',
]
});
on(this.user_menu, 'item-click', lang.hitch(this, this.on_user_menu_click));
on(this.menu_widget, 'item-select', lang.hitch(this, this.on_menu_item_click));
}
});

View File

@ -78,17 +78,10 @@ define(['dojo/_base/declare',
render: function() {
if (this.dom_node) {
construct.empty(this.dom_node);
} else {
this.dom_node = construct.create('div', {
'class': 'navbar primary persistent-secondary'
});
}
this.innerNode = construct.create('div', {
'class': 'navbar-inner'
}, this.dom_node);
if (this.menu) {
this._render_children(null, null, this.innerNode, 1);
}
this.dom_node = this._render_children(null, null, this.dom_node, null, 1);
return this.dom_node;
},
@ -96,19 +89,24 @@ define(['dojo/_base/declare',
* Render submenu container of given level
*
* @protected
* @param {HTMLElement} node Node to add the container to.
* @param {Number} level submenu level
*/
_render_level_container: function(node, level) {
_render_level_container: function(level, parent) {
var lvl_class = this._get_lvl_class(level);
var type_cls = 'nav';
if (level === 2) type_cls = 'persistent';
if (level > 2) type_cls = 'dropdown-menu';
if (level === 1) {
type_cls = 'nav navbar-nav navbar-primary persistent-secondary';
} else if (level === 2) {
type_cls = 'nav navbar-nav navbar-persistent';
} else {
type_cls = 'dropdown-menu';
}
var cont = construct.create('ul', {
'class': type_cls + ' ' + lvl_class
}, node);
});
return cont;
},
@ -143,7 +141,7 @@ define(['dojo/_base/declare',
this._update_item(menu_item, item_node);
// create submenu
this._render_children(menu_item, children, item_node, level + 1);
this._render_children(menu_item, children, null, item_node, level + 1);
construct.place(item_node, container);
},
@ -154,24 +152,35 @@ define(['dojo/_base/declare',
*
* @protected
* @param {navigation.MenuItem|null} menu_item
* @param {HTMLElement} container
* @param {Object|null} children query result
* @param {HTMLElement|null} item_container container for children
* @param {HTMLElement|null} container container for item_container
* @param {number} level
*/
_render_children: function(menu_item, children, container, level) {
_render_children: function(menu_item, children, item_container, container, level) {
if (children === null) {
children = this._get_children(menu_item);
}
if (children.total > 0) {
var item_container = this._render_level_container(container, level);
if (!item_container) {
item_container = this._render_level_container(level, container);
}
if (children.total > 0) {
array.forEach(children, function(menu_item) {
this._render_item(menu_item, item_container, level);
}, this);
construct.place(item_container, container);
}
if (container) {
construct.place(item_container, container);
// use jQuery resize to make use of window.resize throttling
$(window).bind('resize', lang.hitch(this, function() {
this._adjust_size(container, item_container, level);
}));
}
return item_container;
},
_get_children: function(menu_item) {
@ -240,15 +249,10 @@ define(['dojo/_base/declare',
// show and update selected
array.forEach(menu_items, function(item) {
this._update_item(item);
// show submenu
var item_div = query('div[data-item=\''+item.name+'\']', this.dom_node)[0];
if (item_div) {
dom_style.set(item_div, {
display: 'block'
});
}
}, this);
// to force adjusting of item sizes
$(window).trigger('resize');
},
/**
@ -306,6 +310,23 @@ define(['dojo/_base/declare',
*/
item_clicked: function(menu_item/*, event*/) {
this._item_clicked(menu_item);
},
/**
* Adjust parent size according to child size
* @param {HTMLElement} parent parent menu item container
* @param {HTMLElement} child child menu item container
* @param {number} level level of the child menu item
*/
_adjust_size: function(parent, child, level) {
if (level !== 2) return;
var child_height = dom_style.get(child, 'height');
var absolute = dom_style.get(child, 'position') === 'absolute';
if (child_height && absolute) {
dom_style.set(parent, 'marginBottom', child_height+'px');
}
}
});
});

View File

@ -201,7 +201,7 @@ class test_user(UI_driver):
self.logout()
self.init_app(user.PKEY, pwd)
header = self.find('.header', By.CSS_SELECTOR)
header = self.find('.navbar-pf', By.CSS_SELECTOR)
self.assert_text(
'.header-passwordexpires',
'Your password expires in 6 days.',