diff --git a/doc/config.rst b/doc/config.rst index 00410e7c66..163913fae0 100644 --- a/doc/config.rst +++ b/doc/config.rst @@ -1391,7 +1391,7 @@ Navigation panel setup .. config:option:: $cfg['FirstLevelNavigationItems'] :type: integer - :default: 25 + :default: 100 The number of first level databases that can be displayed on each page of navigation tree. diff --git a/js/common.js b/js/common.js index ed7b44d551..44bfaaac9e 100644 --- a/js/common.js +++ b/js/common.js @@ -31,11 +31,11 @@ var PMA_commonParams = (function () { var updateNavigation = false; for (var i in obj) { if (params[i] !== undefined && params[i] !== obj[i]) { + if (i == 'db' || i == 'table') { + updateNavigation = true; + } reload = true; } - if (i == 'db' || i == 'table') { - updateNavigation = true; - } params[i] = obj[i]; } if (updateNavigation && @@ -65,7 +65,9 @@ var PMA_commonParams = (function () { */ set: function (name, value) { var updateNavigation = false; - if (name == 'db' || name == 'table') { + if (name == 'db' || name == 'table' + && params[name] !== value + ) { updateNavigation = true; } params[name] = value; diff --git a/js/navigation.js b/js/navigation.js index 7a3057a991..4d10dda9a1 100644 --- a/js/navigation.js +++ b/js/navigation.js @@ -8,42 +8,66 @@ /** * Loads child items of a node and executes a given callback * + * @param isNode * @param $expandElem expander * @param callback callback function * * @returns void */ -function loadChildNodes($expandElem, callback) { - if (!$expandElem.hasClass('expander')) { - return; - } - var $destination = $expandElem.closest('li'); +function loadChildNodes(isNode, $expandElem, callback) { + if (isNode) { + if (!$expandElem.hasClass('expander')) { + return; + } + var $destination = $expandElem.closest('li'); + var searchClause = PMA_fastFilter.getSearchClause(); + var searchClause2 = PMA_fastFilter.getSearchClause2($expandElem); - var searchClause = PMA_fastFilter.getSearchClause(); - var searchClause2 = PMA_fastFilter.getSearchClause2($expandElem); - - var params = { - aPath: $expandElem.find('span.aPath').text(), - vPath: $expandElem.find('span.vPath').text(), - pos: $expandElem.find('span.pos').text(), - pos2_name: $expandElem.find('span.pos2_name').text(), - pos2_value: $expandElem.find('span.pos2_value').text(), - searchClause: '', - searchClause2: '' - }; - - if ($expandElem.closest('ul').hasClass('search_results') - ) { - params.searchClause = searchClause; - params.searchClause2 = searchClause2; + var params = { + aPath: $expandElem.find('span.aPath').text(), + vPath: $expandElem.find('span.vPath').text(), + pos: $expandElem.find('span.pos').text(), + pos2_name: $expandElem.find('span.pos2_name').text(), + pos2_value: $expandElem.find('span.pos2_value').text(), + searchClause: '', + searchClause2: '' + }; + if ($expandElem.closest('ul').hasClass('search_results') + ) { + params.searchClause = searchClause; + params.searchClause2 = searchClause2; + } + } else { + var $destination = $('#pma_navigation_tree_content'); + var params = { + aPath: $expandElem.attr('aPath'), + vPath: $expandElem.attr('vPath'), + pos: $expandElem.attr('pos'), + pos2_name: '', + pos2_value: '', + searchClause: '', + searchClause2: '' + }; } var url = $('#pma_navigation').find('a.navigation_url').attr('href'); $.get(url, params, function (data) { if (typeof data !== 'undefined' && data.success === true) { - $expandElem.addClass('loaded'); $destination.find('div.list_container').remove(); // FIXME: Hack, there shouldn't be a list container there - $destination.append(data.message); + if (isNode) { + $destination.append(data.message); + $expandElem.addClass('loaded'); + } else { + $destination.html(data.message); + $destination.children() + .first() + .css({ + border: '0px', + margin: '0em', + padding : '0em' + }) + .slideDown('slow'); + } if (data._debug){ $('#session_debug').replaceWith(data._debug); } @@ -141,6 +165,10 @@ $(function () { $icon.attr('src', icon_reload_src); }, 1000); }); + + $(document).on("change", '#navi_db_select', function (event) { + $(this).closest('form').trigger('submit'); + }); /** * Register event handler for click on the collapse all @@ -391,10 +419,6 @@ $(function () { }); }); - if ($('#pma_navigation_tree').hasClass('synced')) { - PMA_showCurrentNavigation(); - } - // Add/Remove favorite table using Ajax. $(document).on("click", ".favorite_table_anchor", function (event) { event.preventDefault(); @@ -445,7 +469,9 @@ $(function () { storage.removeItem('navTree'); }); // Initialize if no previous state is defined - if (typeof storage.navTree === 'undefined') { + if ( ($('#pma_navigation_tree_content').length && typeof storage.navTree === 'undefined') + || ($('#pma_navigation_db_select').length && typeof storage.navSelect === 'undefined') + ) { navTreeStateUpdate(); } else if (PMA_commonParams.get('server') === storage.server && PMA_commonParams.get('token') === storage.token @@ -453,8 +479,16 @@ $(function () { // Restore the tree from storage $('#pma_navigation_tree_content').html(storage.navTree); $('div.pageselector.dbselector').html(storage.page); + $('#pma_navigation_db_select').html(storage.navSelect); } } + + if ($('#pma_navigation_tree').hasClass('synced')) { + if ($("#navi_db_select").length) { + $("#navi_db_select").val(PMA_commonParams.get('db')); + } + PMA_showCurrentNavigation(); + } }); /** @@ -470,6 +504,7 @@ function navTreeStateUpdate() { // content to be stored exceeds storage capacity try { storage.setItem('navTree', $('#pma_navigation_tree_content').html()); + storage.setItem('navSelect', $('#pma_navigation_db_select').html()); storage.setItem('server', PMA_commonParams.get('server')); storage.setItem('token', PMA_commonParams.get('token')); storage.setItem('page', $('div.pageselector.dbselector').html()); @@ -478,6 +513,7 @@ function navTreeStateUpdate() { // state is no more valid, so remove it storage.removeItem('navTree'); storage.removeItem('server'); + storage.removeItem('navSelect'); storage.removeItem('token'); storage.removeItem('page'); } @@ -513,7 +549,7 @@ function expandTreeNode($expandElem, callback) { $icon.hide(); $throbber.insertBefore($icon); - loadChildNodes($expandElem, function (data) { + loadChildNodes(true, $expandElem, function (data) { if (typeof data !== 'undefined' && data.success === true) { var $destination = $expandElem.closest('li'); $icon.removeClass('ic_b_plus').addClass('ic_b_minus'); @@ -589,6 +625,24 @@ function PMA_showCurrentNavigation() { } else { handleTableOrDb(table, $dbItem); } + } else if ($('#navi_db_select').length + && $('option:selected', $('#navi_db_select')).length + ) { + if (! PMA_selectCurrentDb()) { + return; + } + // If loaded database in navigation is not same as current one + if ( $('#pma_navigation_tree_content span.loaded_db:first').text() + !== $('#navi_db_select').val() + ) { + loadChildNodes(false, $('option:selected', $('#navi_db_select')), function (data) { + handleTableOrDb(table, $('#pma_navigation_tree_content')); + var $children = $('#pma_navigation_tree_content').children('div.list_container'); + $children.promise().done(navTreeStateUpdate); + }); + } else { + handleTableOrDb(table, $('#pma_navigation_tree_content')); + } } } PMA_showFullName($('#pma_navigation_tree')); @@ -601,6 +655,7 @@ function PMA_showCurrentNavigation() { var $tableContainer = $container.children('ul').children('li.tableContainer'); if ($tableContainer.length > 0) { var $expander = $tableContainer.children('div:first').children('a.expander'); + $tableContainer.addClass('selected'); expandTreeNode($expander, function () { scrollToView($dbItem, true); }); @@ -691,7 +746,7 @@ function PMA_showCurrentNavigation() { } function loadAndShowTableOrView($expander, $relatedContainer, itemName) { - loadChildNodes($expander, function (data) { + loadChildNodes(true, $expander, function (data) { var $whichItem = findLoadedItem( $relatedContainer.children('div.list_container'), itemName, null, true @@ -734,8 +789,13 @@ function PMA_showCurrentNavigation() { function PMA_reloadNavigation(callback) { var params = { reload: true, - pos: $('#pma_navigation_tree').find('a.expander:first > span.pos').text() + pos: $('#pma_navigation_tree div.dbselector select').val() }; + if ($('#navi_db_select').length) { + params.db = PMA_commonParams.get('db'); + requestNaviReload(params); + return; + } // Traverse the navigation tree backwards to generate all the actual // and virtual paths, as well as the positions in the pagination at // various levels, if necessary. @@ -772,22 +832,36 @@ function PMA_reloadNavigation(callback) { count++; } }); - var url = $('#pma_navigation').find('a.navigation_url').attr('href'); - $.post(url, params, function (data) { - if (typeof data !== 'undefined' && data.success) { - $('#pma_navigation_tree').html(data.message).children('div').show(); - if ($('#pma_navigation_tree').hasClass('synced')) { - PMA_showCurrentNavigation(); + requestNaviReload(params); + function requestNaviReload(params) { + var url = $('#pma_navigation').find('a.navigation_url').attr('href'); + $.post(url, params, function (data) { + if (typeof data !== 'undefined' && data.success) { + $('#pma_navigation_tree').html(data.message).children('div').show(); + if ($('#pma_navigation_tree').hasClass('synced')) { + PMA_selectCurrentDb(); + PMA_showCurrentNavigation(); + } + // Fire the callback, if any + if (typeof callback === 'function') { + callback.call(); + } + navTreeStateUpdate(); + } else { + PMA_ajaxShowMessage(data.error); } - // Fire the callback, if any - if (typeof callback === 'function') { - callback.call(); - } - navTreeStateUpdate(); - } else { - PMA_ajaxShowMessage(data.error); + }); + } +} + +function PMA_selectCurrentDb() { + if ($('#navi_db_select').length) { + $('#navi_db_select').val(PMA_commonParams.get('db')); + if ($('#navi_db_select').val() !== PMA_commonParams.get('db')) { + return false; } - }); + return true; + } } /** diff --git a/libraries/Header.class.php b/libraries/Header.class.php index cddcdc569f..dad848345e 100644 --- a/libraries/Header.class.php +++ b/libraries/Header.class.php @@ -237,6 +237,7 @@ class PMA_Header 'db' => $db, 'token' => $_SESSION[' PMA_token '], 'text_dir' => $GLOBALS['text_dir'], + 'show_navigation_as_tree'=> $GLOBALS['cfg']['ShowNavigationAsTree'], 'pma_absolute_uri' => $GLOBALS['cfg']['PmaAbsoluteUri'], 'pma_text_default_tab' => PMA_Util::getTitleForTarget( $GLOBALS['cfg']['DefaultTabTable'] diff --git a/libraries/config.default.php b/libraries/config.default.php index b26de7449f..995270b72c 100644 --- a/libraries/config.default.php +++ b/libraries/config.default.php @@ -810,12 +810,19 @@ $cfg['CaptchaLoginPrivateKey'] = ''; * Navigation panel setup */ +/** + * Whether to display navigation panel as tree or as pre-4.0 style + * + * @global boolean $cfg['ShowNavigationAsTree'] + */ +$cfg['ShowNavigationAsTree'] = true; + /** * maximum number of first level databases displayed in navigation panel * * @global integer $cfg['FirstLevelNavigationItems'] */ -$cfg['FirstLevelNavigationItems'] = 25; +$cfg['FirstLevelNavigationItems'] = 100; /** * maximum number of items displayed in navigation panel diff --git a/libraries/config/messages.inc.php b/libraries/config/messages.inc.php index c9e0083957..36198d23f8 100644 --- a/libraries/config/messages.inc.php +++ b/libraries/config/messages.inc.php @@ -415,6 +415,8 @@ $strConfigMemoryLimit_desc = __( . '([kbd]0[/kbd] for no limit).' ); $strConfigMemoryLimit_name = __('Memory limit'); +$strConfigShowNavigationAsTree_desc = __('Whether to display navigation panel in tree style or in pre-4.0 style'); +$strConfigShowNavigationAsTree_name = __('Show Navigation as tree'); $strConfigNavigationLinkWithMainPanel_desc = __('Link with main panel by highlighting the current database or table.'); $strConfigNavigationLinkWithMainPanel_name = __('Link with main panel'); $strConfigNavigationDisplayLogo_desc = __('Show logo in navigation panel.'); diff --git a/libraries/config/setup.forms.php b/libraries/config/setup.forms.php index 459df114f8..c6809e51b2 100644 --- a/libraries/config/setup.forms.php +++ b/libraries/config/setup.forms.php @@ -162,6 +162,7 @@ $forms['Sql_queries']['Sql_box'] = array('SQLQuery' => array( 'ShowAsPHP', 'Refresh')); $forms['Navi_panel']['Navi_panel'] = array( + 'ShowNavigationAsTree', 'NavigationLinkWithMainPanel', 'NavigationDisplayLogo', 'NavigationLogoLink', diff --git a/libraries/config/user_preferences.forms.php b/libraries/config/user_preferences.forms.php index 17ca1425ab..11a2a6faab 100644 --- a/libraries/config/user_preferences.forms.php +++ b/libraries/config/user_preferences.forms.php @@ -73,6 +73,7 @@ $forms['Sql_queries']['Sql_box'] = array( 'SQLQuery/ShowAsPHP', 'SQLQuery/Refresh'); $forms['Navi_panel']['Navi_panel'] = array( + 'ShowNavigationAsTree', 'NavigationLinkWithMainPanel', 'NavigationDisplayLogo', 'NavigationLogoLink', diff --git a/libraries/navigation/Navigation.class.php b/libraries/navigation/Navigation.class.php index da0bf099e2..39b6180a88 100644 --- a/libraries/navigation/Navigation.class.php +++ b/libraries/navigation/Navigation.class.php @@ -35,29 +35,44 @@ class PMA_Navigation $retval = $header->getDisplay(); } $tree = new PMA_NavigationTree(); - if (! PMA_Response::getInstance()->isAjax() - || ! empty($_REQUEST['full']) - || ! empty($_REQUEST['reload']) + if ($GLOBALS['cfg']['ShowNavigationAsTree'] ) { - $treeRender = $tree->renderState(); - } else { - $treeRender = $tree->renderPath(); - } + if (! PMA_Response::getInstance()->isAjax() + || ! empty($_REQUEST['full']) + || ! empty($_REQUEST['reload']) + ) { + $treeRender = $this->_quickWarp(); + $treeRender .= $tree->renderState(); + } else { + $treeRender = $tree->renderPath(); + } - if (! $treeRender) { - $retval .= PMA_Message::error( - __('An error has occurred while loading the navigation tree') - )->getDisplay(); + if (! $treeRender) { + $retval .= PMA_Message::error( + __('An error has occurred while loading the navigation tree') + )->getDisplay(); + } else { + $retval .= $treeRender; + } } else { - $retval .= $treeRender; + // provide legacy pre-4.0 navigation + if (! PMA_Response::getInstance()->isAjax() + || ! empty($_REQUEST['full']) + || ! empty($_REQUEST['reload']) + ) { + $retval .= $this->_quickWarp(); + $retval .= $tree->renderDbSelect(); + } else { + $retval = $tree->renderPath(); + } } if (! PMA_Response::getInstance()->isAjax()) { // closes the tags that were opened by the navigation header - $retval .= ''; - $retval .= ''; + $retval .= ''; // pma_navigation_tree + $retval .= ''; // pma_navigation_content $retval .= $this->_getDropHandler(); - $retval .= ''; + $retval .= ''; // pma_navigation } return $retval; @@ -219,5 +234,24 @@ class PMA_Navigation $html .= ''; return $html; } + + /** + * Display quick warp links, contain Recents and Favorites + * + * @return string HTML code + */ + private function _quickWarp() + { + $retval = '