diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index e7c0a58ec9..8e9b1734f9 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1751,6 +1751,7 @@ phutil_register_library_map(array( 'PholioMockListController' => 'applications/pholio/controller/PholioMockListController.php', 'PholioMockMailReceiver' => 'applications/pholio/mail/PholioMockMailReceiver.php', 'PholioMockQuery' => 'applications/pholio/query/PholioMockQuery.php', + 'PholioMockSearchEngine' => 'applications/pholio/query/PholioMockSearchEngine.php', 'PholioMockViewController' => 'applications/pholio/controller/PholioMockViewController.php', 'PholioPHIDTypeMock' => 'applications/pholio/phid/PholioPHIDTypeMock.php', 'PholioRemarkupRule' => 'applications/pholio/remarkup/PholioRemarkupRule.php', @@ -3787,9 +3788,14 @@ phutil_register_library_map(array( 'PholioMockEditor' => 'PhabricatorApplicationTransactionEditor', 'PholioMockEmbedView' => 'AphrontView', 'PholioMockImagesView' => 'AphrontView', - 'PholioMockListController' => 'PholioController', + 'PholioMockListController' => + array( + 0 => 'PholioController', + 1 => 'PhabricatorApplicationSearchResultsControllerInterface', + ), 'PholioMockMailReceiver' => 'PhabricatorObjectMailReceiver', 'PholioMockQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', + 'PholioMockSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PholioMockViewController' => 'PholioController', 'PholioPHIDTypeMock' => 'PhabricatorPHIDType', 'PholioRemarkupRule' => 'PhabricatorRemarkupRuleObject', diff --git a/src/applications/pholio/application/PhabricatorApplicationPholio.php b/src/applications/pholio/application/PhabricatorApplicationPholio.php index 70506f6727..a5d5cb27f2 100644 --- a/src/applications/pholio/application/PhabricatorApplicationPholio.php +++ b/src/applications/pholio/application/PhabricatorApplicationPholio.php @@ -44,8 +44,7 @@ final class PhabricatorApplicationPholio extends PhabricatorApplication { return array( '/M(?P[1-9]\d*)(?:/(?P\d+)/)?' => 'PholioMockViewController', '/pholio/' => array( - '' => 'PholioMockListController', - 'view/(?P\w+)/' => 'PholioMockListController', + '(?:query/(?P[^/]+)/)?' => 'PholioMockListController', 'new/' => 'PholioMockEditController', 'edit/(?P\d+)/' => 'PholioMockEditController', 'comment/(?P\d+)/' => 'PholioMockCommentController', diff --git a/src/applications/pholio/controller/PholioController.php b/src/applications/pholio/controller/PholioController.php index 5aee9521f5..3d404f8fbc 100644 --- a/src/applications/pholio/controller/PholioController.php +++ b/src/applications/pholio/controller/PholioController.php @@ -5,18 +5,22 @@ */ abstract class PholioController extends PhabricatorController { - public function buildSideNav($filter = null, $for_app = false) { + public function buildSideNavView($for_app = false) { + $user = $this->getRequest()->getUser(); + $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); - $nav->addLabel('Mocks'); - $nav->addFilter('view/all', pht('All Mocks')); - $nav->addFilter('view/my', pht('My Mocks')); + id(new PholioMockSearchEngine()) + ->setViewer($user) + ->addNavigationItems($nav->getMenu()); if ($for_app) { $nav->addFilter('new/', pht('Create Mock')); } + $nav->selectFilter(null); + return $nav; } @@ -33,7 +37,7 @@ abstract class PholioController extends PhabricatorController { } public function buildApplicationMenu() { - return $this->buildSideNav(null, true)->getMenu(); + return $this->buildSideNavView(true)->getMenu(); } diff --git a/src/applications/pholio/controller/PholioMockEditController.php b/src/applications/pholio/controller/PholioMockEditController.php index 28e0cb4cfc..40b6c514fa 100644 --- a/src/applications/pholio/controller/PholioMockEditController.php +++ b/src/applications/pholio/controller/PholioMockEditController.php @@ -277,7 +277,7 @@ final class PholioMockEditController extends PholioController { ->setError($e_images)) ->appendChild($submit); - $crumbs = $this->buildApplicationCrumbs($this->buildSideNav()); + $crumbs = $this->buildApplicationCrumbs(); $crumbs->addCrumb( id(new PhabricatorCrumbView()) ->setName($title) @@ -289,12 +289,8 @@ final class PholioMockEditController extends PholioController { $form, ); - $nav = $this->buildSideNav(); - $nav->selectFilter(null); - $nav->appendChild($content); - return $this->buildApplicationPage( - $nav, + $content, array( 'title' => $title, 'device' => true, diff --git a/src/applications/pholio/controller/PholioMockListController.php b/src/applications/pholio/controller/PholioMockListController.php index b0a3bf9b02..63a7b24a43 100644 --- a/src/applications/pholio/controller/PholioMockListController.php +++ b/src/applications/pholio/controller/PholioMockListController.php @@ -1,45 +1,35 @@ view = idx($data, 'view'); + $this->queryKey = idx($data, 'queryKey'); } public function processRequest() { $request = $this->getRequest(); - $user = $request->getUser(); - $viewer_phid = $user->getPHID(); + $controller = id(new PhabricatorApplicationSearchController($request)) + ->setQueryKey($this->queryKey) + ->setSearchEngine(new PholioMockSearchEngine()) + ->setNavigation($this->buildSideNavView()); - $query = id(new PholioMockQuery()) - ->setViewer($user) - ->needCoverFiles(true) - ->needImages(true) - ->needTokenCounts(true); + return $this->delegateToController($controller); + } - $nav = $this->buildSideNav(); - $filter = $nav->selectFilter('view/'.$this->view, 'view/all'); + public function renderResultsList( + array $mocks, + PhabricatorSavedQuery $query) { + assert_instances_of($mocks, 'PholioMock'); - switch ($filter) { - case 'view/all': - default: - $title = pht('All Mocks'); - break; - case 'view/my': - $title = pht('My Mocks'); - $query->withAuthorPHIDs(array($viewer_phid)); - break; - } - - $pager = new AphrontCursorPagerView(); - $pager->readFromRequest($request); - - $mocks = $query->executeWithCursorPager($pager); + $viewer = $this->getRequest()->getUser(); $author_phids = array(); foreach ($mocks as $mock) { @@ -47,47 +37,27 @@ final class PholioMockListController extends PholioController { } $this->loadHandles($author_phids); - $board = new PhabricatorPinboardView(); foreach ($mocks as $mock) { - $item = new PhabricatorPinboardItemView(); - $item->setHeader('M'.$mock->getID().' '.$mock->getName()) - ->setURI('/M'.$mock->getID()) - ->setImageURI($mock->getCoverFile()->getThumb280x210URI()) - ->setImageSize(280, 210) - ->addIconCount('image', count($mock->getImages())) - ->addIconCount('like', $mock->getTokenCount()); + $item = id(new PhabricatorPinboardItemView()) + ->setHeader('M'.$mock->getID().' '.$mock->getName()) + ->setURI('/M'.$mock->getID()) + ->setImageURI($mock->getCoverFile()->getThumb280x210URI()) + ->setImageSize(280, 210) + ->addIconCount('image', count($mock->getImages())) + ->addIconCount('like', $mock->getTokenCount()); if ($mock->getAuthorPHID()) { $author_handle = $this->getHandle($mock->getAuthorPHID()); - $datetime = phabricator_date($mock->getDateCreated(), $user); + $datetime = phabricator_date($mock->getDateCreated(), $viewer); $item->appendChild( pht('By %s on %s', $author_handle->renderLink(), $datetime)); } + $board->addItem($item); } - $content = array( - $board, - $pager, - ); - - $nav->appendChild($content); - - $crumbs = $this->buildApplicationCrumbs($this->buildSideNav()); - $crumbs->addCrumb( - id(new PhabricatorCrumbView()) - ->setName($title) - ->setHref($this->getApplicationURI())); - $nav->setCrumbs($crumbs); - - return $this->buildApplicationPage( - $nav, - array( - 'title' => $title, - 'device' => true, - 'dust' => true, - )); + return $board; } } diff --git a/src/applications/pholio/controller/PholioMockViewController.php b/src/applications/pholio/controller/PholioMockViewController.php index 8c4a14bccd..96fdd37402 100644 --- a/src/applications/pholio/controller/PholioMockViewController.php +++ b/src/applications/pholio/controller/PholioMockViewController.php @@ -91,7 +91,7 @@ final class PholioMockViewController extends PholioController { $add_comment = $this->buildAddCommentView($mock, $comment_form_id); - $crumbs = $this->buildApplicationCrumbs($this->buildSideNav()); + $crumbs = $this->buildApplicationCrumbs(); $crumbs->setActionList($actions); $crumbs->addCrumb( id(new PhabricatorCrumbView()) diff --git a/src/applications/pholio/query/PholioMockSearchEngine.php b/src/applications/pholio/query/PholioMockSearchEngine.php new file mode 100644 index 0000000000..57ffa2127c --- /dev/null +++ b/src/applications/pholio/query/PholioMockSearchEngine.php @@ -0,0 +1,78 @@ +setParameter( + 'authorPHIDs', + array_values($request->getArr('authors'))); + + return $saved; + } + + public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { + $query = id(new PholioMockQuery()) + ->needCoverFiles(true) + ->needImages(true) + ->needTokenCounts(true) + ->withAuthorPHIDs($saved->getParameter('authorPHIDs', array())); + + return $query; + } + + public function buildSearchForm( + AphrontFormView $form, + PhabricatorSavedQuery $saved_query) { + + $phids = $saved_query->getParameter('authorPHIDs', array()); + $handles = id(new PhabricatorObjectHandleData($phids)) + ->setViewer($this->requireViewer()) + ->loadHandles(); + $author_tokens = mpull($handles, 'getFullName', 'getPHID'); + + $form + ->appendChild( + id(new AphrontFormTokenizerControl()) + ->setDatasource('/typeahead/common/users/') + ->setName('authors') + ->setLabel(pht('Authors')) + ->setValue($author_tokens)); + + } + + protected function getURI($path) { + return '/pholio/'.$path; + } + + public function getBuiltinQueryNames() { + $names = array( + 'all' => pht('All Mocks'), + ); + + if ($this->requireViewer()->isLoggedIn()) { + $names['authored'] = pht('Authored'); + } + + return $names; + } + + public function buildSavedQueryFromBuiltin($query_key) { + + $query = $this->newSavedQuery(); + $query->setQueryKey($query_key); + + switch ($query_key) { + case 'all': + return $query; + case 'authored': + return $query->setParameter( + 'authorPHIDs', + array($this->requireViewer()->getPHID())); + } + + return parent::buildSavedQueryFromBuiltin($query_key); + } + +}