mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-18 04:42:40 +01:00
Make documentation items in user menu update as you navigate in Quicksand
Summary: Ref T5867. I sure love Javascript. Test Plan: Navigated between Home, Diffusion and Differential, opening the user profile menu. Saw appropraite help items. Reviewers: chad Reviewed By: chad Maniphest Tasks: T5867 Differential Revision: https://secure.phabricator.com/D17214
This commit is contained in:
parent
db65f828ee
commit
a886969c48
8 changed files with 139 additions and 70 deletions
|
@ -10,7 +10,7 @@ return array(
|
|||
'conpherence.pkg.css' => '0b64e988',
|
||||
'conpherence.pkg.js' => '6249a1cf',
|
||||
'core.pkg.css' => '85f51b68',
|
||||
'core.pkg.js' => '2c684890',
|
||||
'core.pkg.js' => '666970d7',
|
||||
'darkconsole.pkg.js' => 'e7393ebb',
|
||||
'differential.pkg.css' => '9535a7e6',
|
||||
'differential.pkg.js' => 'ddfeb49b',
|
||||
|
@ -374,7 +374,7 @@ return array(
|
|||
'rsrc/image/texture/table_header_hover.png' => '038ec3b9',
|
||||
'rsrc/image/texture/table_header_tall.png' => 'd56b434f',
|
||||
'rsrc/js/application/aphlict/Aphlict.js' => '5359e785',
|
||||
'rsrc/js/application/aphlict/behavior-aphlict-dropdown.js' => '2a171a9d',
|
||||
'rsrc/js/application/aphlict/behavior-aphlict-dropdown.js' => 'caade6f2',
|
||||
'rsrc/js/application/aphlict/behavior-aphlict-listen.js' => 'fb20ac8d',
|
||||
'rsrc/js/application/aphlict/behavior-aphlict-status.js' => '5e2634b9',
|
||||
'rsrc/js/application/aphlict/behavior-desktop-notifications-control.js' => 'edd1ba66',
|
||||
|
@ -530,6 +530,7 @@ return array(
|
|||
'rsrc/js/core/behavior-toggle-class.js' => '92b9ec77',
|
||||
'rsrc/js/core/behavior-tokenizer.js' => 'b3a4b884',
|
||||
'rsrc/js/core/behavior-tooltip.js' => '42fcb747',
|
||||
'rsrc/js/core/behavior-user-menu.js' => '31420f77',
|
||||
'rsrc/js/core/behavior-watch-anchor.js' => '9f36c42d',
|
||||
'rsrc/js/core/behavior-workflow.js' => '0a3f3021',
|
||||
'rsrc/js/core/phtize.js' => 'd254d646',
|
||||
|
@ -595,7 +596,7 @@ return array(
|
|||
'inline-comment-summary-css' => '51efda3a',
|
||||
'javelin-aphlict' => '5359e785',
|
||||
'javelin-behavior' => '61cbc29a',
|
||||
'javelin-behavior-aphlict-dropdown' => '2a171a9d',
|
||||
'javelin-behavior-aphlict-dropdown' => 'caade6f2',
|
||||
'javelin-behavior-aphlict-listen' => 'fb20ac8d',
|
||||
'javelin-behavior-aphlict-status' => '5e2634b9',
|
||||
'javelin-behavior-aphront-basic-tokenizer' => 'b3a4b884',
|
||||
|
@ -719,6 +720,7 @@ return array(
|
|||
'javelin-behavior-toggle-widget' => '3dbf94d5',
|
||||
'javelin-behavior-typeahead-browse' => '635de1ec',
|
||||
'javelin-behavior-typeahead-search' => '93d0c9e3',
|
||||
'javelin-behavior-user-menu' => '31420f77',
|
||||
'javelin-behavior-view-placeholder' => '47830651',
|
||||
'javelin-behavior-workflow' => '0a3f3021',
|
||||
'javelin-color' => '7e41274a',
|
||||
|
@ -1114,17 +1116,6 @@ return array(
|
|||
'javelin-install',
|
||||
'javelin-util',
|
||||
),
|
||||
'2a171a9d' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-request',
|
||||
'javelin-stratcom',
|
||||
'javelin-vector',
|
||||
'javelin-dom',
|
||||
'javelin-uri',
|
||||
'javelin-behavior-device',
|
||||
'phabricator-title',
|
||||
'phabricator-favicon',
|
||||
),
|
||||
'2b8de964' => array(
|
||||
'javelin-install',
|
||||
'javelin-util',
|
||||
|
@ -1144,6 +1135,9 @@ return array(
|
|||
'2ee659ce' => array(
|
||||
'javelin-install',
|
||||
),
|
||||
'31420f77' => array(
|
||||
'javelin-behavior',
|
||||
),
|
||||
'320810c8' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
|
@ -1999,6 +1993,17 @@ return array(
|
|||
'javelin-stratcom',
|
||||
'phabricator-phtize',
|
||||
),
|
||||
'caade6f2' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-request',
|
||||
'javelin-stratcom',
|
||||
'javelin-vector',
|
||||
'javelin-dom',
|
||||
'javelin-uri',
|
||||
'javelin-behavior-device',
|
||||
'phabricator-title',
|
||||
'phabricator-favicon',
|
||||
),
|
||||
'ccf1cbf8' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
|
|
|
@ -175,7 +175,9 @@ abstract class PhabricatorApplication
|
|||
foreach ($articles as $article) {
|
||||
$item = id(new PhabricatorActionView())
|
||||
->setName($article['name'])
|
||||
->setHref($article['href']);
|
||||
->setHref($article['href'])
|
||||
->addSigil('help-item')
|
||||
->setOpenInNewWindow(true);
|
||||
$items[] = $item;
|
||||
}
|
||||
}
|
||||
|
@ -189,12 +191,21 @@ abstract class PhabricatorApplication
|
|||
$href = '/applications/mailcommands/'.$class.'/'.$key.'/';
|
||||
$item = id(new PhabricatorActionView())
|
||||
->setName($spec['name'])
|
||||
->setHref($href);
|
||||
->setHref($href)
|
||||
->addSigil('help-item')
|
||||
->setOpenInNewWindow(true);
|
||||
$items[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
if ($items) {
|
||||
$divider = id(new PhabricatorActionView())
|
||||
->addSigil('help-item')
|
||||
->setType(PhabricatorActionView::TYPE_DIVIDER);
|
||||
array_unshift($items, $divider);
|
||||
}
|
||||
|
||||
return array_values($items);
|
||||
}
|
||||
|
||||
public function getHelpDocumentationArticles(PhabricatorUser $viewer) {
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
final class PhabricatorHomeApplication extends PhabricatorApplication {
|
||||
|
||||
private $application;
|
||||
|
||||
const DASHBOARD_DEFAULT = 'dashboard:default';
|
||||
|
||||
public function getBaseURI() {
|
||||
|
@ -53,25 +51,40 @@ final class PhabricatorHomeApplication extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
$image = $viewer->getProfileImageURI();
|
||||
if ($controller) {
|
||||
$this->application = $controller->getCurrentApplication();
|
||||
}
|
||||
|
||||
$profile_image = id(new PHUIIconView())
|
||||
->setImage($image)
|
||||
->setHeadSize(PHUIIconView::HEAD_SMALL);
|
||||
|
||||
if ($controller) {
|
||||
$application = $controller->getCurrentApplication();
|
||||
} else {
|
||||
$application = null;
|
||||
}
|
||||
$dropdown_menu = $this->renderUserDropdown($viewer, $application);
|
||||
|
||||
$menu_id = celerity_generate_unique_node_id();
|
||||
|
||||
Javelin::initBehavior(
|
||||
'user-menu',
|
||||
array(
|
||||
'menuID' => $menu_id,
|
||||
'menu' => $dropdown_menu->getDropdownMenuMetadata(),
|
||||
));
|
||||
|
||||
return id(new PHUIButtonView())
|
||||
->setID($menu_id)
|
||||
->setTag('a')
|
||||
->setHref('/p/'.$viewer->getUsername().'/')
|
||||
->setIcon($profile_image)
|
||||
->addClass('phabricator-core-user-menu')
|
||||
->setNoCSS(true)
|
||||
->setDropdown(true)
|
||||
->setDropdownMenu($this->renderUserDropdown($viewer));
|
||||
->setHasCaret(true)
|
||||
->setNoCSS(true);
|
||||
}
|
||||
|
||||
private function renderUserDropdown(PhabricatorUser $viewer) {
|
||||
private function renderUserDropdown(
|
||||
PhabricatorUser $viewer,
|
||||
$application) {
|
||||
|
||||
$view = id(new PhabricatorActionListView())
|
||||
->setViewer($viewer);
|
||||
|
@ -98,16 +111,10 @@ final class PhabricatorHomeApplication extends PhabricatorApplication {
|
|||
->setHref('/people/manage/'.$viewer->getID().'/'));
|
||||
|
||||
// Help Menus
|
||||
if ($this->application) {
|
||||
$application = $this->application;
|
||||
if ($application) {
|
||||
$help_links = $application->getHelpMenuItems($viewer);
|
||||
if ($help_links) {
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setType(PhabricatorActionView::TYPE_DIVIDER));
|
||||
|
||||
foreach ($help_links as $link) {
|
||||
$link->setOpenInNewWindow(true);
|
||||
$view->addAction($link);
|
||||
}
|
||||
}
|
||||
|
@ -116,11 +123,13 @@ final class PhabricatorHomeApplication extends PhabricatorApplication {
|
|||
// Logout Menu
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->addSigil('logout-item')
|
||||
->setType(PhabricatorActionView::TYPE_DIVIDER));
|
||||
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Log Out %s', $viewer->getUsername()))
|
||||
->addSigil('logout-item')
|
||||
->setHref('/logout/')
|
||||
->setWorkflow(true));
|
||||
|
||||
|
|
|
@ -278,7 +278,7 @@ final class PhabricatorActionView extends AphrontView {
|
|||
array($icon, $this->name, $caret));
|
||||
}
|
||||
} else {
|
||||
$item = phutil_tag(
|
||||
$item = javelin_tag(
|
||||
'span',
|
||||
array(
|
||||
'class' => 'phabricator-action-view-item',
|
||||
|
|
|
@ -767,22 +767,6 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView
|
|||
->setViewer($viewer);
|
||||
$dropdown_query->execute();
|
||||
|
||||
$rendered_dropdowns = array();
|
||||
$applications = array(
|
||||
'PhabricatorHomeApplication',
|
||||
);
|
||||
foreach ($applications as $application_class) {
|
||||
if (!PhabricatorApplication::isClassInstalledForViewer(
|
||||
$application_class,
|
||||
$viewer)) {
|
||||
continue;
|
||||
}
|
||||
$application = PhabricatorApplication::getByClass($application_class);
|
||||
$menu = $application->buildMainMenuExtraNodes($viewer, $controller);
|
||||
// TODO: Doesn't work with Quicksand active.
|
||||
$rendered_dropdowns[$application_class] = hsprintf('%s', $menu);
|
||||
}
|
||||
|
||||
$hisec_warning_config = $this->getHighSecurityWarningConfig();
|
||||
|
||||
$console_config = null;
|
||||
|
@ -798,6 +782,7 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView
|
|||
|
||||
$application_class = null;
|
||||
$application_search_icon = null;
|
||||
$application_help = null;
|
||||
$controller = $this->getController();
|
||||
if ($controller) {
|
||||
$application = $controller->getCurrentApplication();
|
||||
|
@ -806,6 +791,16 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView
|
|||
if ($application->getApplicationSearchDocumentTypes()) {
|
||||
$application_search_icon = $application->getIcon();
|
||||
}
|
||||
|
||||
$help_items = $application->getHelpMenuItems($viewer);
|
||||
if ($help_items) {
|
||||
$help_list = id(new PhabricatorActionListView())
|
||||
->setViewer($viewer);
|
||||
foreach ($help_items as $help_item) {
|
||||
$help_list->addAction($help_item);
|
||||
}
|
||||
$application_help = $help_list->getDropdownMenuMetadata();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -817,11 +812,11 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView
|
|||
$dropdown_query->getConpherenceData(),
|
||||
),
|
||||
'globalDragAndDrop' => $upload_enabled,
|
||||
'aphlictDropdowns' => $rendered_dropdowns,
|
||||
'hisecWarningConfig' => $hisec_warning_config,
|
||||
'consoleConfig' => $console_config,
|
||||
'applicationClass' => $application_class,
|
||||
'applicationSearchIcon' => $application_search_icon,
|
||||
'helpItems' => $application_help,
|
||||
) + $this->buildAphlictListenConfigData();
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ final class PHUIButtonView extends AphrontTagView {
|
|||
private $name;
|
||||
private $tooltip;
|
||||
private $noCSS;
|
||||
private $hasCaret;
|
||||
|
||||
public function setName($name) {
|
||||
$this->name = $name;
|
||||
|
@ -93,6 +94,15 @@ final class PHUIButtonView extends AphrontTagView {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function setHasCaret($has_caret) {
|
||||
$this->hasCaret = $has_caret;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getHasCaret() {
|
||||
return $this->hasCaret;
|
||||
}
|
||||
|
||||
public function setIcon($icon, $first = true) {
|
||||
if (!($icon instanceof PHUIIconView)) {
|
||||
$icon = id(new PHUIIconView())
|
||||
|
@ -201,7 +211,7 @@ final class PHUIButtonView extends AphrontTagView {
|
|||
}
|
||||
|
||||
$caret = null;
|
||||
if ($this->dropdown) {
|
||||
if ($this->dropdown || $this->getHasCaret()) {
|
||||
$caret = phutil_tag('span', array('class' => 'caret'), '');
|
||||
}
|
||||
|
||||
|
|
|
@ -91,24 +91,6 @@ JX.behavior('aphlict-dropdown', function(config, statics) {
|
|||
null,
|
||||
function (e) {
|
||||
var data = e.getData();
|
||||
if (config.local && config.applicationClass) {
|
||||
var local_dropdowns = data.newResponse.aphlictDropdowns;
|
||||
if (local_dropdowns[config.applicationClass]) {
|
||||
JX.DOM.replace(
|
||||
dropdown,
|
||||
JX.$H(local_dropdowns[config.applicationClass]));
|
||||
dropdown = JX.$(config.dropdownID);
|
||||
if (dropdown.childNodes.length === 0) {
|
||||
JX.DOM.hide(bubble);
|
||||
} else {
|
||||
JX.DOM.show(bubble);
|
||||
}
|
||||
} else {
|
||||
JX.DOM.hide(bubble);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.fromServer) {
|
||||
return;
|
||||
}
|
||||
|
|
57
webroot/rsrc/js/core/behavior-user-menu.js
Normal file
57
webroot/rsrc/js/core/behavior-user-menu.js
Normal file
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
* @provides javelin-behavior-user-menu
|
||||
* @requires javelin-behavior
|
||||
*/
|
||||
|
||||
JX.behavior('user-menu', function(config) {
|
||||
var node = JX.$(config.menuID);
|
||||
var list = JX.$H(config.menu.items).getFragment().firstChild;
|
||||
|
||||
var menu = new JX.PHUIXDropdownMenu(node);
|
||||
|
||||
menu.listen('open', function() {
|
||||
menu.setContent(list);
|
||||
});
|
||||
|
||||
// When the user navigates to a new page, we may need to update the links
|
||||
// to documentation in the menu.
|
||||
JX.Stratcom.listen('quicksand-redraw', null, function(e) {
|
||||
var data = e.getData();
|
||||
|
||||
var new_help = data.newResponse.helpItems;
|
||||
var nodes;
|
||||
if (new_help) {
|
||||
nodes = JX.$H(new_help.items).getFragment().firstChild.children;
|
||||
} else {
|
||||
nodes = [];
|
||||
}
|
||||
|
||||
var ii;
|
||||
|
||||
var tail = [];
|
||||
for (ii = list.children.length - 1; ii >= 0; ii--) {
|
||||
var node = list.children[ii];
|
||||
|
||||
// Remove any old help items.
|
||||
if (JX.Stratcom.hasSigil(node.firstChild, 'help-item')) {
|
||||
JX.DOM.remove(node);
|
||||
}
|
||||
|
||||
// Place the logout items aside, if any exist.
|
||||
if (JX.Stratcom.hasSigil(node.firstChild, 'logout-item')) {
|
||||
JX.DOM.remove(node);
|
||||
tail.push(node);
|
||||
}
|
||||
}
|
||||
|
||||
while (nodes.length) {
|
||||
list.appendChild(nodes[0]);
|
||||
}
|
||||
|
||||
tail.reverse();
|
||||
for (ii = 0; ii < tail.length; ii++) {
|
||||
list.appendChild(tail[ii]);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
Loading…
Reference in a new issue