1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-21 22:32:41 +01:00

Add a side nav to Conduit API method console pages

Summary: Ref T13072. Make large Conduit doc pages a bit more navigable. This prepares for updating "harbormaster.sendmessage" to support sending messages to builds.

Test Plan: Viewed various Conduit API documentation pages, clicked links.

Subscribers: PHID-OPKG-gm6ozazyms6q6i22gyam

Maniphest Tasks: T13072

Differential Revision: https://secure.phabricator.com/D21696
This commit is contained in:
epriestley 2021-07-16 09:53:10 -07:00
parent 2ff1d4b3b0
commit 3df1e17527
11 changed files with 298 additions and 114 deletions

View file

@ -9,7 +9,7 @@ return array(
'names' => array(
'conpherence.pkg.css' => '0e3cf785',
'conpherence.pkg.js' => '020aebcf',
'core.pkg.css' => '0ae696de',
'core.pkg.css' => '00a2e7f4',
'core.pkg.js' => 'd2de90d9',
'dark-console.pkg.js' => '187792c2',
'differential.pkg.css' => 'ffb69e3d',
@ -171,7 +171,7 @@ return array(
'rsrc/css/phui/phui-invisible-character-view.css' => 'c694c4a4',
'rsrc/css/phui/phui-left-right.css' => '68513c34',
'rsrc/css/phui/phui-lightbox.css' => '4ebf22da',
'rsrc/css/phui/phui-list.css' => '2f253c22',
'rsrc/css/phui/phui-list.css' => '0c04affd',
'rsrc/css/phui/phui-object-box.css' => 'b8d7eea0',
'rsrc/css/phui/phui-pager.css' => 'd022c7ad',
'rsrc/css/phui/phui-pinboard-view.css' => '1f08f5d8',
@ -872,7 +872,7 @@ return array(
'phui-invisible-character-view-css' => 'c694c4a4',
'phui-left-right-css' => '68513c34',
'phui-lightbox-css' => '4ebf22da',
'phui-list-view-css' => '2f253c22',
'phui-list-view-css' => '0c04affd',
'phui-object-box-css' => 'b8d7eea0',
'phui-oi-big-ui-css' => 'fa74cc35',
'phui-oi-color-css' => 'b517bfa0',

View file

@ -338,6 +338,7 @@ phutil_register_library_map(array(
'ChatLogConduitAPIMethod' => 'applications/chatlog/conduit/ChatLogConduitAPIMethod.php',
'ChatLogQueryConduitAPIMethod' => 'applications/chatlog/conduit/ChatLogQueryConduitAPIMethod.php',
'ChatLogRecordConduitAPIMethod' => 'applications/chatlog/conduit/ChatLogRecordConduitAPIMethod.php',
'ConduitAPIDocumentationPage' => 'applications/conduit/data/ConduitAPIDocumentationPage.php',
'ConduitAPIMethod' => 'applications/conduit/method/ConduitAPIMethod.php',
'ConduitAPIMethodTestCase' => 'applications/conduit/method/__tests__/ConduitAPIMethodTestCase.php',
'ConduitAPIRequest' => 'applications/conduit/protocol/ConduitAPIRequest.php',
@ -6430,6 +6431,7 @@ phutil_register_library_map(array(
'ChatLogConduitAPIMethod' => 'ConduitAPIMethod',
'ChatLogQueryConduitAPIMethod' => 'ChatLogConduitAPIMethod',
'ChatLogRecordConduitAPIMethod' => 'ChatLogConduitAPIMethod',
'ConduitAPIDocumentationPage' => 'Phobject',
'ConduitAPIMethod' => array(
'Phobject',
'PhabricatorPolicyInterface',

View file

@ -88,23 +88,118 @@ final class PhabricatorConduitConsoleController
$crumbs->addTextCrumb($method->getAPIMethodName());
$crumbs->setBorder(true);
$documentation_pages = $method->getDocumentationPages($viewer);
$documentation_view = $this->newDocumentationView(
$method,
$documentation_pages);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setFooter(array(
id(new PhabricatorAnchorView())
->setAnchorName('overview'),
$info_box,
$method->getMethodDocumentation(),
id(new PhabricatorAnchorView())
->setAnchorName('documentation'),
$documentation_view,
id(new PhabricatorAnchorView())
->setAnchorName('call'),
$form_box,
id(new PhabricatorAnchorView())
->setAnchorName('examples'),
$this->renderExampleBox($method, null),
));
$title = $method->getAPIMethodName();
$nav = $this->newNavigationView($method, $documentation_pages);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->setNavigation($nav)
->appendChild($view);
}
private function newDocumentationView(
ConduitAPIMethod $method,
array $documentation_pages) {
assert_instances_of($documentation_pages, 'ConduitAPIDocumentationPage');
$viewer = $this->getViewer();
$description_properties = id(new PHUIPropertyListView());
$description_properties->addTextContent(
new PHUIRemarkupView($viewer, $method->getMethodDescription()));
$description_box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Method Description'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->appendChild($description_properties);
$view = array();
$view[] = $description_box;
foreach ($documentation_pages as $page) {
$view[] = $page->newView();
}
return $view;
}
private function newNavigationView(
ConduitAPIMethod $method,
array $documentation_pages) {
assert_instances_of($documentation_pages, 'ConduitAPIDocumentationPage');
$console_uri = urisprintf(
'/method/%s/',
$method->getAPIMethodName());
$console_uri = $this->getApplicationURI($console_uri);
$console_uri = new PhutilURI($console_uri);
$nav = id(new AphrontSideNavFilterView())
->setBaseURI($console_uri);
$nav->selectFilter(null);
$nav->newLink('overview')
->setHref('#overview')
->setName(pht('Overview'))
->setIcon('fa-list');
$nav->newLink('documentation')
->setHref('#documentation')
->setName(pht('Documentation'))
->setIcon('fa-book');
foreach ($documentation_pages as $page) {
$nav->newLink($page->getAnchor())
->setHref('#'.$page->getAnchor())
->setName($page->getName())
->setIcon($page->getIconIcon())
->setIndented(true);
}
$nav->newLink('call')
->setHref('#call')
->setName(pht('Call Method'))
->setIcon('fa-play');
$nav->newLink('examples')
->setHref('#examples')
->setName(pht('Examples'))
->setIcon('fa-folder-open-o');
return $nav;
}
private function buildMethodProperties(ConduitAPIMethod $method) {
$viewer = $this->getViewer();
@ -171,7 +266,6 @@ final class PhabricatorConduitConsoleController
pht('Errors'),
$error_description);
$scope = $method->getRequiredScope();
switch ($scope) {
case ConduitAPIMethod::SCOPE_ALWAYS:
@ -201,11 +295,6 @@ final class PhabricatorConduitConsoleController
$oauth_description,
));
$view->addSectionHeader(
pht('Description'), PHUIPropertyListView::ICON_SUMMARY);
$view->addTextContent(
new PHUIRemarkupView($viewer, $method->getMethodDescription()));
return $view;
}

View file

@ -0,0 +1,61 @@
<?php
final class ConduitAPIDocumentationPage
extends Phobject {
private $name;
private $anchor;
private $iconIcon;
private $content = array();
public function setName($name) {
$this->name = $name;
return $this;
}
public function getName() {
return $this->name;
}
public function setAnchor($anchor) {
$this->anchor = $anchor;
return $this;
}
public function getAnchor() {
return $this->anchor;
}
public function setContent($content) {
$this->content = $content;
return $this;
}
public function getContent() {
return $this->content;
}
public function setIconIcon($icon_icon) {
$this->iconIcon = $icon_icon;
return $this;
}
public function getIconIcon() {
return $this->iconIcon;
}
public function newView() {
$anchor_name = $this->getAnchor();
$anchor_view = id(new PhabricatorAnchorView())
->setAnchorName($anchor_name);
$content = $this->content;
return array(
$anchor_view,
$content,
);
}
}

View file

@ -40,8 +40,33 @@ abstract class ConduitAPIMethod
*/
abstract public function getMethodDescription();
public function getMethodDocumentation() {
return null;
final public function getDocumentationPages(PhabricatorUser $viewer) {
$pages = $this->newDocumentationPages($viewer);
return $pages;
}
protected function newDocumentationPages(PhabricatorUser $viewer) {
return array();
}
final protected function newDocumentationPage(PhabricatorUser $viewer) {
return id(new ConduitAPIDocumentationPage())
->setIconIcon('fa-chevron-right');
}
final protected function newDocumentationBoxPage(
PhabricatorUser $viewer,
$title,
$content) {
$box_view = id(new PHUIObjectBoxView())
->setHeaderText($title)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($content);
return $this->newDocumentationPage($viewer)
->setName($title)
->setContent($box_view);
}
abstract protected function defineParamTypes();

View file

@ -7,14 +7,6 @@ abstract class HarbormasterConduitAPIMethod extends ConduitAPIMethod {
'PhabricatorHarbormasterApplication');
}
public function getMethodStatus() {
return self::METHOD_STATUS_UNSTABLE;
}
public function getMethodStatusDescription() {
return pht('All Harbormaster APIs are new and subject to change.');
}
protected function returnArtifactList(array $artifacts) {
$list = array();

View file

@ -60,7 +60,7 @@ abstract class PhabricatorSearchEngineAPIMethod
PhabricatorEnv::getDoclink('Conduit API: Using Search Endpoints'));
}
final public function getMethodDocumentation() {
final protected function newDocumentationPages(PhabricatorUser $viewer) {
$viewer = $this->getViewer();
$engine = $this->newSearchEngine()
@ -70,17 +70,18 @@ abstract class PhabricatorSearchEngineAPIMethod
$out = array();
$out[] = $this->buildQueriesBox($engine);
$out[] = $this->buildConstraintsBox($engine);
$out[] = $this->buildOrderBox($engine, $query);
$out[] = $this->buildFieldsBox($engine);
$out[] = $this->buildAttachmentsBox($engine);
$out[] = $this->buildPagingBox($engine);
$out[] = $this->buildQueriesDocumentationPage($viewer, $engine);
$out[] = $this->buildConstraintsDocumentationPage($viewer, $engine);
$out[] = $this->buildOrderDocumentationPage($viewer, $engine, $query);
$out[] = $this->buildFieldsDocumentationPage($viewer, $engine);
$out[] = $this->buildAttachmentsDocumentationPage($viewer, $engine);
$out[] = $this->buildPagingDocumentationPage($viewer, $engine);
return $out;
}
private function buildQueriesBox(
private function buildQueriesDocumentationPage(
PhabricatorUser $viewer,
PhabricatorApplicationSearchEngine $engine) {
$viewer = $this->getViewer();
@ -140,15 +141,18 @@ EOTEXT
null,
));
return id(new PHUIObjectBoxView())
->setHeaderText(pht('Builtin and Saved Queries'))
->setCollapsed(true)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->appendChild($this->newRemarkupDocumentationView($info))
->appendChild($table);
$title = pht('Prebuilt Queries');
$content = array(
$this->newRemarkupDocumentationView($info),
$table,
);
return $this->newDocumentationBoxPage($viewer, $title, $content)
->setAnchor('queries');
}
private function buildConstraintsBox(
private function buildConstraintsDocumentationPage(
PhabricatorUser $viewer,
PhabricatorApplicationSearchEngine $engine) {
$info = pht(<<<EOTEXT
@ -281,16 +285,21 @@ EOTEXT
'wide',
));
return id(new PHUIObjectBoxView())
->setHeaderText(pht('Custom Query Constraints'))
->setCollapsed(true)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->appendChild($this->newRemarkupDocumentationView($info))
->appendChild($table)
->appendChild($constant_lists);
$title = pht('Constraints');
$content = array(
$this->newRemarkupDocumentationView($info),
$table,
$constant_lists,
);
return $this->newDocumentationBoxPage($viewer, $title, $content)
->setAnchor('constraints')
->setIconIcon('fa-filter');
}
private function buildOrderBox(
private function buildOrderDocumentationPage(
PhabricatorUser $viewer,
PhabricatorApplicationSearchEngine $engine,
$query) {
@ -388,18 +397,21 @@ EOTEXT
'wide',
));
$title = pht('Result Ordering');
$content = array(
$this->newRemarkupDocumentationView($orders_info),
$orders_table,
$this->newRemarkupDocumentationView($columns_info),
$columns_table,
);
return id(new PHUIObjectBoxView())
->setHeaderText(pht('Result Ordering'))
->setCollapsed(true)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->appendChild($this->newRemarkupDocumentationView($orders_info))
->appendChild($orders_table)
->appendChild($this->newRemarkupDocumentationView($columns_info))
->appendChild($columns_table);
return $this->newDocumentationBoxPage($viewer, $title, $content)
->setAnchor('ordering')
->setIconIcon('fa-sort-numeric-asc');
}
private function buildFieldsBox(
private function buildFieldsDocumentationPage(
PhabricatorUser $viewer,
PhabricatorApplicationSearchEngine $engine) {
$info = pht(<<<EOTEXT
@ -470,15 +482,19 @@ EOTEXT
'wide',
));
return id(new PHUIObjectBoxView())
->setHeaderText(pht('Object Fields'))
->setCollapsed(true)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->appendChild($this->newRemarkupDocumentationView($info))
->appendChild($table);
$title = pht('Object Fields');
$content = array(
$this->newRemarkupDocumentationView($info),
$table,
);
return $this->newDocumentationBoxPage($viewer, $title, $content)
->setAnchor('fields')
->setIconIcon('fa-cube');
}
private function buildAttachmentsBox(
private function buildAttachmentsDocumentationPage(
PhabricatorUser $viewer,
PhabricatorApplicationSearchEngine $engine) {
$info = pht(<<<EOTEXT
@ -560,15 +576,19 @@ EOTEXT
'wide',
));
return id(new PHUIObjectBoxView())
->setHeaderText(pht('Attachments'))
->setCollapsed(true)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->appendChild($this->newRemarkupDocumentationView($info))
->appendChild($table);
$title = pht('Attachments');
$content = array(
$this->newRemarkupDocumentationView($info),
$table,
);
return $this->newDocumentationBoxPage($viewer, $title, $content)
->setAnchor('attachments')
->setIconIcon('fa-cubes');
}
private function buildPagingBox(
private function buildPagingDocumentationPage(
PhabricatorUser $viewer,
PhabricatorApplicationSearchEngine $engine) {
$info = pht(<<<EOTEXT
@ -631,11 +651,14 @@ if `before` is `null`, there are no previous results available.
EOTEXT
);
return id(new PHUIObjectBoxView())
->setHeaderText(pht('Paging and Limits'))
->setCollapsed(true)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->appendChild($this->newRemarkupDocumentationView($info));
$title = pht('Paging and Limits');
$content = array(
$this->newRemarkupDocumentationView($info),
);
return $this->newDocumentationBoxPage($viewer, $title, $content)
->setAnchor('paging')
->setIconIcon('fa-clone');
}
}

View file

@ -13,7 +13,7 @@ final class TransactionSearchConduitAPIMethod
'or an entire object type.');
}
public function getMethodDocumentation() {
protected function newDocumentationPages(PhabricatorUser $viewer) {
$markup = pht(<<<EOREMARKUP
When an object (like a task) is edited, Phabricator creates a "transaction"
and applies it. This list of transactions on each object is the basis for
@ -77,11 +77,10 @@ EOREMARKUP
$markup = $this->newRemarkupDocumentationView($markup);
return id(new PHUIObjectBoxView())
->setCollapsed(true)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setHeaderText(pht('Method Details'))
->appendChild($markup);
return array(
$this->newDocumentationBoxPage($viewer, pht('Method Details'), $markup)
->setAnchor('details'),
);
}
protected function defineParamTypes() {

View file

@ -38,9 +38,7 @@ abstract class PhabricatorEditEngineAPIMethod
PhabricatorEnv::getDoclink('Conduit API: Using Edit Endpoints'));
}
final public function getMethodDocumentation() {
$viewer = $this->getViewer();
final protected function newDocumentationPages(PhabricatorUser $viewer) {
$engine = $this->newEditEngine()
->setViewer($viewer);
@ -48,16 +46,15 @@ abstract class PhabricatorEditEngineAPIMethod
$out = array();
$out[] = $this->buildEditTypesBoxes($engine, $types);
return $out;
return $this->buildEditTypesDocumentationPages($viewer, $engine, $types);
}
private function buildEditTypesBoxes(
private function buildEditTypesDocumentationPages(
PhabricatorUser $viewer,
PhabricatorEditEngine $engine,
array $types) {
$boxes = array();
$pages = array();
$summary_info = pht(
'This endpoint supports these types of transactions. See below for '.
@ -83,12 +80,14 @@ abstract class PhabricatorEditEngineAPIMethod
'wide',
));
$boxes[] = id(new PHUIObjectBoxView())
->setHeaderText(pht('Transaction Types'))
->setCollapsed(true)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->appendChild($this->buildRemarkup($summary_info))
->appendChild($summary_table);
$title = pht('Transaction Summary');
$content = array(
$this->buildRemarkup($summary_info),
$summary_table,
);
$pages[] = $this->newDocumentationBoxPage($viewer, $title, $content)
->setAnchor('types');
foreach ($types as $type) {
$section = array();
@ -130,15 +129,18 @@ abstract class PhabricatorEditEngineAPIMethod
'wide',
));
$boxes[] = id(new PHUIObjectBoxView())
->setHeaderText(pht('Transaction Type: %s', $type->getEditType()))
->setCollapsed(true)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->appendChild($this->buildRemarkup($section))
->appendChild($type_table);
$title = $type->getEditType();
$content = array(
$this->buildRemarkup($section),
$type_table,
);
$pages[] = $this->newDocumentationBoxPage($viewer, $title, $content)
->setAnchor($type->getEditType())
->setIconIcon('fa-pencil');
}
return $boxes;
return $pages;
}

View file

@ -11,9 +11,7 @@ final class EdgeSearchConduitAPIMethod
return pht('Read edge relationships between objects.');
}
public function getMethodDocumentation() {
$viewer = $this->getViewer();
protected function newDocumentationPages(PhabricatorUser $viewer) {
$rows = array();
foreach ($this->getConduitEdgeTypeMap() as $key => $type) {
$inverse_constant = $type->getInverseEdgeConstant();
@ -48,17 +46,11 @@ final class EdgeSearchConduitAPIMethod
'wide',
));
return id(new PHUIObjectBoxView())
->setHeaderText(pht('Edge Types'))
->setTable($types_table);
}
public function getMethodStatus() {
return self::METHOD_STATUS_UNSTABLE;
}
public function getMethodStatusDescription() {
return pht('This method is new and experimental.');
return array(
$this->newDocumentationBoxPage($viewer, pht('Edge Types'), $types_table)
->setAnchor('types'),
);
}
protected function defineParamTypes() {

View file

@ -75,11 +75,10 @@
padding: 4px 10px;
}
.phui-list-sidenav .phui-list-item-has-icon .phui-list-item-indented {
padding-left: 18px;
.phabricator-side-menu .phui-list-item-has-icon .phui-list-item-indented {
padding-left: 24px;
}
.device-desktop .phui-list-sidenav .phui-list-item-href:hover {
background: {$sky};
color: white;