mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-09 16:32:39 +01:00
Add breadcrumbs and ApplicationSearch to Phriction
Summary: Fixes T3631. Also adds ApplicationSearch. Test Plan: Viewed "New", "Edit"; saw breadcrumbs. Viewed "index", saw application search. Reviewers: btrahan, chad Reviewed By: chad CC: aran Maniphest Tasks: T3631 Differential Revision: https://secure.phabricator.com/D6593
This commit is contained in:
parent
091beee730
commit
91c08ca629
6 changed files with 206 additions and 233 deletions
|
@ -1863,6 +1863,7 @@ phutil_register_library_map(array(
|
|||
'PhrictionNewController' => 'applications/phriction/controller/PhrictionNewController.php',
|
||||
'PhrictionPHIDTypeDocument' => 'applications/phriction/phid/PhrictionPHIDTypeDocument.php',
|
||||
'PhrictionRemarkupRule' => 'applications/phriction/remarkup/PhrictionRemarkupRule.php',
|
||||
'PhrictionSearchEngine' => 'applications/phriction/query/PhrictionSearchEngine.php',
|
||||
'PhrictionSearchIndexer' => 'applications/phriction/search/PhrictionSearchIndexer.php',
|
||||
'PonderAddAnswerView' => 'applications/ponder/view/PonderAddAnswerView.php',
|
||||
'PonderAddCommentView' => 'applications/ponder/view/PonderAddCommentView.php',
|
||||
|
@ -3957,11 +3958,16 @@ phutil_register_library_map(array(
|
|||
'PhrictionDocumentTestCase' => 'PhabricatorTestCase',
|
||||
'PhrictionEditController' => 'PhrictionController',
|
||||
'PhrictionHistoryController' => 'PhrictionController',
|
||||
'PhrictionListController' => 'PhrictionController',
|
||||
'PhrictionListController' =>
|
||||
array(
|
||||
0 => 'PhrictionController',
|
||||
1 => 'PhabricatorApplicationSearchResultsControllerInterface',
|
||||
),
|
||||
'PhrictionMoveController' => 'PhrictionController',
|
||||
'PhrictionNewController' => 'PhrictionController',
|
||||
'PhrictionPHIDTypeDocument' => 'PhabricatorPHIDType',
|
||||
'PhrictionRemarkupRule' => 'PhutilRemarkupRule',
|
||||
'PhrictionSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PhrictionSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
|
||||
'PonderAddAnswerView' => 'AphrontView',
|
||||
'PonderAddCommentView' => 'AphrontView',
|
||||
|
|
|
@ -42,8 +42,7 @@ final class PhabricatorApplicationPhriction extends PhabricatorApplication {
|
|||
'/w/(?P<slug>.+/)' => 'PhrictionDocumentController',
|
||||
|
||||
'/phriction/' => array(
|
||||
'' => 'PhrictionListController',
|
||||
'list/(?P<view>[^/]+)/' => 'PhrictionListController',
|
||||
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PhrictionListController',
|
||||
|
||||
'history(?P<slug>/)' => 'PhrictionHistoryController',
|
||||
'history/(?P<slug>.+/)' => 'PhrictionHistoryController',
|
||||
|
|
|
@ -5,45 +5,28 @@
|
|||
*/
|
||||
abstract class PhrictionController extends PhabricatorController {
|
||||
|
||||
public function buildStandardPageResponse($view, array $data) {
|
||||
|
||||
$page = $this->buildStandardPageView();
|
||||
|
||||
$page->setApplicationName(pht('Phriction'));
|
||||
$page->setBaseURI('/w/');
|
||||
$page->setTitle(idx($data, 'title'));
|
||||
$page->setGlyph("\xE2\x9A\xA1");
|
||||
|
||||
$page->appendChild($view);
|
||||
$page->setSearchDefaultScope(PhabricatorSearchScope::SCOPE_WIKI);
|
||||
|
||||
$response = new AphrontWebpageResponse();
|
||||
return $response->setContent($page->render());
|
||||
}
|
||||
|
||||
public function buildSideNavView($filter = null, $for_app = false) {
|
||||
public function buildSideNavView($for_app = false) {
|
||||
$user = $this->getRequest()->getUser();
|
||||
|
||||
$nav = new AphrontSideNavFilterView();
|
||||
$nav->setBaseURI(new PhutilURI('/phriction/list/'));
|
||||
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
|
||||
|
||||
if ($for_app) {
|
||||
$nav->addFilter('', pht('Root Document'), '/w/');
|
||||
$nav->addFilter('', pht('New Document'), '/phriction/new');
|
||||
$nav->addFilter('create', pht('New Document'));
|
||||
$nav->addFilter('/phriction/', pht('Index'));
|
||||
}
|
||||
|
||||
$nav->addLabel(pht('Filters'));
|
||||
$nav->addFilter('active', pht('Active Documents'));
|
||||
$nav->addFilter('all', pht('All Documents'));
|
||||
$nav->addFilter('updates', pht('Recently Updated'));
|
||||
id(new PhrictionSearchEngine())
|
||||
->setViewer($user)
|
||||
->addNavigationItems($nav->getMenu());
|
||||
|
||||
$nav->selectFilter($filter, 'active');
|
||||
$nav->selectFilter(null);
|
||||
|
||||
return $nav;
|
||||
}
|
||||
|
||||
public function buildApplicationMenu() {
|
||||
return $this->buildSideNavView(null, true)->getMenu();
|
||||
return $this->buildSideNavView(true)->getMenu();
|
||||
}
|
||||
|
||||
public function buildApplicationCrumbs() {
|
||||
|
|
|
@ -248,11 +248,26 @@ final class PhrictionEditController
|
|||
'uri' => '/phriction/preview/?draftkey='.$draft_key,
|
||||
));
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
if ($document->getID()) {
|
||||
$crumbs->addCrumb(
|
||||
id(new PhabricatorCrumbView())
|
||||
->setName($content->getTitle())
|
||||
->setHref(PhrictionDocument::getSlugURI($document->getSlug())));
|
||||
$crumbs->addCrumb(
|
||||
id(new PhabricatorCrumbView())
|
||||
->setName(pht('Edit')));
|
||||
} else {
|
||||
$crumbs->addCrumb(
|
||||
id(new PhabricatorCrumbView())
|
||||
->setName(pht('Create')));
|
||||
}
|
||||
|
||||
return $this->buildApplicationPage(
|
||||
array(
|
||||
$crumbs,
|
||||
$draft_note,
|
||||
$error_view,
|
||||
$header,
|
||||
$form,
|
||||
$preview_panel,
|
||||
),
|
||||
|
|
|
@ -1,233 +1,91 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @group phriction
|
||||
*/
|
||||
final class PhrictionListController
|
||||
extends PhrictionController {
|
||||
extends PhrictionController
|
||||
implements PhabricatorApplicationSearchResultsControllerInterface {
|
||||
|
||||
private $view;
|
||||
private $queryKey;
|
||||
|
||||
private $documents;
|
||||
private $handles;
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->view = idx($data, 'view');
|
||||
$this->queryKey = idx($data, 'queryKey');
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
$controller = id(new PhabricatorApplicationSearchController($request))
|
||||
->setQueryKey($this->queryKey)
|
||||
->setSearchEngine(new PhrictionSearchEngine())
|
||||
->setNavigation($this->buildSideNavView());
|
||||
|
||||
$views = array(
|
||||
'active' => pht('Active Documents'),
|
||||
'all' => pht('All Documents'),
|
||||
'updates' => pht('Recently Updated'),
|
||||
);
|
||||
return $this->delegateToController($controller);
|
||||
}
|
||||
|
||||
if (empty($views[$this->view])) {
|
||||
$this->view = 'active';
|
||||
}
|
||||
public function renderResultsList(
|
||||
array $documents,
|
||||
PhabricatorSavedQuery $query) {
|
||||
assert_instances_of($documents, 'PhrictionDocument');
|
||||
|
||||
$nav = $this->buildSideNavView($this->view);
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addCrumb(id(new PhabricatorCrumbView())
|
||||
->setName($views[$this->view])
|
||||
->setHref($this->getApplicationURI('list/' . $this->view)));
|
||||
|
||||
$nav->appendChild(
|
||||
array(
|
||||
$crumbs,
|
||||
));
|
||||
|
||||
$pager = id(new AphrontCursorPagerView())
|
||||
->readFromRequest($request);
|
||||
|
||||
$query = id(new PhrictionDocumentQuery())
|
||||
->setViewer($user);
|
||||
|
||||
switch ($this->view) {
|
||||
case 'active':
|
||||
$query->withStatus(PhrictionDocumentQuery::STATUS_OPEN);
|
||||
break;
|
||||
case 'all':
|
||||
$query->withStatus(PhrictionDocumentQuery::STATUS_NONSTUB);
|
||||
break;
|
||||
case 'updates':
|
||||
$query->withStatus(PhrictionDocumentQuery::STATUS_NONSTUB);
|
||||
$query->setOrder(PhrictionDocumentQuery::ORDER_UPDATED);
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Unknown view '{$this->view}'!");
|
||||
}
|
||||
|
||||
$this->documents = $query->executeWithCursorPager($pager);
|
||||
|
||||
$changeref_docs = array();
|
||||
if ($this->view == 'updates') {
|
||||
// Loading some documents here since they may not appear in the query
|
||||
// results.
|
||||
$changeref_ids = array_filter(mpull(
|
||||
mpull($this->documents, 'getContent'), 'getChangeRef'));
|
||||
if ($changeref_ids) {
|
||||
$changeref_docs = id(new PhrictionDocumentQuery())
|
||||
->setViewer($user)
|
||||
->withIDs($changeref_ids)
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
$viewer = $this->getRequest()->getUser();
|
||||
|
||||
$phids = array();
|
||||
foreach ($this->documents as $document) {
|
||||
$phids[] = $document->getContent()->getAuthorPHID();
|
||||
foreach ($documents as $document) {
|
||||
$content = $document->getContent();
|
||||
if ($document->hasProject()) {
|
||||
$phids[] = $document->getProject()->getPHID();
|
||||
}
|
||||
$phids[] = $content->getAuthorPHID();
|
||||
}
|
||||
|
||||
$this->handles = $this->loadViewerHandles($phids);
|
||||
$this->loadHandles($phids);
|
||||
|
||||
$list = new PhabricatorObjectItemListView();
|
||||
$list->setUser($viewer);
|
||||
foreach ($documents as $document) {
|
||||
$content = $document->getContent();
|
||||
$slug = $document->getSlug();
|
||||
$author_phid = $content->getAuthorPHID();
|
||||
$slug_uri = PhrictionDocument::getSlugURI($slug);
|
||||
|
||||
foreach ($this->documents as $document) {
|
||||
if ($this->view == 'updates') {
|
||||
$list->addItem(
|
||||
$this->buildItemForUpdates($document, $changeref_docs));
|
||||
} else {
|
||||
$list->addItem(
|
||||
$this->buildItemTheCasualWay($document));
|
||||
$byline = pht(
|
||||
'Edited by %s',
|
||||
$this->getHandle($author_phid)->renderLink());
|
||||
|
||||
$updated = phabricator_datetime(
|
||||
$content->getDateCreated(),
|
||||
$viewer);
|
||||
|
||||
$item = id(new PhabricatorObjectItemView())
|
||||
->setHeader($content->getTitle())
|
||||
->setHref($slug_uri)
|
||||
->addByline($byline)
|
||||
->addIcon('none', $updated);
|
||||
|
||||
if ($document->hasProject()) {
|
||||
$item->addAttribute(
|
||||
$this->getHandle($document->getProject()->getPHID())->renderLink());
|
||||
}
|
||||
|
||||
$item->addAttribute($slug_uri);
|
||||
|
||||
switch ($document->getStatus()) {
|
||||
case PhrictionDocumentStatus::STATUS_DELETED:
|
||||
$item->setDisabled(true);
|
||||
$item->addIcon('delete', pht('Deleted'));
|
||||
break;
|
||||
case PhrictionDocumentStatus::STATUS_MOVED:
|
||||
$item->setDisabled(true);
|
||||
$item->addIcon('arrow-right', pht('Moved Away'));
|
||||
break;
|
||||
}
|
||||
|
||||
$list->addItem($item);
|
||||
}
|
||||
|
||||
$nav->appendChild($list);
|
||||
$nav->appendChild($pager);
|
||||
|
||||
return $this->buildApplicationPage(
|
||||
$nav,
|
||||
array(
|
||||
'title' => pht('Document Index'),
|
||||
'dust' => true,
|
||||
));
|
||||
}
|
||||
|
||||
private function buildItemTheCasualWay(PhrictionDocument $document) {
|
||||
$user = $this->getRequest()->getUser();
|
||||
|
||||
$project_link = null;
|
||||
if ($document->hasProject()) {
|
||||
$project_phid = $document->getProject()->getPHID();
|
||||
$project_link = $this->handles[$project_phid]->renderLink();
|
||||
}
|
||||
|
||||
$content = $document->getContent();
|
||||
$author = $this->handles[$content->getAuthorPHID()]->renderLink();
|
||||
$title = $content->getTitle();
|
||||
|
||||
$slug = $document->getSlug();
|
||||
$slug_uri = PhrictionDocument::getSlugURI($slug);
|
||||
$edit_uri = '/phriction/edit/' . $document->getID() . '/';
|
||||
$history_uri = PhrictionDocument::getSlugURI($slug, 'history');
|
||||
|
||||
$item = id(new PhabricatorObjectItemView())
|
||||
->setHeader($title)
|
||||
->setHref($slug_uri)
|
||||
->addAttribute(pht('By %s', $author))
|
||||
->addAttribute(pht('Updated: %s',
|
||||
phabricator_datetime($content->getDateCreated(), $user)))
|
||||
->addAttribute($slug_uri);
|
||||
|
||||
if ($project_link) {
|
||||
$item->addAttribute(pht('Project %s', $project_link));
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
private function buildItemForUpdates(PhrictionDocument $document,
|
||||
array $docs_from_refs) {
|
||||
|
||||
$user = $this->getRequest()->getUser();
|
||||
|
||||
$content = $document->getContent();
|
||||
$version = $content->getVersion();
|
||||
$author = $this->handles[$content->getAuthorPHID()]->renderLink();
|
||||
$title = $content->getTitle();
|
||||
|
||||
$slug = $document->getSlug();
|
||||
$slug_uri = PhrictionDocument::getSlugURI($slug);
|
||||
$document_link = hsprintf('<a href="%s">%s</a>', $slug_uri, $title);
|
||||
|
||||
$change_type = $content->getChangeType();
|
||||
switch ($content->getChangeType()) {
|
||||
case PhrictionChangeType::CHANGE_DELETE:
|
||||
$change_type = pht('%s deleted %s', $author, $document_link);
|
||||
break;
|
||||
case PhrictionChangeType::CHANGE_EDIT:
|
||||
$change_type = pht('%s edited %s', $author, $document_link);
|
||||
break;
|
||||
case PhrictionChangeType::CHANGE_MOVE_HERE:
|
||||
case PhrictionChangeType::CHANGE_MOVE_AWAY:
|
||||
$change_ref = $content->getChangeRef();
|
||||
$ref_doc = idx($docs_from_refs, $change_ref);
|
||||
if (!$ref_doc) {
|
||||
if ($change_type == PhrictionChangeType::CHANGE_MOVE_HERE) {
|
||||
$change_type = pht(
|
||||
'%s moved %s from elsewhere',
|
||||
$author,
|
||||
$document_link);
|
||||
} else {
|
||||
$change_type = pht(
|
||||
'%s moved %s to elsewhere',
|
||||
$author,
|
||||
$document_link);
|
||||
}
|
||||
} else {
|
||||
$ref_doc_slug = PhrictionDocument::getSlugURI($ref_doc->getSlug());
|
||||
$ref_doc_link = hsprintf('<a href="%s">%1$s</a>', $ref_doc_slug);
|
||||
|
||||
if ($change_type == PhrictionChangeType::CHANGE_MOVE_HERE) {
|
||||
$change_type = pht(
|
||||
'%s moved %s from %s',
|
||||
$author,
|
||||
$document_link,
|
||||
$ref_doc_link);
|
||||
} else {
|
||||
$change_type = pht(
|
||||
'%s moved %s to %s',
|
||||
$author,
|
||||
$document_link,
|
||||
$ref_doc_link);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Unknown change type!");
|
||||
break;
|
||||
}
|
||||
|
||||
$item = id(new PhabricatorObjectItemView())
|
||||
->setHeader($change_type)
|
||||
->addAttribute(phabricator_datetime($content->getDateCreated(), $user))
|
||||
->addAttribute($slug_uri);
|
||||
|
||||
if ($content->getDescription()) {
|
||||
$item->addAttribute($content->getDescription());
|
||||
}
|
||||
|
||||
if ($version > 1) {
|
||||
$diff_uri = new PhutilURI('/phriction/diff/'.$document->getID().'/');
|
||||
$uri = $diff_uri->alter('l', $version - 1)->alter('r', $version);
|
||||
$item->addIcon('history', pht('View Change'),
|
||||
array(
|
||||
'href' => $uri,
|
||||
));
|
||||
} else {
|
||||
$item->addIcon('history-grey', pht('No diff available'));
|
||||
}
|
||||
|
||||
return $item;
|
||||
return $list;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
112
src/applications/phriction/query/PhrictionSearchEngine.php
Normal file
112
src/applications/phriction/query/PhrictionSearchEngine.php
Normal file
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
|
||||
final class PhrictionSearchEngine
|
||||
extends PhabricatorApplicationSearchEngine {
|
||||
|
||||
public function buildSavedQueryFromRequest(AphrontRequest $request) {
|
||||
$saved = new PhabricatorSavedQuery();
|
||||
|
||||
$saved->setParameter('status', $request->getArr('status'));
|
||||
$saved->setParameter('order', $request->getArr('order'));
|
||||
|
||||
return $saved;
|
||||
}
|
||||
|
||||
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
|
||||
$query = id(new PhrictionDocumentQuery())
|
||||
->withStatus(PhrictionDocumentQuery::STATUS_NONSTUB);
|
||||
|
||||
$status = $saved->getParameter('status');
|
||||
$status = idx($this->getStatusValues(), $status);
|
||||
if ($status) {
|
||||
$query->withStatus($status);
|
||||
}
|
||||
|
||||
$order = $saved->getParameter('order');
|
||||
$order = idx($this->getOrderValues(), $order);
|
||||
if ($order) {
|
||||
$query->setOrder($order);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function buildSearchForm(
|
||||
AphrontFormView $form,
|
||||
PhabricatorSavedQuery $saved_query) {
|
||||
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setLabel(pht('Status'))
|
||||
->setName('status')
|
||||
->setOptions($this->getStatusOptions())
|
||||
->setValue($saved_query->getParameter('status')))
|
||||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setLabel(pht('Order'))
|
||||
->setName('order')
|
||||
->setOptions($this->getOrderOptions())
|
||||
->setValue($saved_query->getParameter('order')));
|
||||
}
|
||||
|
||||
protected function getURI($path) {
|
||||
return '/phriction/'.$path;
|
||||
}
|
||||
|
||||
public function getBuiltinQueryNames() {
|
||||
$names = array(
|
||||
'active' => pht('Active'),
|
||||
'updated' => pht('Updated'),
|
||||
'all' => pht('All'),
|
||||
);
|
||||
|
||||
return $names;
|
||||
}
|
||||
|
||||
public function buildSavedQueryFromBuiltin($query_key) {
|
||||
|
||||
$query = $this->newSavedQuery();
|
||||
$query->setQueryKey($query_key);
|
||||
|
||||
switch ($query_key) {
|
||||
case 'active':
|
||||
return $query->setParameter('status', 'active');
|
||||
case 'all':
|
||||
return $query;
|
||||
case 'updated':
|
||||
return $query->setParameter('order', 'updated');
|
||||
}
|
||||
|
||||
return parent::buildSavedQueryFromBuiltin($query_key);
|
||||
}
|
||||
|
||||
private function getStatusOptions() {
|
||||
return array(
|
||||
'active' => pht('Show Active Documents'),
|
||||
'all' => pht('Show All Documents'),
|
||||
);
|
||||
}
|
||||
|
||||
private function getStatusValues() {
|
||||
return array(
|
||||
'active' => PhrictionDocumentQuery::STATUS_OPEN,
|
||||
'all' => PhrictionDocumentQuery::STATUS_NONSTUB,
|
||||
);
|
||||
}
|
||||
|
||||
private function getOrderOptions() {
|
||||
return array(
|
||||
'created' => pht('Date Created'),
|
||||
'updated' => pht('Date Updated'),
|
||||
);
|
||||
}
|
||||
|
||||
private function getOrderValues() {
|
||||
return array(
|
||||
'created' => PhrictionDocumentQuery::ORDER_CREATED,
|
||||
'updated' => PhrictionDocumentQuery::ORDER_UPDATED,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue