diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1894,6 +1894,7 @@ '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 @@ '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 --- a/src/applications/almanac/application/PhabricatorAlmanacApplication.php +++ b/src/applications/almanac/application/PhabricatorAlmanacApplication.php @@ -26,8 +26,13 @@ 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 --- a/src/applications/audit/application/PhabricatorAuditApplication.php +++ b/src/applications/audit/application/PhabricatorAuditApplication.php @@ -22,8 +22,13 @@ 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 --- a/src/applications/auth/application/PhabricatorAuthApplication.php +++ b/src/applications/auth/application/PhabricatorAuthApplication.php @@ -26,16 +26,16 @@ 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 --- a/src/applications/base/PhabricatorApplication.php +++ b/src/applications/base/PhabricatorApplication.php @@ -169,8 +169,48 @@ 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 --- a/src/applications/conduit/application/PhabricatorConduitApplication.php +++ b/src/applications/conduit/application/PhabricatorConduitApplication.php @@ -14,8 +14,13 @@ 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 --- a/src/applications/differential/application/PhabricatorDifferentialApplication.php +++ b/src/applications/differential/application/PhabricatorDifferentialApplication.php @@ -22,8 +22,13 @@ 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 @@ 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 --- a/src/applications/diffusion/application/PhabricatorDiffusionApplication.php +++ b/src/applications/diffusion/application/PhabricatorDiffusionApplication.php @@ -22,8 +22,13 @@ 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 --- a/src/applications/drydock/application/PhabricatorDrydockApplication.php +++ b/src/applications/drydock/application/PhabricatorDrydockApplication.php @@ -34,8 +34,13 @@ 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 --- a/src/applications/help/application/PhabricatorHelpApplication.php +++ b/src/applications/help/application/PhabricatorHelpApplication.php @@ -19,6 +19,8 @@ '/help/' => array( 'keyboardshortcut/' => 'PhabricatorHelpKeyboardShortcutController', 'editorprotocol/' => 'PhabricatorHelpEditorProtocolController', + 'documentation/(?P\w+)/' + => 'PhabricatorHelpDocumentationController', ), ); } @@ -27,27 +29,75 @@ 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()); - - $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; + $items = array(); + if ($application) { + $help_items = $application->getHelpMenuItems($user); + if ($help_items) { + $help_id = celerity_generate_unique_node_id(); + + 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 --- /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 --- a/src/applications/herald/application/PhabricatorHeraldApplication.php +++ b/src/applications/herald/application/PhabricatorHeraldApplication.php @@ -22,8 +22,13 @@ 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 --- a/src/applications/home/controller/PhabricatorHomeQuickCreateController.php +++ b/src/applications/home/controller/PhabricatorHomeQuickCreateController.php @@ -32,5 +32,4 @@ )); } - } diff --git a/src/applications/legalpad/application/PhabricatorLegalpadApplication.php b/src/applications/legalpad/application/PhabricatorLegalpadApplication.php --- a/src/applications/legalpad/application/PhabricatorLegalpadApplication.php +++ b/src/applications/legalpad/application/PhabricatorLegalpadApplication.php @@ -32,8 +32,13 @@ ); } - 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 --- a/src/applications/maniphest/application/PhabricatorManiphestApplication.php +++ b/src/applications/maniphest/application/PhabricatorManiphestApplication.php @@ -146,6 +146,7 @@ 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 --- a/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php +++ b/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php @@ -138,14 +138,6 @@ ->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 --- a/src/applications/meta/controller/PhabricatorApplicationEmailCommandsController.php +++ b/src/applications/meta/controller/PhabricatorApplicationEmailCommandsController.php @@ -78,9 +78,11 @@ $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 @@ $viewer)); $box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Mail Commands')) + ->setHeaderText($title) ->appendChild($content_box); return $this->buildApplicationPage( @@ -100,7 +102,7 @@ $box, ), array( - 'title' => 'asdf', + 'title' => $title, )); } diff --git a/src/applications/oauthserver/application/PhabricatorOAuthServerApplication.php b/src/applications/oauthserver/application/PhabricatorOAuthServerApplication.php --- a/src/applications/oauthserver/application/PhabricatorOAuthServerApplication.php +++ b/src/applications/oauthserver/application/PhabricatorOAuthServerApplication.php @@ -34,8 +34,14 @@ 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 --- a/src/applications/owners/application/PhabricatorOwnersApplication.php +++ b/src/applications/owners/application/PhabricatorOwnersApplication.php @@ -22,8 +22,13 @@ 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 --- a/src/applications/phame/application/PhabricatorPhameApplication.php +++ b/src/applications/phame/application/PhabricatorPhameApplication.php @@ -22,8 +22,13 @@ 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 --- a/src/applications/phriction/application/PhabricatorPhrictionApplication.php +++ b/src/applications/phriction/application/PhabricatorPhrictionApplication.php @@ -22,8 +22,13 @@ 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 --- a/src/applications/slowvote/application/PhabricatorSlowvoteApplication.php +++ b/src/applications/slowvote/application/PhabricatorSlowvoteApplication.php @@ -22,8 +22,13 @@ 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() {