2013-09-10 19:04:26 +02:00
|
|
|
<?php
|
|
|
|
|
2013-09-13 18:50:46 +02:00
|
|
|
final class ManiphestTaskListController
|
2013-09-10 19:04:26 +02:00
|
|
|
extends ManiphestController
|
|
|
|
implements PhabricatorApplicationSearchResultsControllerInterface {
|
|
|
|
|
|
|
|
private $queryKey;
|
|
|
|
|
|
|
|
public function shouldAllowPublic() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function willProcessRequest(array $data) {
|
|
|
|
$this->queryKey = idx($data, 'queryKey');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function processRequest() {
|
|
|
|
$request = $this->getRequest();
|
|
|
|
$controller = id(new PhabricatorApplicationSearchController($request))
|
|
|
|
->setQueryKey($this->queryKey)
|
|
|
|
->setSearchEngine(new ManiphestTaskSearchEngine())
|
|
|
|
->setNavigation($this->buildSideNavView());
|
|
|
|
|
|
|
|
return $this->delegateToController($controller);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function renderResultsList(
|
|
|
|
array $tasks,
|
|
|
|
PhabricatorSavedQuery $query) {
|
|
|
|
assert_instances_of($tasks, 'ManiphestTask');
|
|
|
|
|
|
|
|
$viewer = $this->getRequest()->getUser();
|
|
|
|
|
2013-09-13 01:58:09 +02:00
|
|
|
// If we didn't match anything, just pick up the default empty state.
|
|
|
|
if (!$tasks) {
|
|
|
|
return id(new PHUIObjectItemListView())
|
|
|
|
->setUser($viewer);
|
|
|
|
}
|
|
|
|
|
2013-09-13 16:13:06 +02:00
|
|
|
$group_parameter = nonempty($query->getParameter('group'), 'priority');
|
|
|
|
$order_parameter = nonempty($query->getParameter('order'), 'priority');
|
2013-09-13 01:58:09 +02:00
|
|
|
|
2013-11-13 20:25:57 +01:00
|
|
|
$handles = ManiphestTaskListView::loadTaskHandles($viewer, $tasks);
|
2013-09-13 01:58:09 +02:00
|
|
|
$groups = $this->groupTasks(
|
|
|
|
$tasks,
|
|
|
|
$group_parameter,
|
|
|
|
$handles);
|
|
|
|
|
Add capabilities for editing task triage details (priority, assignee, etc)
Summary:
This is primarily a client request, and a little bit use-case specific, but policies seem to be holding up well and I'm getting more comfortable about maintaining this. Much if it can run through ApplicationTransactions.
Allow the ability to edit status, policies, priorities, assignees and projects of a task to be restricted to some subset of users. Also allow bulk edit to be locked. This affects the editor itself and the edit, view and list interfaces.
Test Plan: As a restricted user, created, edited and commented on tasks. Tried to drag them around.
Reviewers: btrahan
Reviewed By: btrahan
CC: aran
Differential Revision: https://secure.phabricator.com/D7357
2013-10-22 01:59:06 +02:00
|
|
|
$can_edit_priority = $this->hasApplicationCapability(
|
|
|
|
ManiphestCapabilityEditPriority::CAPABILITY);
|
|
|
|
|
2013-09-13 01:58:09 +02:00
|
|
|
$can_drag = ($order_parameter == 'priority') &&
|
Add capabilities for editing task triage details (priority, assignee, etc)
Summary:
This is primarily a client request, and a little bit use-case specific, but policies seem to be holding up well and I'm getting more comfortable about maintaining this. Much if it can run through ApplicationTransactions.
Allow the ability to edit status, policies, priorities, assignees and projects of a task to be restricted to some subset of users. Also allow bulk edit to be locked. This affects the editor itself and the edit, view and list interfaces.
Test Plan: As a restricted user, created, edited and commented on tasks. Tried to drag them around.
Reviewers: btrahan
Reviewed By: btrahan
CC: aran
Differential Revision: https://secure.phabricator.com/D7357
2013-10-22 01:59:06 +02:00
|
|
|
($can_edit_priority) &&
|
2013-09-13 01:58:09 +02:00
|
|
|
($group_parameter == 'none' || $group_parameter == 'priority');
|
|
|
|
|
2013-09-25 22:45:04 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2013-09-13 01:58:09 +02:00
|
|
|
$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,
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
Add capabilities for editing task triage details (priority, assignee, etc)
Summary:
This is primarily a client request, and a little bit use-case specific, but policies seem to be holding up well and I'm getting more comfortable about maintaining this. Much if it can run through ApplicationTransactions.
Allow the ability to edit status, policies, priorities, assignees and projects of a task to be restricted to some subset of users. Also allow bulk edit to be locked. This affects the editor itself and the edit, view and list interfaces.
Test Plan: As a restricted user, created, edited and commented on tasks. Tried to drag them around.
Reviewers: btrahan
Reviewed By: btrahan
CC: aran
Differential Revision: https://secure.phabricator.com/D7357
2013-10-22 01:59:06 +02:00
|
|
|
if ($can_drag) {
|
|
|
|
Javelin::initBehavior(
|
|
|
|
'maniphest-subpriority-editor',
|
|
|
|
array(
|
|
|
|
'uri' => '/maniphest/subpriority/',
|
|
|
|
));
|
|
|
|
}
|
2013-09-13 01:58:09 +02:00
|
|
|
|
|
|
|
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);
|
2013-09-10 19:04:26 +02:00
|
|
|
|
2013-09-13 01:58:09 +02:00
|
|
|
$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);
|
2013-09-10 19:04:26 +02:00
|
|
|
}
|
|
|
|
|
2013-09-13 01:58:09 +02:00
|
|
|
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');
|
|
|
|
}
|
2013-09-10 19:04:26 +02:00
|
|
|
}
|
|
|
|
|
2013-09-13 01:58:09 +02:00
|
|
|
private function renderBatchEditor(PhabricatorSavedQuery $saved_query) {
|
|
|
|
$user = $this->getRequest()->getUser();
|
|
|
|
|
Add capabilities for editing task triage details (priority, assignee, etc)
Summary:
This is primarily a client request, and a little bit use-case specific, but policies seem to be holding up well and I'm getting more comfortable about maintaining this. Much if it can run through ApplicationTransactions.
Allow the ability to edit status, policies, priorities, assignees and projects of a task to be restricted to some subset of users. Also allow bulk edit to be locked. This affects the editor itself and the edit, view and list interfaces.
Test Plan: As a restricted user, created, edited and commented on tasks. Tried to drag them around.
Reviewers: btrahan
Reviewed By: btrahan
CC: aran
Differential Revision: https://secure.phabricator.com/D7357
2013-10-22 01:59:06 +02:00
|
|
|
$batch_capability = ManiphestCapabilityBulkEdit::CAPABILITY;
|
|
|
|
if (!$this->hasApplicationCapability($batch_capability)) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2013-09-25 22:45:04 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2013-09-13 01:58:09 +02:00
|
|
|
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(
|
|
|
|
'<div class="maniphest-batch-editor">'.
|
|
|
|
'<div class="batch-editor-header">%s</div>'.
|
|
|
|
'<table class="maniphest-batch-editor-layout">'.
|
|
|
|
'<tr>'.
|
|
|
|
'<td>%s%s</td>'.
|
|
|
|
'<td>%s</td>'.
|
|
|
|
'<td id="batch-select-status-cell">%s</td>'.
|
|
|
|
'<td class="batch-select-submit-cell">%s%s</td>'.
|
|
|
|
'</tr>'.
|
|
|
|
'</table>'.
|
|
|
|
'</div>',
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2013-09-10 19:04:26 +02:00
|
|
|
}
|