1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-26 00:32:42 +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( 'names' => array(
'conpherence.pkg.css' => '0e3cf785', 'conpherence.pkg.css' => '0e3cf785',
'conpherence.pkg.js' => '020aebcf', 'conpherence.pkg.js' => '020aebcf',
'core.pkg.css' => '0ae696de', 'core.pkg.css' => '00a2e7f4',
'core.pkg.js' => 'd2de90d9', 'core.pkg.js' => 'd2de90d9',
'dark-console.pkg.js' => '187792c2', 'dark-console.pkg.js' => '187792c2',
'differential.pkg.css' => 'ffb69e3d', 'differential.pkg.css' => 'ffb69e3d',
@ -171,7 +171,7 @@ return array(
'rsrc/css/phui/phui-invisible-character-view.css' => 'c694c4a4', 'rsrc/css/phui/phui-invisible-character-view.css' => 'c694c4a4',
'rsrc/css/phui/phui-left-right.css' => '68513c34', 'rsrc/css/phui/phui-left-right.css' => '68513c34',
'rsrc/css/phui/phui-lightbox.css' => '4ebf22da', '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-object-box.css' => 'b8d7eea0',
'rsrc/css/phui/phui-pager.css' => 'd022c7ad', 'rsrc/css/phui/phui-pager.css' => 'd022c7ad',
'rsrc/css/phui/phui-pinboard-view.css' => '1f08f5d8', 'rsrc/css/phui/phui-pinboard-view.css' => '1f08f5d8',
@ -872,7 +872,7 @@ return array(
'phui-invisible-character-view-css' => 'c694c4a4', 'phui-invisible-character-view-css' => 'c694c4a4',
'phui-left-right-css' => '68513c34', 'phui-left-right-css' => '68513c34',
'phui-lightbox-css' => '4ebf22da', 'phui-lightbox-css' => '4ebf22da',
'phui-list-view-css' => '2f253c22', 'phui-list-view-css' => '0c04affd',
'phui-object-box-css' => 'b8d7eea0', 'phui-object-box-css' => 'b8d7eea0',
'phui-oi-big-ui-css' => 'fa74cc35', 'phui-oi-big-ui-css' => 'fa74cc35',
'phui-oi-color-css' => 'b517bfa0', 'phui-oi-color-css' => 'b517bfa0',

View file

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

View file

@ -88,23 +88,118 @@ final class PhabricatorConduitConsoleController
$crumbs->addTextCrumb($method->getAPIMethodName()); $crumbs->addTextCrumb($method->getAPIMethodName());
$crumbs->setBorder(true); $crumbs->setBorder(true);
$documentation_pages = $method->getDocumentationPages($viewer);
$documentation_view = $this->newDocumentationView(
$method,
$documentation_pages);
$view = id(new PHUITwoColumnView()) $view = id(new PHUITwoColumnView())
->setHeader($header) ->setHeader($header)
->setFooter(array( ->setFooter(array(
id(new PhabricatorAnchorView())
->setAnchorName('overview'),
$info_box, $info_box,
$method->getMethodDocumentation(),
id(new PhabricatorAnchorView())
->setAnchorName('documentation'),
$documentation_view,
id(new PhabricatorAnchorView())
->setAnchorName('call'),
$form_box, $form_box,
id(new PhabricatorAnchorView())
->setAnchorName('examples'),
$this->renderExampleBox($method, null), $this->renderExampleBox($method, null),
)); ));
$title = $method->getAPIMethodName(); $title = $method->getAPIMethodName();
$nav = $this->newNavigationView($method, $documentation_pages);
return $this->newPage() return $this->newPage()
->setTitle($title) ->setTitle($title)
->setCrumbs($crumbs) ->setCrumbs($crumbs)
->setNavigation($nav)
->appendChild($view); ->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) { private function buildMethodProperties(ConduitAPIMethod $method) {
$viewer = $this->getViewer(); $viewer = $this->getViewer();
@ -171,7 +266,6 @@ final class PhabricatorConduitConsoleController
pht('Errors'), pht('Errors'),
$error_description); $error_description);
$scope = $method->getRequiredScope(); $scope = $method->getRequiredScope();
switch ($scope) { switch ($scope) {
case ConduitAPIMethod::SCOPE_ALWAYS: case ConduitAPIMethod::SCOPE_ALWAYS:
@ -201,11 +295,6 @@ final class PhabricatorConduitConsoleController
$oauth_description, $oauth_description,
)); ));
$view->addSectionHeader(
pht('Description'), PHUIPropertyListView::ICON_SUMMARY);
$view->addTextContent(
new PHUIRemarkupView($viewer, $method->getMethodDescription()));
return $view; 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(); abstract public function getMethodDescription();
public function getMethodDocumentation() { final public function getDocumentationPages(PhabricatorUser $viewer) {
return null; $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(); abstract protected function defineParamTypes();

View file

@ -7,14 +7,6 @@ abstract class HarbormasterConduitAPIMethod extends ConduitAPIMethod {
'PhabricatorHarbormasterApplication'); '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) { protected function returnArtifactList(array $artifacts) {
$list = array(); $list = array();

View file

@ -60,7 +60,7 @@ abstract class PhabricatorSearchEngineAPIMethod
PhabricatorEnv::getDoclink('Conduit API: Using Search Endpoints')); PhabricatorEnv::getDoclink('Conduit API: Using Search Endpoints'));
} }
final public function getMethodDocumentation() { final protected function newDocumentationPages(PhabricatorUser $viewer) {
$viewer = $this->getViewer(); $viewer = $this->getViewer();
$engine = $this->newSearchEngine() $engine = $this->newSearchEngine()
@ -70,17 +70,18 @@ abstract class PhabricatorSearchEngineAPIMethod
$out = array(); $out = array();
$out[] = $this->buildQueriesBox($engine); $out[] = $this->buildQueriesDocumentationPage($viewer, $engine);
$out[] = $this->buildConstraintsBox($engine); $out[] = $this->buildConstraintsDocumentationPage($viewer, $engine);
$out[] = $this->buildOrderBox($engine, $query); $out[] = $this->buildOrderDocumentationPage($viewer, $engine, $query);
$out[] = $this->buildFieldsBox($engine); $out[] = $this->buildFieldsDocumentationPage($viewer, $engine);
$out[] = $this->buildAttachmentsBox($engine); $out[] = $this->buildAttachmentsDocumentationPage($viewer, $engine);
$out[] = $this->buildPagingBox($engine); $out[] = $this->buildPagingDocumentationPage($viewer, $engine);
return $out; return $out;
} }
private function buildQueriesBox( private function buildQueriesDocumentationPage(
PhabricatorUser $viewer,
PhabricatorApplicationSearchEngine $engine) { PhabricatorApplicationSearchEngine $engine) {
$viewer = $this->getViewer(); $viewer = $this->getViewer();
@ -140,15 +141,18 @@ EOTEXT
null, null,
)); ));
return id(new PHUIObjectBoxView()) $title = pht('Prebuilt Queries');
->setHeaderText(pht('Builtin and Saved Queries')) $content = array(
->setCollapsed(true) $this->newRemarkupDocumentationView($info),
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) $table,
->appendChild($this->newRemarkupDocumentationView($info)) );
->appendChild($table);
return $this->newDocumentationBoxPage($viewer, $title, $content)
->setAnchor('queries');
} }
private function buildConstraintsBox( private function buildConstraintsDocumentationPage(
PhabricatorUser $viewer,
PhabricatorApplicationSearchEngine $engine) { PhabricatorApplicationSearchEngine $engine) {
$info = pht(<<<EOTEXT $info = pht(<<<EOTEXT
@ -281,16 +285,21 @@ EOTEXT
'wide', 'wide',
)); ));
return id(new PHUIObjectBoxView())
->setHeaderText(pht('Custom Query Constraints')) $title = pht('Constraints');
->setCollapsed(true) $content = array(
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) $this->newRemarkupDocumentationView($info),
->appendChild($this->newRemarkupDocumentationView($info)) $table,
->appendChild($table) $constant_lists,
->appendChild($constant_lists); );
return $this->newDocumentationBoxPage($viewer, $title, $content)
->setAnchor('constraints')
->setIconIcon('fa-filter');
} }
private function buildOrderBox( private function buildOrderDocumentationPage(
PhabricatorUser $viewer,
PhabricatorApplicationSearchEngine $engine, PhabricatorApplicationSearchEngine $engine,
$query) { $query) {
@ -388,18 +397,21 @@ EOTEXT
'wide', 'wide',
)); ));
$title = pht('Result Ordering');
$content = array(
$this->newRemarkupDocumentationView($orders_info),
$orders_table,
$this->newRemarkupDocumentationView($columns_info),
$columns_table,
);
return id(new PHUIObjectBoxView()) return $this->newDocumentationBoxPage($viewer, $title, $content)
->setHeaderText(pht('Result Ordering')) ->setAnchor('ordering')
->setCollapsed(true) ->setIconIcon('fa-sort-numeric-asc');
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->appendChild($this->newRemarkupDocumentationView($orders_info))
->appendChild($orders_table)
->appendChild($this->newRemarkupDocumentationView($columns_info))
->appendChild($columns_table);
} }
private function buildFieldsBox( private function buildFieldsDocumentationPage(
PhabricatorUser $viewer,
PhabricatorApplicationSearchEngine $engine) { PhabricatorApplicationSearchEngine $engine) {
$info = pht(<<<EOTEXT $info = pht(<<<EOTEXT
@ -470,15 +482,19 @@ EOTEXT
'wide', 'wide',
)); ));
return id(new PHUIObjectBoxView()) $title = pht('Object Fields');
->setHeaderText(pht('Object Fields')) $content = array(
->setCollapsed(true) $this->newRemarkupDocumentationView($info),
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) $table,
->appendChild($this->newRemarkupDocumentationView($info)) );
->appendChild($table);
return $this->newDocumentationBoxPage($viewer, $title, $content)
->setAnchor('fields')
->setIconIcon('fa-cube');
} }
private function buildAttachmentsBox( private function buildAttachmentsDocumentationPage(
PhabricatorUser $viewer,
PhabricatorApplicationSearchEngine $engine) { PhabricatorApplicationSearchEngine $engine) {
$info = pht(<<<EOTEXT $info = pht(<<<EOTEXT
@ -560,15 +576,19 @@ EOTEXT
'wide', 'wide',
)); ));
return id(new PHUIObjectBoxView()) $title = pht('Attachments');
->setHeaderText(pht('Attachments')) $content = array(
->setCollapsed(true) $this->newRemarkupDocumentationView($info),
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) $table,
->appendChild($this->newRemarkupDocumentationView($info)) );
->appendChild($table);
return $this->newDocumentationBoxPage($viewer, $title, $content)
->setAnchor('attachments')
->setIconIcon('fa-cubes');
} }
private function buildPagingBox( private function buildPagingDocumentationPage(
PhabricatorUser $viewer,
PhabricatorApplicationSearchEngine $engine) { PhabricatorApplicationSearchEngine $engine) {
$info = pht(<<<EOTEXT $info = pht(<<<EOTEXT
@ -631,11 +651,14 @@ if `before` is `null`, there are no previous results available.
EOTEXT EOTEXT
); );
return id(new PHUIObjectBoxView()) $title = pht('Paging and Limits');
->setHeaderText(pht('Paging and Limits')) $content = array(
->setCollapsed(true) $this->newRemarkupDocumentationView($info),
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) );
->appendChild($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.'); 'or an entire object type.');
} }
public function getMethodDocumentation() { protected function newDocumentationPages(PhabricatorUser $viewer) {
$markup = pht(<<<EOREMARKUP $markup = pht(<<<EOREMARKUP
When an object (like a task) is edited, Phabricator creates a "transaction" 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 and applies it. This list of transactions on each object is the basis for
@ -77,11 +77,10 @@ EOREMARKUP
$markup = $this->newRemarkupDocumentationView($markup); $markup = $this->newRemarkupDocumentationView($markup);
return id(new PHUIObjectBoxView()) return array(
->setCollapsed(true) $this->newDocumentationBoxPage($viewer, pht('Method Details'), $markup)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setAnchor('details'),
->setHeaderText(pht('Method Details')) );
->appendChild($markup);
} }
protected function defineParamTypes() { protected function defineParamTypes() {

View file

@ -38,9 +38,7 @@ abstract class PhabricatorEditEngineAPIMethod
PhabricatorEnv::getDoclink('Conduit API: Using Edit Endpoints')); PhabricatorEnv::getDoclink('Conduit API: Using Edit Endpoints'));
} }
final public function getMethodDocumentation() { final protected function newDocumentationPages(PhabricatorUser $viewer) {
$viewer = $this->getViewer();
$engine = $this->newEditEngine() $engine = $this->newEditEngine()
->setViewer($viewer); ->setViewer($viewer);
@ -48,16 +46,15 @@ abstract class PhabricatorEditEngineAPIMethod
$out = array(); $out = array();
$out[] = $this->buildEditTypesBoxes($engine, $types); return $this->buildEditTypesDocumentationPages($viewer, $engine, $types);
return $out;
} }
private function buildEditTypesBoxes( private function buildEditTypesDocumentationPages(
PhabricatorUser $viewer,
PhabricatorEditEngine $engine, PhabricatorEditEngine $engine,
array $types) { array $types) {
$boxes = array(); $pages = array();
$summary_info = pht( $summary_info = pht(
'This endpoint supports these types of transactions. See below for '. 'This endpoint supports these types of transactions. See below for '.
@ -83,12 +80,14 @@ abstract class PhabricatorEditEngineAPIMethod
'wide', 'wide',
)); ));
$boxes[] = id(new PHUIObjectBoxView()) $title = pht('Transaction Summary');
->setHeaderText(pht('Transaction Types')) $content = array(
->setCollapsed(true) $this->buildRemarkup($summary_info),
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) $summary_table,
->appendChild($this->buildRemarkup($summary_info)) );
->appendChild($summary_table);
$pages[] = $this->newDocumentationBoxPage($viewer, $title, $content)
->setAnchor('types');
foreach ($types as $type) { foreach ($types as $type) {
$section = array(); $section = array();
@ -130,15 +129,18 @@ abstract class PhabricatorEditEngineAPIMethod
'wide', 'wide',
)); ));
$boxes[] = id(new PHUIObjectBoxView()) $title = $type->getEditType();
->setHeaderText(pht('Transaction Type: %s', $type->getEditType())) $content = array(
->setCollapsed(true) $this->buildRemarkup($section),
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) $type_table,
->appendChild($this->buildRemarkup($section)) );
->appendChild($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.'); return pht('Read edge relationships between objects.');
} }
public function getMethodDocumentation() { protected function newDocumentationPages(PhabricatorUser $viewer) {
$viewer = $this->getViewer();
$rows = array(); $rows = array();
foreach ($this->getConduitEdgeTypeMap() as $key => $type) { foreach ($this->getConduitEdgeTypeMap() as $key => $type) {
$inverse_constant = $type->getInverseEdgeConstant(); $inverse_constant = $type->getInverseEdgeConstant();
@ -48,17 +46,11 @@ final class EdgeSearchConduitAPIMethod
'wide', 'wide',
)); ));
return id(new PHUIObjectBoxView())
->setHeaderText(pht('Edge Types'))
->setTable($types_table);
}
public function getMethodStatus() { return array(
return self::METHOD_STATUS_UNSTABLE; $this->newDocumentationBoxPage($viewer, pht('Edge Types'), $types_table)
} ->setAnchor('types'),
);
public function getMethodStatusDescription() {
return pht('This method is new and experimental.');
} }
protected function defineParamTypes() { protected function defineParamTypes() {

View file

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