From ce887d55c2e5650fcd2f40a4d6f44ba1b3edec01 Mon Sep 17 00:00:00 2001 From: epriestley Date: Wed, 11 Jun 2014 10:39:23 -0700 Subject: [PATCH] Use JS to manage dashboard tab panels Summary: Fixes T5271. This is mostly similar to normal tab panel JS, but I think we'll eventually do async rendering and/or saved tabs so it's reasonable to split it out. Test Plan: Toggled tabs on a tab panel, saw tab selected state change. Reviewers: btrahan, chad Reviewed By: chad Subscribers: epriestley Maniphest Tasks: T5271 Differential Revision: https://secure.phabricator.com/D9478 --- resources/celerity/map.php | 18 ++++++--- .../PhabricatorDashboardPanelTypeTabs.php | 38 +++++++++++-------- .../dashboard/behavior-dashboard-tab-panel.js | 38 +++++++++++++++++++ 3 files changed, 73 insertions(+), 21 deletions(-) create mode 100644 webroot/rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 9a30568d5d..d7c858ec60 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -345,6 +345,7 @@ return array( 'rsrc/js/application/countdown/timer.js' => '361e3ed3', 'rsrc/js/application/dashboard/behavior-dashboard-async-panel.js' => '469c0d9e', 'rsrc/js/application/dashboard/behavior-dashboard-move-panels.js' => 'fa187a68', + 'rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js' => 'aa077691', 'rsrc/js/application/differential/ChangesetViewManager.js' => 'db09a523', 'rsrc/js/application/differential/DifferentialInlineCommentEditor.js' => 'f2441746', 'rsrc/js/application/differential/behavior-add-reviewers-and-ccs.js' => '533a187b', @@ -545,6 +546,7 @@ return array( 'javelin-behavior-dark-console' => 'e9fdb5e5', 'javelin-behavior-dashboard-async-panel' => '469c0d9e', 'javelin-behavior-dashboard-move-panels' => 'fa187a68', + 'javelin-behavior-dashboard-tab-panel' => 'aa077691', 'javelin-behavior-device' => '03d6ed07', 'javelin-behavior-differential-add-reviewers-and-ccs' => '533a187b', 'javelin-behavior-differential-comment-jump' => '71755c79', @@ -1260,6 +1262,11 @@ return array( 2 => 'javelin-util', 3 => 'phabricator-shaped-request', ), + '7319e029' => + array( + 0 => 'javelin-behavior', + 1 => 'javelin-dom', + ), '62e18640' => array( 0 => 'javelin-install', @@ -1332,11 +1339,6 @@ return array( 1 => 'javelin-stratcom', 2 => 'javelin-dom', ), - '7319e029' => - array( - 0 => 'javelin-behavior', - 1 => 'javelin-dom', - ), '76f4ebed' => array( 0 => 'javelin-install', @@ -1612,6 +1614,12 @@ return array( 1 => 'javelin-stratcom', 2 => 'javelin-dom', ), + 'aa077691' => + array( + 0 => 'javelin-behavior', + 1 => 'javelin-dom', + 2 => 'javelin-stratcom', + ), 'ad7a69ca' => array( 0 => 'javelin-install', diff --git a/src/applications/dashboard/paneltype/PhabricatorDashboardPanelTypeTabs.php b/src/applications/dashboard/paneltype/PhabricatorDashboardPanelTypeTabs.php index 2386eabcfb..5e192e4677 100644 --- a/src/applications/dashboard/paneltype/PhabricatorDashboardPanelTypeTabs.php +++ b/src/applications/dashboard/paneltype/PhabricatorDashboardPanelTypeTabs.php @@ -45,30 +45,18 @@ final class PhabricatorDashboardPanelTypeTabs $selected = 0; - // TODO: Instead of using reveal-content here, we should write some nice - // JS which loads panels on demand, manages tab selected states, and maybe - // saves the tab you selected. - $node_ids = array(); foreach ($config as $idx => $tab_spec) { $node_ids[$idx] = celerity_generate_unique_node_id(); } - Javelin::initBehavior('phabricator-reveal-content'); - foreach ($config as $idx => $tab_spec) { - $hide_ids = $node_ids; - unset($hide_ids[$idx]); - $list->addMenuItem( id(new PHUIListItemView()) ->setHref('#') - ->addSigil('reveal-content') - ->setMetadata( - array( - 'showIDs' => array(idx($node_ids, $idx)), - 'hideIDs' => array_values($hide_ids), - )) + ->setSelected($idx == $selected) + ->addSigil('dashboard-tab-panel-tab') + ->setMetadata(array('idx' => $idx)) ->setName(idx($tab_spec, 'name', pht('Nameless Tab')))); } @@ -85,6 +73,12 @@ final class PhabricatorDashboardPanelTypeTabs $parent_phids = $engine->getParentPanelPHIDs(); $parent_phids[] = $panel->getPHID(); + // TODO: Currently, we'll load all the panels on page load. It would be + // vaguely nice to load hidden panels only when the user selects them. + + // TODO: Maybe we should persist which panel the user selected, so it + // remains selected across page loads. + $content = array(); $no_headers = PhabricatorDashboardPanelRenderingEngine::HEADER_MODE_NONE; foreach ($config as $idx => $tab_spec) { @@ -112,8 +106,20 @@ final class PhabricatorDashboardPanelTypeTabs $panel_content); } + Javelin::initBehavior('dashboard-tab-panel'); - return array($list, $content); + return javelin_tag( + 'div', + array( + 'sigil' => 'dashboard-tab-panel-container', + 'meta' => array( + 'panels' => $node_ids, + ), + ), + array( + $list, + $content, + )); } } diff --git a/webroot/rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js b/webroot/rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js new file mode 100644 index 0000000000..56622c10b6 --- /dev/null +++ b/webroot/rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js @@ -0,0 +1,38 @@ +/** + * @provides javelin-behavior-dashboard-tab-panel + * @requires javelin-behavior + * javelin-dom + * javelin-stratcom + */ + +JX.behavior('dashboard-tab-panel', function(config) { + + JX.Stratcom.listen('click', 'dashboard-tab-panel-tab', function(e) { + e.kill(); + + var ii; + var idx = e.getNodeData('dashboard-tab-panel-tab').idx; + + var root = e.getNode('dashboard-tab-panel-container'); + var data = JX.Stratcom.getData(root); + + // Give the tab the user clicked a selected style, and remove it from + // the other tabs. + var tabs = JX.DOM.scry(root, 'li', 'dashboard-tab-panel-tab'); + for (ii = 0; ii < tabs.length; ii++) { + JX.DOM.alterClass(tabs[ii], 'phui-list-item-selected', (ii == idx)); + } + + // Switch the visible content to correspond to whatever the user clicked. + for (ii = 0; ii < data.panels.length; ii++) { + var panel = JX.$(data.panels[ii]); + if (ii == idx) { + JX.DOM.show(panel); + } else { + JX.DOM.hide(panel); + } + } + + }); + +});