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 @@ -932,6 +932,7 @@ 'ManiphestTaskProject' => 'applications/maniphest/storage/ManiphestTaskProject.php', 'ManiphestTaskProjectsView' => 'applications/maniphest/view/ManiphestTaskProjectsView.php', 'ManiphestTaskQuery' => 'applications/maniphest/query/ManiphestTaskQuery.php', + 'ManiphestTaskResultListView' => 'applications/maniphest/view/ManiphestTaskResultListView.php', 'ManiphestTaskSearchEngine' => 'applications/maniphest/query/ManiphestTaskSearchEngine.php', 'ManiphestTaskStatus' => 'applications/maniphest/constants/ManiphestTaskStatus.php', 'ManiphestTaskStatusTestCase' => 'applications/maniphest/constants/__tests__/ManiphestTaskStatusTestCase.php', @@ -3649,11 +3650,7 @@ 'ManiphestTaskDescriptionPreviewController' => 'ManiphestController', 'ManiphestTaskDetailController' => 'ManiphestController', 'ManiphestTaskEditController' => 'ManiphestController', - 'ManiphestTaskListController' => - array( - 0 => 'ManiphestController', - 1 => 'PhabricatorApplicationSearchResultsControllerInterface', - ), + 'ManiphestTaskListController' => 'ManiphestController', 'ManiphestTaskListView' => 'ManiphestView', 'ManiphestTaskMailReceiver' => 'PhabricatorObjectMailReceiver', 'ManiphestTaskOwner' => 'ManiphestConstants', @@ -3661,6 +3658,7 @@ 'ManiphestTaskProject' => 'ManiphestDAO', 'ManiphestTaskProjectsView' => 'ManiphestView', 'ManiphestTaskQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', + 'ManiphestTaskResultListView' => 'ManiphestView', 'ManiphestTaskSearchEngine' => 'PhabricatorApplicationSearchEngine', 'ManiphestTaskStatus' => 'ManiphestConstants', 'ManiphestTaskStatusTestCase' => 'PhabricatorTestCase', @@ -4635,11 +4633,7 @@ 'PhabricatorPasteDAO' => 'PhabricatorLiskDAO', 'PhabricatorPasteEditController' => 'PhabricatorPasteController', 'PhabricatorPasteEditor' => 'PhabricatorApplicationTransactionEditor', - 'PhabricatorPasteListController' => - array( - 0 => 'PhabricatorPasteController', - 1 => 'PhabricatorApplicationSearchResultsControllerInterface', - ), + 'PhabricatorPasteListController' => 'PhabricatorPasteController', 'PhabricatorPastePHIDTypePaste' => 'PhabricatorPHIDType', 'PhabricatorPasteQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorPasteRemarkupRule' => 'PhabricatorRemarkupRuleObject', @@ -4658,18 +4652,10 @@ 'PhabricatorPeopleEmpowerController' => 'PhabricatorPeopleController', 'PhabricatorPeopleHovercardEventListener' => 'PhabricatorEventListener', 'PhabricatorPeopleLdapController' => 'PhabricatorPeopleController', - 'PhabricatorPeopleListController' => - array( - 0 => 'PhabricatorPeopleController', - 1 => 'PhabricatorApplicationSearchResultsControllerInterface', - ), + 'PhabricatorPeopleListController' => 'PhabricatorPeopleController', 'PhabricatorPeopleLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorPeopleLogSearchEngine' => 'PhabricatorApplicationSearchEngine', - 'PhabricatorPeopleLogsController' => - array( - 0 => 'PhabricatorPeopleController', - 1 => 'PhabricatorApplicationSearchResultsControllerInterface', - ), + 'PhabricatorPeopleLogsController' => 'PhabricatorPeopleController', 'PhabricatorPeopleNewController' => 'PhabricatorPeopleController', 'PhabricatorPeoplePHIDTypeExternal' => 'PhabricatorPHIDType', 'PhabricatorPeoplePHIDTypeUser' => 'PhabricatorPHIDType', diff --git a/src/applications/maniphest/controller/ManiphestTaskListController.php b/src/applications/maniphest/controller/ManiphestTaskListController.php --- a/src/applications/maniphest/controller/ManiphestTaskListController.php +++ b/src/applications/maniphest/controller/ManiphestTaskListController.php @@ -1,8 +1,7 @@ getRequest(); $controller = id(new PhabricatorApplicationSearchController($request)) ->setQueryKey($this->queryKey) - ->setSearchEngine(new ManiphestTaskSearchEngine()) + ->setSearchEngine( + id(new ManiphestTaskSearchEngine()) + ->setShowBatchControls(true)) ->setNavigation($this->buildSideNavView()); return $this->delegateToController($controller); } - public function renderResultsList( - array $tasks, - PhabricatorSavedQuery $query) { - assert_instances_of($tasks, 'ManiphestTask'); - - $viewer = $this->getRequest()->getUser(); - - // If we didn't match anything, just pick up the default empty state. - if (!$tasks) { - return id(new PHUIObjectItemListView()) - ->setUser($viewer); - } - - $group_parameter = nonempty($query->getParameter('group'), 'priority'); - $order_parameter = nonempty($query->getParameter('order'), 'priority'); - - $handles = ManiphestTaskListView::loadTaskHandles($viewer, $tasks); - $groups = $this->groupTasks( - $tasks, - $group_parameter, - $handles); - - $can_edit_priority = $this->hasApplicationCapability( - ManiphestCapabilityEditPriority::CAPABILITY); - - $can_drag = ($order_parameter == 'priority') && - ($can_edit_priority) && - ($group_parameter == 'none' || $group_parameter == 'priority'); - - if (!$viewer->isLoggedIn()) { - // TODO: (T603) Eventually, we conceivably need to make each task - // draggable individually, since the user may be able to edit some but - // not others. - $can_drag = false; - } - - $result = array(); - - $lists = array(); - foreach ($groups as $group => $list) { - $task_list = new ManiphestTaskListView(); - $task_list->setShowBatchControls(true); - if ($can_drag) { - $task_list->setShowSubpriorityControls(true); - } - $task_list->setUser($viewer); - $task_list->setTasks($list); - $task_list->setHandles($handles); - - $header = javelin_tag( - 'h1', - array( - 'class' => 'maniphest-task-group-header', - 'sigil' => 'task-group', - 'meta' => array( - 'priority' => head($list)->getPriority(), - ), - ), - pht('%s (%s)', $group, new PhutilNumber(count($list)))); - - $lists[] = phutil_tag( - 'div', - array( - 'class' => 'maniphest-task-group' - ), - array( - $header, - $task_list, - )); - } - - if ($can_drag) { - Javelin::initBehavior( - 'maniphest-subpriority-editor', - array( - 'uri' => '/maniphest/subpriority/', - )); - } - - return phutil_tag( - 'div', - array( - 'class' => 'maniphest-list-container', - ), - array( - $lists, - $this->renderBatchEditor($query), - )); - } - - private function groupTasks(array $tasks, $group, array $handles) { - assert_instances_of($tasks, 'ManiphestTask'); - assert_instances_of($handles, 'PhabricatorObjectHandle'); - - $groups = $this->getTaskGrouping($tasks, $group); - - $results = array(); - foreach ($groups as $label_key => $tasks) { - $label = $this->getTaskLabelName($group, $label_key, $handles); - $results[$label][] = $tasks; - } - foreach ($results as $label => $task_groups) { - $results[$label] = array_mergev($task_groups); - } - - return $results; - } - - private function getTaskGrouping(array $tasks, $group) { - switch ($group) { - case 'priority': - return mgroup($tasks, 'getPriority'); - case 'status': - return mgroup($tasks, 'getStatus'); - case 'assigned': - return mgroup($tasks, 'getOwnerPHID'); - case 'project': - return mgroup($tasks, 'getGroupByProjectPHID'); - default: - return array(pht('Tasks') => $tasks); - } - } - - private function getTaskLabelName($group, $label_key, array $handles) { - switch ($group) { - case 'priority': - return ManiphestTaskPriority::getTaskPriorityName($label_key); - case 'status': - return ManiphestTaskStatus::getTaskStatusFullName($label_key); - case 'assigned': - if ($label_key) { - return $handles[$label_key]->getFullName(); - } else { - return pht('(Not Assigned)'); - } - case 'project': - if ($label_key) { - return $handles[$label_key]->getFullName(); - } else { - return pht('(No Project)'); - } - default: - return pht('Tasks'); - } - } - - private function renderBatchEditor(PhabricatorSavedQuery $saved_query) { - $user = $this->getRequest()->getUser(); - - $batch_capability = ManiphestCapabilityBulkEdit::CAPABILITY; - if (!$this->hasApplicationCapability($batch_capability)) { - return null; - } - - if (!$user->isLoggedIn()) { - // Don't show the batch editor or excel export for logged-out users. - // Technically we //could// let them export, but ehh. - return null; - } - - Javelin::initBehavior( - 'maniphest-batch-selector', - array( - 'selectAll' => 'batch-select-all', - 'selectNone' => 'batch-select-none', - 'submit' => 'batch-select-submit', - 'status' => 'batch-select-status-cell', - 'idContainer' => 'batch-select-id-container', - 'formID' => 'batch-select-form', - )); - - $select_all = javelin_tag( - 'a', - array( - 'href' => '#', - 'mustcapture' => true, - 'class' => 'grey button', - 'id' => 'batch-select-all', - ), - pht('Select All')); - - $select_none = javelin_tag( - 'a', - array( - 'href' => '#', - 'mustcapture' => true, - 'class' => 'grey button', - 'id' => 'batch-select-none', - ), - pht('Clear Selection')); - - $submit = phutil_tag( - 'button', - array( - 'id' => 'batch-select-submit', - 'disabled' => 'disabled', - 'class' => 'disabled', - ), - pht("Batch Edit Selected \xC2\xBB")); - - $export = javelin_tag( - 'a', - array( - 'href' => '/maniphest/export/'.$saved_query->getQueryKey().'/', - 'class' => 'grey button', - ), - pht('Export to Excel')); - - $hidden = phutil_tag( - 'div', - array( - 'id' => 'batch-select-id-container', - ), - ''); - - $editor = hsprintf( - '
'. - '
%s
'. - ''. - ''. - ''. - ''. - ''. - ''. - ''. - '
%s%s%s%s%s%s
'. - '
', - pht('Batch Task Editor'), - $select_all, - $select_none, - $export, - '', - $submit, - $hidden); - - $editor = phabricator_form( - $user, - array( - 'method' => 'POST', - 'action' => '/maniphest/batch/', - 'id' => 'batch-select-form', - ), - $editor); - - return $editor; - } - } diff --git a/src/applications/maniphest/query/ManiphestTaskSearchEngine.php b/src/applications/maniphest/query/ManiphestTaskSearchEngine.php --- a/src/applications/maniphest/query/ManiphestTaskSearchEngine.php +++ b/src/applications/maniphest/query/ManiphestTaskSearchEngine.php @@ -3,6 +3,17 @@ final class ManiphestTaskSearchEngine extends PhabricatorApplicationSearchEngine { + private $showBatchControls; + + public function setShowBatchControls($show_batch_controls) { + $this->showBatchControls = $show_batch_controls; + return $this; + } + + public function getApplicationClassName() { + return 'PhabricatorApplicationManiphest'; + } + public function getCustomFieldObject() { return new ManiphestTask(); } @@ -473,4 +484,30 @@ ); } + protected function renderResultList( + array $tasks, + PhabricatorSavedQuery $saved, + array $handles) { + + $viewer = $this->requireViewer(); + + $can_edit_priority = PhabricatorPolicyFilter::hasCapability( + $viewer, + $this->getApplication(), + ManiphestCapabilityEditPriority::CAPABILITY); + + $can_bulk_edit = PhabricatorPolicyFilter::hasCapability( + $viewer, + $this->getApplication(), + ManiphestCapabilityBulkEdit::CAPABILITY); + + return id(new ManiphestTaskResultListView()) + ->setUser($viewer) + ->setTasks($tasks) + ->setSavedQuery($saved) + ->setCanEditPriority($can_edit_priority) + ->setCanBatchEdit($can_bulk_edit) + ->setShowBatchControls($this->showBatchControls); + } + } diff --git a/src/applications/maniphest/controller/ManiphestTaskListController.php b/src/applications/maniphest/view/ManiphestTaskResultListView.php copy from src/applications/maniphest/controller/ManiphestTaskListController.php copy to src/applications/maniphest/view/ManiphestTaskResultListView.php --- a/src/applications/maniphest/controller/ManiphestTaskListController.php +++ b/src/applications/maniphest/view/ManiphestTaskResultListView.php @@ -1,35 +1,42 @@ savedQuery = $query; + return $this; } - public function willProcessRequest(array $data) { - $this->queryKey = idx($data, 'queryKey'); + public function setTasks(array $tasks) { + $this->tasks = $tasks; + return $this; } - public function processRequest() { - $request = $this->getRequest(); - $controller = id(new PhabricatorApplicationSearchController($request)) - ->setQueryKey($this->queryKey) - ->setSearchEngine(new ManiphestTaskSearchEngine()) - ->setNavigation($this->buildSideNavView()); + public function setCanEditPriority($can_edit_priority) { + $this->canEditPriority = $can_edit_priority; + return $this; + } - return $this->delegateToController($controller); + public function setCanBatchEdit($can_batch_edit) { + $this->canBatchEdit = $can_batch_edit; + return $this; } - public function renderResultsList( - array $tasks, - PhabricatorSavedQuery $query) { - assert_instances_of($tasks, 'ManiphestTask'); + public function setShowBatchControls($show_batch_controls) { + $this->showBatchControls = $show_batch_controls; + return $this; + } - $viewer = $this->getRequest()->getUser(); + public function render() { + $viewer = $this->getUser(); + $tasks = $this->tasks; + $query = $this->savedQuery; // If we didn't match anything, just pick up the default empty state. if (!$tasks) { @@ -46,8 +53,7 @@ $group_parameter, $handles); - $can_edit_priority = $this->hasApplicationCapability( - ManiphestCapabilityEditPriority::CAPABILITY); + $can_edit_priority = $this->canEditPriority; $can_drag = ($order_parameter == 'priority') && ($can_edit_priority) && @@ -65,7 +71,7 @@ $lists = array(); foreach ($groups as $group => $list) { $task_list = new ManiphestTaskListView(); - $task_list->setShowBatchControls(true); + $task_list->setShowBatchControls($this->showBatchControls); if ($can_drag) { $task_list->setShowSubpriorityControls(true); } @@ -110,10 +116,11 @@ ), array( $lists, - $this->renderBatchEditor($query), + $this->showBatchControls ? $this->renderBatchEditor($query) : null, )); } + private function groupTasks(array $tasks, $group, array $handles) { assert_instances_of($tasks, 'ManiphestTask'); assert_instances_of($handles, 'PhabricatorObjectHandle'); @@ -171,10 +178,9 @@ } private function renderBatchEditor(PhabricatorSavedQuery $saved_query) { - $user = $this->getRequest()->getUser(); + $user = $this->getUser(); - $batch_capability = ManiphestCapabilityBulkEdit::CAPABILITY; - if (!$this->hasApplicationCapability($batch_capability)) { + if (!$this->canBatchEdit) { return null; } @@ -270,5 +276,4 @@ return $editor; } - }