diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 1b80afbdaa..116886402e 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1894,6 +1894,7 @@ phutil_register_library_map(array( 'PhabricatorHashTestCase' => 'infrastructure/util/__tests__/PhabricatorHashTestCase.php', 'PhabricatorHelpApplication' => 'applications/help/application/PhabricatorHelpApplication.php', 'PhabricatorHelpController' => 'applications/help/controller/PhabricatorHelpController.php', + 'PhabricatorHelpDocumentationController' => 'applications/help/controller/PhabricatorHelpDocumentationController.php', 'PhabricatorHelpEditorProtocolController' => 'applications/help/controller/PhabricatorHelpEditorProtocolController.php', 'PhabricatorHelpKeyboardShortcutController' => 'applications/help/controller/PhabricatorHelpKeyboardShortcutController.php', 'PhabricatorHeraldApplication' => 'applications/herald/application/PhabricatorHeraldApplication.php', @@ -5232,6 +5233,7 @@ phutil_register_library_map(array( 'PhabricatorHashTestCase' => 'PhabricatorTestCase', 'PhabricatorHelpApplication' => 'PhabricatorApplication', 'PhabricatorHelpController' => 'PhabricatorController', + 'PhabricatorHelpDocumentationController' => 'PhabricatorHelpController', 'PhabricatorHelpEditorProtocolController' => 'PhabricatorHelpController', 'PhabricatorHelpKeyboardShortcutController' => 'PhabricatorHelpController', 'PhabricatorHeraldApplication' => 'PhabricatorApplication', diff --git a/src/applications/almanac/application/PhabricatorAlmanacApplication.php b/src/applications/almanac/application/PhabricatorAlmanacApplication.php index 4ef75aca08..88eafd3331 100644 --- a/src/applications/almanac/application/PhabricatorAlmanacApplication.php +++ b/src/applications/almanac/application/PhabricatorAlmanacApplication.php @@ -26,8 +26,13 @@ final class PhabricatorAlmanacApplication extends PhabricatorApplication { return self::GROUP_UTILITIES; } - public function getHelpURI() { - return PhabricatorEnv::getDoclink('Almanac User Guide'); + public function getHelpDocumentationArticles(PhabricatorUser $viewer) { + return array( + array( + 'name' => pht('Alamanac User Guide'), + 'href' => PhabricatorEnv::getDoclink('Almanac User Guide'), + ), + ); } public function isPrototype() { diff --git a/src/applications/audit/application/PhabricatorAuditApplication.php b/src/applications/audit/application/PhabricatorAuditApplication.php index a3b3448fdb..e186215c96 100644 --- a/src/applications/audit/application/PhabricatorAuditApplication.php +++ b/src/applications/audit/application/PhabricatorAuditApplication.php @@ -22,8 +22,13 @@ final class PhabricatorAuditApplication extends PhabricatorApplication { return true; } - public function getHelpURI() { - return PhabricatorEnv::getDoclink('Audit User Guide'); + public function getHelpDocumentationArticles(PhabricatorUser $viewer) { + return array( + array( + 'name' => pht('Audit User Guide'), + 'href' => PhabricatorEnv::getDoclink('Audit User Guide'), + ), + ); } public function getRoutes() { diff --git a/src/applications/auth/application/PhabricatorAuthApplication.php b/src/applications/auth/application/PhabricatorAuthApplication.php index 0647c498da..dfa1be6f75 100644 --- a/src/applications/auth/application/PhabricatorAuthApplication.php +++ b/src/applications/auth/application/PhabricatorAuthApplication.php @@ -26,16 +26,16 @@ final class PhabricatorAuthApplication extends PhabricatorApplication { return pht('Login/Registration'); } - public function getHelpURI() { + public function getHelpDocumentationArticles(PhabricatorUser $viewer) { // NOTE: Although reasonable help exists for this in "Configuring Accounts - // and Registration", specifying a help URI here means we get the menu + // and Registration", specifying help items here means we get the menu // item in all the login/link interfaces, which is confusing and not // helpful. // TODO: Special case this, or split the auth and auth administration // applications? - return null; + return array(); } public function buildMainMenuItems( diff --git a/src/applications/base/PhabricatorApplication.php b/src/applications/base/PhabricatorApplication.php index a01d50a03f..6fdb93c784 100644 --- a/src/applications/base/PhabricatorApplication.php +++ b/src/applications/base/PhabricatorApplication.php @@ -169,8 +169,48 @@ abstract class PhabricatorApplication implements PhabricatorPolicyInterface { return null; } - public function getHelpURI() { - return null; + public function getHelpMenuItems(PhabricatorUser $viewer) { + $items = array(); + + $articles = $this->getHelpDocumentationArticles($viewer); + if ($articles) { + $items[] = id(new PHUIListItemView()) + ->setType(PHUIListItemView::TYPE_LABEL) + ->setName(pht('%s Documentation', $this->getName())); + foreach ($articles as $article) { + $item = id(new PHUIListItemView()) + ->setName($article['name']) + ->setIcon('fa-book') + ->setHref($article['href']); + + $items[] = $item; + } + } + + $command_specs = $this->getMailCommandObjects(); + if ($command_specs) { + $items[] = id(new PHUIListItemView()) + ->setType(PHUIListItemView::TYPE_LABEL) + ->setName(pht('Email Help')); + foreach ($command_specs as $key => $spec) { + $object = $spec['object']; + + $class = get_class($this); + $href = '/applications/mailcommands/'.$class.'/'.$key.'/'; + + $item = id(new PHUIListItemView()) + ->setName($spec['name']) + ->setIcon('fa-envelope-o') + ->setHref($href); + $items[] = $item; + } + } + + return $items; + } + + public function getHelpDocumentationArticles(PhabricatorUser $viewer) { + return array(); } public function getOverview() { diff --git a/src/applications/conduit/application/PhabricatorConduitApplication.php b/src/applications/conduit/application/PhabricatorConduitApplication.php index 8b2048507b..6e7cc02c90 100644 --- a/src/applications/conduit/application/PhabricatorConduitApplication.php +++ b/src/applications/conduit/application/PhabricatorConduitApplication.php @@ -14,8 +14,13 @@ final class PhabricatorConduitApplication extends PhabricatorApplication { return false; } - public function getHelpURI() { - return PhabricatorEnv::getDoclink('Conduit Technical Documentation'); + public function getHelpDocumentationArticles(PhabricatorUser $viewer) { + return array( + array( + 'name' => pht('Conduit Technical Documentation'), + 'href' => PhabricatorEnv::getDoclink('Conduit Technical Documentation'), + ), + ); } public function getName() { diff --git a/src/applications/differential/application/PhabricatorDifferentialApplication.php b/src/applications/differential/application/PhabricatorDifferentialApplication.php index 5a7eb82d1c..43044d3a9f 100644 --- a/src/applications/differential/application/PhabricatorDifferentialApplication.php +++ b/src/applications/differential/application/PhabricatorDifferentialApplication.php @@ -22,8 +22,13 @@ final class PhabricatorDifferentialApplication extends PhabricatorApplication { return true; } - public function getHelpURI() { - return PhabricatorEnv::getDoclink('Differential User Guide'); + public function getHelpDocumentationArticles(PhabricatorUser $viewer) { + return array( + array( + 'name' => pht('Differential User Guide'), + 'href' => PhabricatorEnv::getDoclink('Differential User Guide'), + ), + ); } public function getFactObjectsForAnalysis() { @@ -189,6 +194,7 @@ EOTEXT public function getMailCommandObjects() { return array( 'revision' => array( + 'name' => pht('Email Commands: Revisions'), 'object' => new DifferentialRevision(), ), ); diff --git a/src/applications/diffusion/application/PhabricatorDiffusionApplication.php b/src/applications/diffusion/application/PhabricatorDiffusionApplication.php index 80c478f65f..28d8a33458 100644 --- a/src/applications/diffusion/application/PhabricatorDiffusionApplication.php +++ b/src/applications/diffusion/application/PhabricatorDiffusionApplication.php @@ -22,8 +22,13 @@ final class PhabricatorDiffusionApplication extends PhabricatorApplication { return true; } - public function getHelpURI() { - return PhabricatorEnv::getDoclink('Diffusion User Guide'); + public function getHelpDocumentationArticles(PhabricatorUser $viewer) { + return array( + array( + 'name' => pht('Diffusion User Guide'), + 'href' => PhabricatorEnv::getDoclink('Diffusion User Guide'), + ), + ); } public function getFactObjectsForAnalysis() { diff --git a/src/applications/drydock/application/PhabricatorDrydockApplication.php b/src/applications/drydock/application/PhabricatorDrydockApplication.php index 033e2666c7..b2c758b563 100644 --- a/src/applications/drydock/application/PhabricatorDrydockApplication.php +++ b/src/applications/drydock/application/PhabricatorDrydockApplication.php @@ -34,8 +34,13 @@ final class PhabricatorDrydockApplication extends PhabricatorApplication { return true; } - public function getHelpURI() { - return PhabricatorEnv::getDoclink('Drydock User Guide'); + public function getHelpDocumentationArticles(PhabricatorUser $viewer) { + return array( + array( + 'name' => pht('Drydock User Guide'), + 'href' => PhabricatorEnv::getDoclink('Drydock User Guide'), + ), + ); } public function getRoutes() { diff --git a/src/applications/help/application/PhabricatorHelpApplication.php b/src/applications/help/application/PhabricatorHelpApplication.php index d2845a1b7e..cd1704ea42 100644 --- a/src/applications/help/application/PhabricatorHelpApplication.php +++ b/src/applications/help/application/PhabricatorHelpApplication.php @@ -19,6 +19,8 @@ final class PhabricatorHelpApplication extends PhabricatorApplication { '/help/' => array( 'keyboardshortcut/' => 'PhabricatorHelpKeyboardShortcutController', 'editorprotocol/' => 'PhabricatorHelpEditorProtocolController', + 'documentation/(?P\w+)/' + => 'PhabricatorHelpDocumentationController', ), ); } @@ -27,27 +29,75 @@ final class PhabricatorHelpApplication extends PhabricatorApplication { PhabricatorUser $user, PhabricatorController $controller = null) { - $items = array(); - $application = null; if ($controller) { $application = $controller->getCurrentApplication(); } - if ($application && $application->getHelpURI()) { - $help_name = pht('%s Help', $application->getName()); + $items = array(); + if ($application) { + $help_items = $application->getHelpMenuItems($user); + if ($help_items) { + $help_id = celerity_generate_unique_node_id(); - $item = id(new PHUIListItemView()) - ->setName($help_name) - ->addClass('core-menu-item') - ->setIcon('fa-info-circle') - ->setAural($help_name) - ->setOrder(200) - ->setHref($application->getHelpURI()); - $items[] = $item; + Javelin::initBehavior( + 'aphlict-dropdown', + array( + 'bubbleID' => $help_id, + 'dropdownID' => 'phabricator-help-menu', + 'local' => true, + 'desktop' => true, + 'right' => true, + )); + + $help_name = pht('%s Help', $application->getName()); + + $item = id(new PHUIListItemView()) + ->setName($help_name) + ->setIcon('fa-life-ring') + ->setHref('/help/documentation/'.get_class($application).'/') + ->addClass('core-menu-item') + ->setID($help_id) + ->setAural($help_name) + ->setOrder(200); + $items[] = $item; + } } return $items; } + public function buildMainMenuExtraNodes( + PhabricatorUser $viewer, + PhabricatorController $controller = null) { + + if (!$controller) { + return null; + } + + $application = $controller->getCurrentApplication(); + if (!$application) { + return null; + } + + $help_items = $application->getHelpMenuItems($viewer); + if (!$help_items) { + return null; + } + + $view = new PHUIListView(); + foreach ($help_items as $item) { + $view->addMenuItem($item); + } + + return phutil_tag( + 'div', + array( + 'id' => 'phabricator-help-menu', + 'class' => 'phabricator-main-menu-dropdown phui-list-sidenav', + 'style' => 'display: none', + ), + $view); + } + } diff --git a/src/applications/help/controller/PhabricatorHelpDocumentationController.php b/src/applications/help/controller/PhabricatorHelpDocumentationController.php new file mode 100644 index 0000000000..ce4dc38f42 --- /dev/null +++ b/src/applications/help/controller/PhabricatorHelpDocumentationController.php @@ -0,0 +1,52 @@ +getViewer(); + + $application_class = $request->getURIData('application'); + $application = id(new PhabricatorApplicationQuery()) + ->setViewer($viewer) + ->withClasses(array($application_class)) + ->executeOne(); + if (!$application) { + return new Aphront404Response(); + } + + $items = $application->getHelpMenuItems($viewer); + $title = pht('%s Help', $application->getName()); + + $list = id(new PHUIObjectItemListView()) + ->setUser($viewer); + foreach ($items as $item) { + if ($item->getType() == PHUIListItemView::TYPE_LABEL) { + continue; + } + $list->addItem( + id(new PHUIObjectItemView()) + ->setHeader($item->getName()) + ->setWorkflow($item->getWorkflow()) + ->setHref($item->getHref())); + } + + $crumbs = $this->buildApplicationCrumbs(); + $crumbs->addTextCrumb($title); + + return $this->buildApplicationPage( + array( + $crumbs, + $list, + ), + array( + 'title' => $title, + )); + } + + +} diff --git a/src/applications/herald/application/PhabricatorHeraldApplication.php b/src/applications/herald/application/PhabricatorHeraldApplication.php index d6fedeca7f..f364117fba 100644 --- a/src/applications/herald/application/PhabricatorHeraldApplication.php +++ b/src/applications/herald/application/PhabricatorHeraldApplication.php @@ -22,8 +22,13 @@ final class PhabricatorHeraldApplication extends PhabricatorApplication { return "\xE2\x98\xBF"; } - public function getHelpURI() { - return PhabricatorEnv::getDoclink('Herald User Guide'); + public function getHelpDocumentationArticles(PhabricatorUser $viewer) { + return array( + array( + 'name' => pht('Herald User Guide'), + 'href' => PhabricatorEnv::getDoclink('Herald User Guide'), + ), + ); } public function getFlavorText() { diff --git a/src/applications/home/controller/PhabricatorHomeQuickCreateController.php b/src/applications/home/controller/PhabricatorHomeQuickCreateController.php index 82b39cb688..deb54072a0 100644 --- a/src/applications/home/controller/PhabricatorHomeQuickCreateController.php +++ b/src/applications/home/controller/PhabricatorHomeQuickCreateController.php @@ -32,5 +32,4 @@ final class PhabricatorHomeQuickCreateController )); } - } diff --git a/src/applications/legalpad/application/PhabricatorLegalpadApplication.php b/src/applications/legalpad/application/PhabricatorLegalpadApplication.php index a453881ca8..9c92dab03b 100644 --- a/src/applications/legalpad/application/PhabricatorLegalpadApplication.php +++ b/src/applications/legalpad/application/PhabricatorLegalpadApplication.php @@ -32,8 +32,13 @@ final class PhabricatorLegalpadApplication extends PhabricatorApplication { ); } - public function getHelpURI() { - return PhabricatorEnv::getDoclink('Legalpad User Guide'); + public function getHelpDocumentationArticles(PhabricatorUser $viewer) { + return array( + array( + 'name' => pht('Legalpad User Guide'), + 'href' => PhabricatorEnv::getDoclink('Legalpad User Guide'), + ), + ); } public function getOverview() { diff --git a/src/applications/maniphest/application/PhabricatorManiphestApplication.php b/src/applications/maniphest/application/PhabricatorManiphestApplication.php index 2405e446f0..71751b3914 100644 --- a/src/applications/maniphest/application/PhabricatorManiphestApplication.php +++ b/src/applications/maniphest/application/PhabricatorManiphestApplication.php @@ -146,6 +146,7 @@ final class PhabricatorManiphestApplication extends PhabricatorApplication { public function getMailCommandObjects() { return array( 'task' => array( + 'name' => pht('Email Commands: Tasks'), 'object' => new ManiphestTask(), ), ); diff --git a/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php b/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php index 169532d773..da23cc31ff 100644 --- a/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php +++ b/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php @@ -138,14 +138,6 @@ final class PhabricatorApplicationDetailViewController ->setUser($user) ->setObjectURI($this->getRequest()->getRequestURI()); - if ($selected->getHelpURI()) { - $view->addAction( - id(new PhabricatorActionView()) - ->setName(pht('Help / Documentation')) - ->setIcon('fa-life-ring') - ->setHref($selected->getHelpURI())); - } - $can_edit = PhabricatorPolicyFilter::hasCapability( $user, $selected, diff --git a/src/applications/meta/controller/PhabricatorApplicationEmailCommandsController.php b/src/applications/meta/controller/PhabricatorApplicationEmailCommandsController.php index fe89672fd2..b3d406df99 100644 --- a/src/applications/meta/controller/PhabricatorApplicationEmailCommandsController.php +++ b/src/applications/meta/controller/PhabricatorApplicationEmailCommandsController.php @@ -78,9 +78,11 @@ final class PhabricatorApplicationEmailCommandsController $content = implode("\n\n", $content); + $title = $spec['name']; + $crumbs = $this->buildApplicationCrumbs(); $this->addApplicationCrumb($crumbs, $selected); - $crumbs->addTextCrumb(pht('Mail Commands')); + $crumbs->addTextCrumb($title); $content_box = id(new PHUIBoxView()) ->addMargin(PHUI::MARGIN_LARGE) @@ -91,7 +93,7 @@ final class PhabricatorApplicationEmailCommandsController $viewer)); $box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Mail Commands')) + ->setHeaderText($title) ->appendChild($content_box); return $this->buildApplicationPage( @@ -100,7 +102,7 @@ final class PhabricatorApplicationEmailCommandsController $box, ), array( - 'title' => 'asdf', + 'title' => $title, )); } diff --git a/src/applications/oauthserver/application/PhabricatorOAuthServerApplication.php b/src/applications/oauthserver/application/PhabricatorOAuthServerApplication.php index 82bb0d6821..08e5e207f6 100644 --- a/src/applications/oauthserver/application/PhabricatorOAuthServerApplication.php +++ b/src/applications/oauthserver/application/PhabricatorOAuthServerApplication.php @@ -34,8 +34,14 @@ final class PhabricatorOAuthServerApplication extends PhabricatorApplication { return true; } - public function getHelpURI() { - return PhabricatorEnv::getDoclink('Using the Phabricator OAuth Server'); + public function getHelpDocumentationArticles(PhabricatorUser $viewer) { + return array( + array( + 'name' => pht('Using the Phabricator OAuth Server'), + 'href' => PhabricatorEnv::getDoclink( + 'Using the Phabricator OAuth Server'), + ), + ); } public function getRoutes() { diff --git a/src/applications/owners/application/PhabricatorOwnersApplication.php b/src/applications/owners/application/PhabricatorOwnersApplication.php index fc11103179..ba44293016 100644 --- a/src/applications/owners/application/PhabricatorOwnersApplication.php +++ b/src/applications/owners/application/PhabricatorOwnersApplication.php @@ -22,8 +22,13 @@ final class PhabricatorOwnersApplication extends PhabricatorApplication { return "\xE2\x98\x81"; } - public function getHelpURI() { - return PhabricatorEnv::getDoclink('Owners Tool User Guide'); + public function getHelpDocumentationArticles(PhabricatorUser $viewer) { + return array( + array( + 'name' => pht('Owners User Guide'), + 'href' => PhabricatorEnv::getDoclink('Owners Tool User Guide'), + ), + ); } public function getFlavorText() { diff --git a/src/applications/phame/application/PhabricatorPhameApplication.php b/src/applications/phame/application/PhabricatorPhameApplication.php index 452a521854..b466ad5191 100644 --- a/src/applications/phame/application/PhabricatorPhameApplication.php +++ b/src/applications/phame/application/PhabricatorPhameApplication.php @@ -22,8 +22,13 @@ final class PhabricatorPhameApplication extends PhabricatorApplication { return "\xe2\x9c\xa9"; } - public function getHelpURI() { - return PhabricatorEnv::getDoclink('Phame User Guide'); + public function getHelpDocumentationArticles(PhabricatorUser $viewer) { + return array( + array( + 'name' => pht('Phame User Guide'), + 'href' => PhabricatorEnv::getDoclink('Phame User Guide'), + ), + ); } public function isPrototype() { diff --git a/src/applications/phriction/application/PhabricatorPhrictionApplication.php b/src/applications/phriction/application/PhabricatorPhrictionApplication.php index db378633a4..89fff32ffe 100644 --- a/src/applications/phriction/application/PhabricatorPhrictionApplication.php +++ b/src/applications/phriction/application/PhabricatorPhrictionApplication.php @@ -22,8 +22,13 @@ final class PhabricatorPhrictionApplication extends PhabricatorApplication { return true; } - public function getHelpURI() { - return PhabricatorEnv::getDoclink('Phriction User Guide'); + public function getHelpDocumentationArticles(PhabricatorUser $viewer) { + return array( + array( + 'name' => pht('Phriction User Guide'), + 'href' => PhabricatorEnv::getDoclink('Phriction User Guide'), + ), + ); } public function getTitleGlyph() { diff --git a/src/applications/slowvote/application/PhabricatorSlowvoteApplication.php b/src/applications/slowvote/application/PhabricatorSlowvoteApplication.php index 9114b0ea89..fa3acfd779 100644 --- a/src/applications/slowvote/application/PhabricatorSlowvoteApplication.php +++ b/src/applications/slowvote/application/PhabricatorSlowvoteApplication.php @@ -22,8 +22,13 @@ final class PhabricatorSlowvoteApplication extends PhabricatorApplication { return "\xE2\x9C\x94"; } - public function getHelpURI() { - return PhabricatorEnv::getDoclink('Slowvote User Guide'); + public function getHelpDocumentationArticles(PhabricatorUser $viewer) { + return array( + array( + 'name' => pht('Slowvote User Guide'), + 'href' => PhabricatorEnv::getDoclink('Slowvote User Guide'), + ), + ); } public function getFlavorText() {