2011-02-08 19:53:59 +01:00
|
|
|
<?php
|
|
|
|
|
2012-03-10 00:46:25 +01:00
|
|
|
final class ManiphestTaskDetailController extends ManiphestController {
|
2011-02-08 19:53:59 +01:00
|
|
|
|
2013-09-25 22:44:52 +02:00
|
|
|
public function shouldAllowPublic() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-08-02 02:06:57 +02:00
|
|
|
public function handleRequest(AphrontRequest $request) {
|
|
|
|
$viewer = $this->getViewer();
|
|
|
|
$id = $request->getURIData('id');
|
2011-02-08 19:53:59 +01:00
|
|
|
|
|
|
|
$e_title = null;
|
|
|
|
|
|
|
|
$priority_map = ManiphestTaskPriority::getTaskPriorityMap();
|
|
|
|
|
2013-09-25 22:44:14 +02:00
|
|
|
$task = id(new ManiphestTaskQuery())
|
2015-08-02 02:06:57 +02:00
|
|
|
->setViewer($viewer)
|
|
|
|
->withIDs(array($id))
|
2014-12-11 01:27:30 +01:00
|
|
|
->needSubscriberPHIDs(true)
|
2013-09-25 22:44:14 +02:00
|
|
|
->executeOne();
|
2011-03-31 06:38:24 +02:00
|
|
|
if (!$task) {
|
|
|
|
return new Aphront404Response();
|
|
|
|
}
|
2011-02-08 19:53:59 +01:00
|
|
|
|
2011-08-03 23:20:05 +02:00
|
|
|
$workflow = $request->getStr('workflow');
|
|
|
|
$parent_task = null;
|
|
|
|
if ($workflow && is_numeric($workflow)) {
|
2013-09-25 22:44:14 +02:00
|
|
|
$parent_task = id(new ManiphestTaskQuery())
|
2015-08-02 02:06:57 +02:00
|
|
|
->setViewer($viewer)
|
2013-09-25 22:44:14 +02:00
|
|
|
->withIDs(array($workflow))
|
|
|
|
->executeOne();
|
2011-08-03 23:20:05 +02:00
|
|
|
}
|
|
|
|
|
2013-09-17 00:58:35 +02:00
|
|
|
$field_list = PhabricatorCustomField::getObjectFields(
|
|
|
|
$task,
|
|
|
|
PhabricatorCustomField::ROLE_VIEW);
|
2014-02-21 23:44:01 +01:00
|
|
|
$field_list
|
2015-08-02 02:06:57 +02:00
|
|
|
->setViewer($viewer)
|
2014-02-21 23:44:01 +01:00
|
|
|
->readFieldsFromStorage($task);
|
2013-03-08 02:24:58 +01:00
|
|
|
|
2014-07-18 00:42:06 +02:00
|
|
|
$e_commit = ManiphestTaskHasCommitEdgeType::EDGECONST;
|
2014-12-28 15:10:49 +01:00
|
|
|
$e_dep_on = ManiphestTaskDependsOnTaskEdgeType::EDGECONST;
|
|
|
|
$e_dep_by = ManiphestTaskDependedOnByTaskEdgeType::EDGECONST;
|
2014-07-18 00:41:08 +02:00
|
|
|
$e_rev = ManiphestTaskHasRevisionEdgeType::EDGECONST;
|
2015-01-02 00:11:41 +01:00
|
|
|
$e_mock = ManiphestTaskHasMockEdgeType::EDGECONST;
|
2012-07-19 05:41:42 +02:00
|
|
|
|
|
|
|
$phid = $task->getPHID();
|
|
|
|
|
|
|
|
$query = id(new PhabricatorEdgeQuery())
|
|
|
|
->withSourcePHIDs(array($phid))
|
|
|
|
->withEdgeTypes(
|
|
|
|
array(
|
|
|
|
$e_commit,
|
|
|
|
$e_dep_on,
|
|
|
|
$e_dep_by,
|
2012-07-20 17:59:39 +02:00
|
|
|
$e_rev,
|
2013-07-20 00:59:29 +02:00
|
|
|
$e_mock,
|
2012-07-19 05:41:42 +02:00
|
|
|
));
|
2012-12-11 23:03:16 +01:00
|
|
|
$edges = idx($query->execute(), $phid);
|
2012-07-19 05:41:42 +02:00
|
|
|
$phids = array_fill_keys($query->getDestinationPHIDs(), true);
|
2012-04-05 02:34:25 +02:00
|
|
|
|
2011-02-08 19:53:59 +01:00
|
|
|
if ($task->getOwnerPHID()) {
|
|
|
|
$phids[$task->getOwnerPHID()] = true;
|
|
|
|
}
|
|
|
|
$phids[$task->getAuthorPHID()] = true;
|
|
|
|
|
2011-02-17 23:32:01 +01:00
|
|
|
$attached = $task->getAttached();
|
|
|
|
foreach ($attached as $type => $list) {
|
|
|
|
foreach ($list as $phid => $info) {
|
|
|
|
$phids[$phid] = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-03 23:20:05 +02:00
|
|
|
if ($parent_task) {
|
|
|
|
$phids[$parent_task->getPHID()] = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
$phids = array_keys($phids);
|
2015-08-02 02:06:57 +02:00
|
|
|
$handles = $viewer->loadHandles($phids);
|
2013-03-08 02:24:58 +01:00
|
|
|
|
2015-03-02 01:07:04 +01:00
|
|
|
$info_view = null;
|
2011-08-03 23:20:05 +02:00
|
|
|
if ($parent_task) {
|
2015-03-02 01:07:04 +01:00
|
|
|
$info_view = new PHUIInfoView();
|
|
|
|
$info_view->setSeverity(PHUIInfoView::SEVERITY_NOTICE);
|
|
|
|
$info_view->addButton(
|
|
|
|
id(new PHUIButtonView())
|
2015-03-02 18:01:04 +01:00
|
|
|
->setTag('a')
|
2015-03-02 01:07:04 +01:00
|
|
|
->setHref('/maniphest/task/create/?parent='.$parent_task->getID())
|
|
|
|
->setText(pht('Create Another Subtask')));
|
|
|
|
|
|
|
|
$info_view->appendChild(hsprintf(
|
2015-03-30 15:18:54 +02:00
|
|
|
'Created a subtask of <strong>%s</strong>.',
|
|
|
|
$handles->renderHandle($parent_task->getPHID())));
|
2011-08-03 23:20:05 +02:00
|
|
|
} else if ($workflow == 'create') {
|
2015-03-02 01:07:04 +01:00
|
|
|
$info_view = new PHUIInfoView();
|
|
|
|
$info_view->setSeverity(PHUIInfoView::SEVERITY_NOTICE);
|
|
|
|
$info_view->addButton(
|
|
|
|
id(new PHUIButtonView())
|
2015-03-02 18:01:04 +01:00
|
|
|
->setTag('a')
|
2015-03-02 01:07:04 +01:00
|
|
|
->setHref('/maniphest/task/create/?template='.$task->getID())
|
|
|
|
->setText(pht('Similar Task')));
|
|
|
|
$info_view->addButton(
|
|
|
|
id(new PHUIButtonView())
|
2015-03-02 18:01:04 +01:00
|
|
|
->setTag('a')
|
2015-03-02 01:07:04 +01:00
|
|
|
->setHref('/maniphest/task/create/')
|
|
|
|
->setText(pht('Empty Task')));
|
|
|
|
$info_view->appendChild(pht('New task created. Create another?'));
|
2011-07-26 19:39:36 +02:00
|
|
|
}
|
2011-02-20 23:15:53 +01:00
|
|
|
|
2012-07-11 20:40:10 +02:00
|
|
|
$engine = new PhabricatorMarkupEngine();
|
2015-08-02 02:06:57 +02:00
|
|
|
$engine->setViewer($viewer);
|
2015-01-01 17:05:51 +01:00
|
|
|
$engine->setContextObject($task);
|
2012-07-11 20:40:10 +02:00
|
|
|
$engine->addObject($task, ManiphestTask::MARKUP_FIELD_DESCRIPTION);
|
|
|
|
|
2014-11-13 23:44:55 +01:00
|
|
|
$timeline = $this->buildTransactionTimeline(
|
|
|
|
$task,
|
|
|
|
new ManiphestTransactionQuery(),
|
|
|
|
$engine);
|
2013-03-08 02:24:33 +01:00
|
|
|
|
2011-02-08 19:53:59 +01:00
|
|
|
$resolution_types = ManiphestTaskStatus::getTaskStatusMap();
|
|
|
|
|
2013-09-25 20:16:43 +02:00
|
|
|
$transaction_types = array(
|
2014-12-11 01:27:30 +01:00
|
|
|
PhabricatorTransactions::TYPE_COMMENT => pht('Comment'),
|
|
|
|
ManiphestTransaction::TYPE_STATUS => pht('Change Status'),
|
|
|
|
ManiphestTransaction::TYPE_OWNER => pht('Reassign / Claim'),
|
|
|
|
PhabricatorTransactions::TYPE_SUBSCRIBERS => pht('Add CCs'),
|
|
|
|
ManiphestTransaction::TYPE_PRIORITY => pht('Change Priority'),
|
2014-12-18 23:17:16 +01:00
|
|
|
PhabricatorTransactions::TYPE_EDGE => pht('Associate Projects'),
|
2013-09-25 20:16:43 +02:00
|
|
|
);
|
|
|
|
|
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
|
|
|
// Remove actions the user doesn't have permission to take.
|
|
|
|
|
|
|
|
$requires = array(
|
|
|
|
ManiphestTransaction::TYPE_OWNER =>
|
2014-07-25 00:20:39 +02:00
|
|
|
ManiphestEditAssignCapability::CAPABILITY,
|
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
|
|
|
ManiphestTransaction::TYPE_PRIORITY =>
|
2014-07-25 00:20:39 +02:00
|
|
|
ManiphestEditPriorityCapability::CAPABILITY,
|
2014-12-18 23:17:16 +01:00
|
|
|
PhabricatorTransactions::TYPE_EDGE =>
|
2014-07-25 00:20:39 +02:00
|
|
|
ManiphestEditProjectsCapability::CAPABILITY,
|
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
|
|
|
ManiphestTransaction::TYPE_STATUS =>
|
2014-07-25 00:20:39 +02:00
|
|
|
ManiphestEditStatusCapability::CAPABILITY,
|
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
|
|
|
);
|
|
|
|
|
|
|
|
foreach ($transaction_types as $type => $name) {
|
|
|
|
if (isset($requires[$type])) {
|
|
|
|
if (!$this->hasApplicationCapability($requires[$type])) {
|
|
|
|
unset($transaction_types[$type]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-25 21:47:42 +01:00
|
|
|
// Don't show an option to change to the current status, or to change to
|
|
|
|
// the duplicate status explicitly.
|
|
|
|
unset($resolution_types[$task->getStatus()]);
|
|
|
|
unset($resolution_types[ManiphestTaskStatus::getDuplicateStatus()]);
|
|
|
|
|
|
|
|
// Don't show owner/priority changes for closed tasks, as they don't make
|
|
|
|
// much sense.
|
|
|
|
if ($task->isClosed()) {
|
2013-09-25 20:16:43 +02:00
|
|
|
unset($transaction_types[ManiphestTransaction::TYPE_PRIORITY]);
|
|
|
|
unset($transaction_types[ManiphestTransaction::TYPE_OWNER]);
|
2011-02-08 19:53:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
$default_claim = array(
|
2015-08-02 02:06:57 +02:00
|
|
|
$viewer->getPHID() => $viewer->getUsername().
|
|
|
|
' ('.$viewer->getRealName().')',
|
2011-02-08 19:53:59 +01:00
|
|
|
);
|
|
|
|
|
2011-05-11 01:18:47 +02:00
|
|
|
$draft = id(new PhabricatorDraft())->loadOneWhere(
|
|
|
|
'authorPHID = %s AND draftKey = %s',
|
2015-08-02 02:06:57 +02:00
|
|
|
$viewer->getPHID(),
|
2011-05-11 01:18:47 +02:00
|
|
|
$task->getPHID());
|
|
|
|
if ($draft) {
|
|
|
|
$draft_text = $draft->getDraft();
|
|
|
|
} else {
|
|
|
|
$draft_text = null;
|
|
|
|
}
|
|
|
|
|
2015-04-18 17:38:47 +02:00
|
|
|
$projects_source = new PhabricatorProjectDatasource();
|
|
|
|
$users_source = new PhabricatorPeopleDatasource();
|
|
|
|
$mailable_source = new PhabricatorMetaMTAMailableDatasource();
|
|
|
|
|
2011-02-08 19:53:59 +01:00
|
|
|
$comment_form = new AphrontFormView();
|
|
|
|
$comment_form
|
2015-08-02 02:06:57 +02:00
|
|
|
->setUser($viewer)
|
2014-03-14 23:13:51 +01:00
|
|
|
->setWorkflow(true)
|
2011-02-08 19:53:59 +01:00
|
|
|
->setAction('/maniphest/transaction/save/')
|
2011-02-21 05:08:16 +01:00
|
|
|
->setEncType('multipart/form-data')
|
2011-02-08 19:53:59 +01:00
|
|
|
->addHiddenInput('taskID', $task->getID())
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormSelectControl())
|
2013-03-13 07:30:03 +01:00
|
|
|
->setLabel(pht('Action'))
|
2011-02-08 19:53:59 +01:00
|
|
|
->setName('action')
|
|
|
|
->setOptions($transaction_types)
|
|
|
|
->setID('transaction-action'))
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormSelectControl())
|
2014-03-25 21:47:42 +01:00
|
|
|
->setLabel(pht('Status'))
|
2011-02-08 19:53:59 +01:00
|
|
|
->setName('resolution')
|
|
|
|
->setControlID('resolution')
|
|
|
|
->setControlStyle('display: none')
|
|
|
|
->setOptions($resolution_types))
|
2015-03-31 23:10:55 +02:00
|
|
|
->appendControl(
|
2011-02-08 19:53:59 +01:00
|
|
|
id(new AphrontFormTokenizerControl())
|
2013-03-13 07:30:03 +01:00
|
|
|
->setLabel(pht('Assign To'))
|
2011-02-08 19:53:59 +01:00
|
|
|
->setName('assign_to')
|
|
|
|
->setControlID('assign_to')
|
|
|
|
->setControlStyle('display: none')
|
|
|
|
->setID('assign-tokenizer')
|
2015-04-18 17:38:47 +02:00
|
|
|
->setDisableBehavior(true)
|
|
|
|
->setDatasource($users_source))
|
2015-03-31 23:10:55 +02:00
|
|
|
->appendControl(
|
2011-02-08 19:53:59 +01:00
|
|
|
id(new AphrontFormTokenizerControl())
|
2013-03-13 07:30:03 +01:00
|
|
|
->setLabel(pht('CCs'))
|
2011-02-08 19:53:59 +01:00
|
|
|
->setName('ccs')
|
|
|
|
->setControlID('ccs')
|
|
|
|
->setControlStyle('display: none')
|
|
|
|
->setID('cc-tokenizer')
|
2015-04-18 17:38:47 +02:00
|
|
|
->setDisableBehavior(true)
|
|
|
|
->setDatasource($mailable_source))
|
2011-02-08 19:53:59 +01:00
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormSelectControl())
|
2013-03-13 07:30:03 +01:00
|
|
|
->setLabel(pht('Priority'))
|
2011-02-08 19:53:59 +01:00
|
|
|
->setName('priority')
|
|
|
|
->setOptions($priority_map)
|
|
|
|
->setControlID('priority')
|
|
|
|
->setControlStyle('display: none')
|
|
|
|
->setValue($task->getPriority()))
|
2015-03-31 23:10:55 +02:00
|
|
|
->appendControl(
|
2011-02-21 05:08:16 +01:00
|
|
|
id(new AphrontFormTokenizerControl())
|
2013-03-13 07:30:03 +01:00
|
|
|
->setLabel(pht('Projects'))
|
2011-02-21 05:08:16 +01:00
|
|
|
->setName('projects')
|
|
|
|
->setControlID('projects')
|
|
|
|
->setControlStyle('display: none')
|
|
|
|
->setID('projects-tokenizer')
|
2015-04-18 17:38:47 +02:00
|
|
|
->setDisableBehavior(true)
|
|
|
|
->setDatasource($projects_source))
|
2011-02-21 05:08:16 +01:00
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormFileControl())
|
2013-03-13 07:30:03 +01:00
|
|
|
->setLabel(pht('File'))
|
2011-02-21 05:08:16 +01:00
|
|
|
->setName('file')
|
|
|
|
->setControlID('file')
|
|
|
|
->setControlStyle('display: none'))
|
2011-02-08 19:53:59 +01:00
|
|
|
->appendChild(
|
2012-09-19 21:27:28 +02:00
|
|
|
id(new PhabricatorRemarkupControl())
|
2015-08-02 02:06:57 +02:00
|
|
|
->setUser($viewer)
|
2013-03-13 07:30:03 +01:00
|
|
|
->setLabel(pht('Comments'))
|
2011-02-08 19:53:59 +01:00
|
|
|
->setName('comments')
|
2011-05-11 01:18:47 +02:00
|
|
|
->setValue($draft_text)
|
2012-11-27 23:06:31 +01:00
|
|
|
->setID('transaction-comments')
|
2015-08-02 02:06:57 +02:00
|
|
|
->setUser($viewer))
|
2014-05-21 21:44:58 +02:00
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormSubmitControl())
|
|
|
|
->setValue(pht('Submit')));
|
2011-02-08 19:53:59 +01:00
|
|
|
|
2011-05-11 13:17:48 +02:00
|
|
|
$control_map = array(
|
2014-12-11 01:27:30 +01:00
|
|
|
ManiphestTransaction::TYPE_STATUS => 'resolution',
|
|
|
|
ManiphestTransaction::TYPE_OWNER => 'assign_to',
|
|
|
|
PhabricatorTransactions::TYPE_SUBSCRIBERS => 'ccs',
|
|
|
|
ManiphestTransaction::TYPE_PRIORITY => 'priority',
|
2014-12-18 23:17:16 +01:00
|
|
|
PhabricatorTransactions::TYPE_EDGE => 'projects',
|
2011-05-11 13:17:48 +02:00
|
|
|
);
|
|
|
|
|
2012-04-14 16:05:58 +02:00
|
|
|
$tokenizer_map = array(
|
2014-12-18 23:17:16 +01:00
|
|
|
PhabricatorTransactions::TYPE_EDGE => array(
|
2012-04-14 16:05:58 +02:00
|
|
|
'id' => 'projects-tokenizer',
|
2014-07-11 02:28:29 +02:00
|
|
|
'src' => $projects_source->getDatasourceURI(),
|
|
|
|
'placeholder' => $projects_source->getPlaceholderText(),
|
2012-04-14 16:05:58 +02:00
|
|
|
),
|
2013-09-25 20:16:43 +02:00
|
|
|
ManiphestTransaction::TYPE_OWNER => array(
|
2012-04-14 16:05:58 +02:00
|
|
|
'id' => 'assign-tokenizer',
|
2014-07-18 00:44:18 +02:00
|
|
|
'src' => $users_source->getDatasourceURI(),
|
2012-04-14 16:05:58 +02:00
|
|
|
'value' => $default_claim,
|
|
|
|
'limit' => 1,
|
2014-07-18 00:44:18 +02:00
|
|
|
'placeholder' => $users_source->getPlaceholderText(),
|
2012-04-14 16:05:58 +02:00
|
|
|
),
|
2014-12-11 01:27:30 +01:00
|
|
|
PhabricatorTransactions::TYPE_SUBSCRIBERS => array(
|
2012-04-14 16:05:58 +02:00
|
|
|
'id' => 'cc-tokenizer',
|
2014-07-18 00:44:29 +02:00
|
|
|
'src' => $mailable_source->getDatasourceURI(),
|
|
|
|
'placeholder' => $mailable_source->getPlaceholderText(),
|
2012-04-14 16:05:58 +02:00
|
|
|
),
|
|
|
|
);
|
|
|
|
|
2013-09-25 22:44:52 +02:00
|
|
|
// TODO: Initializing these behaviors for logged out users fatals things.
|
2015-08-02 02:06:57 +02:00
|
|
|
if ($viewer->isLoggedIn()) {
|
2013-09-25 22:44:52 +02:00
|
|
|
Javelin::initBehavior('maniphest-transaction-controls', array(
|
|
|
|
'select' => 'transaction-action',
|
|
|
|
'controlMap' => $control_map,
|
|
|
|
'tokenizers' => $tokenizer_map,
|
|
|
|
));
|
|
|
|
|
|
|
|
Javelin::initBehavior('maniphest-transaction-preview', array(
|
|
|
|
'uri' => '/maniphest/transaction/preview/'.$task->getID().'/',
|
|
|
|
'preview' => 'transaction-preview',
|
|
|
|
'comments' => 'transaction-comments',
|
|
|
|
'action' => 'transaction-action',
|
|
|
|
'map' => $control_map,
|
|
|
|
'tokenizers' => $tokenizer_map,
|
|
|
|
));
|
|
|
|
}
|
2011-05-10 17:29:28 +02:00
|
|
|
|
2014-04-19 02:51:46 +02:00
|
|
|
$is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
|
2013-11-22 01:09:04 +01:00
|
|
|
$comment_header = $is_serious
|
|
|
|
? pht('Add Comment')
|
|
|
|
: pht('Weigh In');
|
2011-02-08 19:53:59 +01:00
|
|
|
|
2013-11-11 18:23:23 +01:00
|
|
|
$preview_panel = phutil_tag_div(
|
|
|
|
'aphront-panel-preview',
|
|
|
|
phutil_tag(
|
|
|
|
'div',
|
|
|
|
array('id' => 'transaction-preview'),
|
|
|
|
phutil_tag_div(
|
|
|
|
'aphront-panel-preview-loading-text',
|
|
|
|
pht('Loading preview...'))));
|
2011-05-10 17:29:28 +02:00
|
|
|
|
2012-12-11 23:03:16 +01:00
|
|
|
$object_name = 'T'.$task->getID();
|
2013-04-09 21:42:03 +02:00
|
|
|
$actions = $this->buildActionView($task);
|
2012-12-11 23:03:16 +01:00
|
|
|
|
2013-12-19 02:47:34 +01:00
|
|
|
$crumbs = $this->buildApplicationCrumbs()
|
2015-01-12 16:24:35 +01:00
|
|
|
->addTextCrumb($object_name, '/'.$object_name);
|
2012-12-11 23:03:16 +01:00
|
|
|
|
|
|
|
$header = $this->buildHeaderView($task);
|
2013-10-11 16:53:56 +02:00
|
|
|
$properties = $this->buildPropertyView(
|
2015-03-30 03:56:28 +02:00
|
|
|
$task, $field_list, $edges, $actions, $handles);
|
2013-10-11 16:53:56 +02:00
|
|
|
$description = $this->buildDescriptionView($task, $engine);
|
2012-12-11 23:03:16 +01:00
|
|
|
|
2015-08-02 02:06:57 +02:00
|
|
|
if (!$viewer->isLoggedIn()) {
|
2013-09-25 22:44:52 +02:00
|
|
|
// TODO: Eventually, everything should run through this. For now, we're
|
|
|
|
// only using it to get a consistent "Login to Comment" button.
|
2013-12-05 17:44:43 +01:00
|
|
|
$comment_box = id(new PhabricatorApplicationTransactionCommentView())
|
2015-08-02 02:06:57 +02:00
|
|
|
->setUser($viewer)
|
2013-09-25 22:44:52 +02:00
|
|
|
->setRequestURI($request->getRequestURI());
|
|
|
|
$preview_panel = null;
|
2013-12-05 17:44:43 +01:00
|
|
|
} else {
|
|
|
|
$comment_box = id(new PHUIObjectBoxView())
|
|
|
|
->setFlush(true)
|
|
|
|
->setHeaderText($comment_header)
|
[Redesign] Add Table, Collapse support to ObjectBox
Summary: Converts most all tables to be directly set via `setTable` to an ObjectBox. I think this path is more flexible design wise, as we can change the box based on children, and not just CSS. We also already do this with PropertyList, Forms, ObjectList, and Header. `setCollapsed` is added to ObjectBox to all children objects to bleed to the edges (like diffs).
Test Plan: I did a grep of `appendChild($table)` as well as searches for `PHUIObjectBoxView`, also with manual opening of hundreds of files. I'm sure I missed 5-8 places. If you just appendChild($table) nothing breaks, it just looks a little funny.
Reviewers: epriestley, btrahan
Subscribers: Korvin, epriestley
Differential Revision: https://secure.phabricator.com/D12955
2015-05-20 21:43:34 +02:00
|
|
|
->setForm($comment_form);
|
2014-05-05 19:55:58 +02:00
|
|
|
$timeline->setQuoteTargetID('transaction-comments');
|
|
|
|
$timeline->setQuoteRef($object_name);
|
2013-09-25 22:44:52 +02:00
|
|
|
}
|
|
|
|
|
2013-09-29 00:55:38 +02:00
|
|
|
$object_box = id(new PHUIObjectBoxView())
|
|
|
|
->setHeader($header)
|
2013-10-11 16:53:56 +02:00
|
|
|
->addPropertyList($properties);
|
|
|
|
|
|
|
|
if ($description) {
|
|
|
|
$object_box->addPropertyList($description);
|
|
|
|
}
|
2013-09-29 00:55:38 +02:00
|
|
|
|
2012-12-11 23:03:16 +01:00
|
|
|
return $this->buildApplicationPage(
|
2011-02-08 19:53:59 +01:00
|
|
|
array(
|
2012-12-11 23:03:16 +01:00
|
|
|
$crumbs,
|
2015-05-08 18:38:46 +02:00
|
|
|
$info_view,
|
2013-09-29 00:55:38 +02:00
|
|
|
$object_box,
|
2013-09-23 23:29:40 +02:00
|
|
|
$timeline,
|
2013-09-29 00:55:38 +02:00
|
|
|
$comment_box,
|
2011-05-10 17:29:28 +02:00
|
|
|
$preview_panel,
|
2011-02-08 19:53:59 +01:00
|
|
|
),
|
|
|
|
array(
|
2011-02-10 01:38:31 +01:00
|
|
|
'title' => 'T'.$task->getID().' '.$task->getTitle(),
|
2012-06-14 02:28:21 +02:00
|
|
|
'pageObjects' => array($task->getPHID()),
|
2011-02-08 19:53:59 +01:00
|
|
|
));
|
|
|
|
}
|
2011-02-19 07:15:28 +01:00
|
|
|
|
2012-12-11 23:03:16 +01:00
|
|
|
private function buildHeaderView(ManiphestTask $task) {
|
2013-09-17 18:12:37 +02:00
|
|
|
$view = id(new PHUIHeaderView())
|
2013-09-25 22:44:45 +02:00
|
|
|
->setHeader($task->getTitle())
|
|
|
|
->setUser($this->getRequest()->getUser())
|
|
|
|
->setPolicyObject($task);
|
2012-12-11 23:03:16 +01:00
|
|
|
|
2013-09-24 17:42:04 +02:00
|
|
|
$status = $task->getStatus();
|
|
|
|
$status_name = ManiphestTaskStatus::renderFullDescription($status);
|
|
|
|
|
|
|
|
$view->addProperty(PHUIHeaderView::PROPERTY_STATUS, $status_name);
|
2012-12-11 23:03:16 +01:00
|
|
|
|
|
|
|
return $view;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private function buildActionView(ManiphestTask $task) {
|
|
|
|
$viewer = $this->getRequest()->getUser();
|
2013-05-04 00:47:39 +02:00
|
|
|
$viewer_phid = $viewer->getPHID();
|
2012-12-11 23:03:16 +01:00
|
|
|
|
|
|
|
$id = $task->getID();
|
|
|
|
$phid = $task->getPHID();
|
|
|
|
|
2013-09-25 22:44:52 +02:00
|
|
|
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
|
|
|
$viewer,
|
|
|
|
$task,
|
|
|
|
PhabricatorPolicyCapability::CAN_EDIT);
|
|
|
|
|
2013-07-12 20:39:47 +02:00
|
|
|
$view = id(new PhabricatorActionListView())
|
|
|
|
->setUser($viewer)
|
|
|
|
->setObject($task)
|
2013-09-25 22:44:52 +02:00
|
|
|
->setObjectURI($this->getRequest()->getRequestURI());
|
|
|
|
|
|
|
|
$view->addAction(
|
2012-12-11 23:03:16 +01:00
|
|
|
id(new PhabricatorActionView())
|
|
|
|
->setName(pht('Edit Task'))
|
2014-05-12 19:08:32 +02:00
|
|
|
->setIcon('fa-pencil')
|
2013-09-25 22:44:52 +02:00
|
|
|
->setHref($this->getApplicationURI("/task/edit/{$id}/"))
|
|
|
|
->setDisabled(!$can_edit)
|
|
|
|
->setWorkflow(!$can_edit));
|
2012-12-11 23:03:16 +01:00
|
|
|
|
|
|
|
$view->addAction(
|
|
|
|
id(new PhabricatorActionView())
|
2013-07-17 19:01:13 +02:00
|
|
|
->setName(pht('Merge Duplicates In'))
|
2012-12-11 23:03:16 +01:00
|
|
|
->setHref("/search/attach/{$phid}/TASK/merge/")
|
|
|
|
->setWorkflow(true)
|
2014-05-12 19:08:32 +02:00
|
|
|
->setIcon('fa-compress')
|
2013-09-25 22:44:52 +02:00
|
|
|
->setDisabled(!$can_edit)
|
2013-10-16 19:35:52 +02:00
|
|
|
->setWorkflow(true));
|
2012-12-11 23:03:16 +01:00
|
|
|
|
|
|
|
$view->addAction(
|
|
|
|
id(new PhabricatorActionView())
|
|
|
|
->setName(pht('Create Subtask'))
|
|
|
|
->setHref($this->getApplicationURI("/task/create/?parent={$id}"))
|
2014-05-12 19:08:32 +02:00
|
|
|
->setIcon('fa-level-down'));
|
2012-12-11 23:03:16 +01:00
|
|
|
|
|
|
|
$view->addAction(
|
|
|
|
id(new PhabricatorActionView())
|
"Blocks" instead of "Dependent Tasks"
Summary: Fixes T5021, UI labels for the fields, "Edit Dependencies" in the action list, transaction strings ("added dependent tasks", etc), UI strings in the dependencies dialog (title/submit/etc)
Test Plan: Open task, edit blocks, dialog should have new term, task history should show "blocks" instead of "dependencies"
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: epriestley, Korvin
Maniphest Tasks: T5021
Differential Revision: https://secure.phabricator.com/D9270
2014-05-23 22:50:20 +02:00
|
|
|
->setName(pht('Edit Blocking Tasks'))
|
|
|
|
->setHref("/search/attach/{$phid}/TASK/blocks/")
|
2012-12-11 23:03:16 +01:00
|
|
|
->setWorkflow(true)
|
2014-05-12 19:08:32 +02:00
|
|
|
->setIcon('fa-link')
|
2013-09-25 22:44:52 +02:00
|
|
|
->setDisabled(!$can_edit)
|
2013-10-01 21:01:55 +02:00
|
|
|
->setWorkflow(true));
|
2012-12-11 23:03:16 +01:00
|
|
|
|
|
|
|
return $view;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function buildPropertyView(
|
|
|
|
ManiphestTask $task,
|
2013-09-17 01:02:27 +02:00
|
|
|
PhabricatorCustomFieldList $field_list,
|
2012-12-11 23:03:16 +01:00
|
|
|
array $edges,
|
2015-03-30 03:56:28 +02:00
|
|
|
PhabricatorActionListView $actions,
|
|
|
|
$handles) {
|
2012-12-11 23:03:16 +01:00
|
|
|
|
|
|
|
$viewer = $this->getRequest()->getUser();
|
|
|
|
|
2013-10-11 16:53:56 +02:00
|
|
|
$view = id(new PHUIPropertyListView())
|
2013-02-15 16:47:14 +01:00
|
|
|
->setUser($viewer)
|
2013-10-11 16:53:56 +02:00
|
|
|
->setObject($task)
|
|
|
|
->setActionList($actions);
|
2012-12-11 23:03:16 +01:00
|
|
|
|
|
|
|
$view->addProperty(
|
|
|
|
pht('Assigned To'),
|
|
|
|
$task->getOwnerPHID()
|
2015-03-30 15:18:54 +02:00
|
|
|
? $handles->renderHandle($task->getOwnerPHID())
|
2015-03-30 03:56:28 +02:00
|
|
|
: phutil_tag('em', array(), pht('None')));
|
2012-12-11 23:03:16 +01:00
|
|
|
|
|
|
|
$view->addProperty(
|
|
|
|
pht('Priority'),
|
2013-01-29 20:01:47 +01:00
|
|
|
ManiphestTaskPriority::getTaskPriorityName($task->getPriority()));
|
2012-12-11 23:03:16 +01:00
|
|
|
|
|
|
|
$view->addProperty(
|
|
|
|
pht('Author'),
|
2015-03-30 15:18:54 +02:00
|
|
|
$handles->renderHandle($task->getAuthorPHID()));
|
2012-12-11 23:03:16 +01:00
|
|
|
|
|
|
|
$source = $task->getOriginalEmailSource();
|
|
|
|
if ($source) {
|
|
|
|
$subject = '[T'.$task->getID().'] '.$task->getTitle();
|
|
|
|
$view->addProperty(
|
|
|
|
pht('From Email'),
|
2013-01-18 03:43:35 +01:00
|
|
|
phutil_tag(
|
2012-12-11 23:03:16 +01:00
|
|
|
'a',
|
|
|
|
array(
|
2014-10-07 15:01:04 +02:00
|
|
|
'href' => 'mailto:'.$source.'?subject='.$subject,
|
2013-07-20 00:59:29 +02:00
|
|
|
),
|
2013-01-18 03:43:35 +01:00
|
|
|
$source));
|
2012-12-11 23:03:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
$edge_types = array(
|
2014-12-28 15:10:49 +01:00
|
|
|
ManiphestTaskDependedOnByTaskEdgeType::EDGECONST
|
2014-07-18 00:41:08 +02:00
|
|
|
=> pht('Blocks'),
|
2014-12-28 15:10:49 +01:00
|
|
|
ManiphestTaskDependsOnTaskEdgeType::EDGECONST
|
2014-07-18 00:41:08 +02:00
|
|
|
=> pht('Blocked By'),
|
|
|
|
ManiphestTaskHasRevisionEdgeType::EDGECONST
|
|
|
|
=> pht('Differential Revisions'),
|
2015-01-02 00:11:41 +01:00
|
|
|
ManiphestTaskHasMockEdgeType::EDGECONST
|
2014-07-18 00:41:08 +02:00
|
|
|
=> pht('Pholio Mocks'),
|
2012-12-11 23:03:16 +01:00
|
|
|
);
|
|
|
|
|
2013-04-06 20:40:43 +02:00
|
|
|
$revisions_commits = array();
|
|
|
|
|
|
|
|
$commit_phids = array_keys(
|
2014-07-18 00:42:06 +02:00
|
|
|
$edges[ManiphestTaskHasCommitEdgeType::EDGECONST]);
|
2013-04-06 20:40:43 +02:00
|
|
|
if ($commit_phids) {
|
2015-01-01 04:43:26 +01:00
|
|
|
$commit_drev = DiffusionCommitHasRevisionEdgeType::EDGECONST;
|
2013-04-13 07:48:16 +02:00
|
|
|
$drev_edges = id(new PhabricatorEdgeQuery())
|
|
|
|
->withSourcePHIDs($commit_phids)
|
|
|
|
->withEdgeTypes(array($commit_drev))
|
|
|
|
->execute();
|
2013-04-06 20:40:43 +02:00
|
|
|
|
2013-04-13 07:48:16 +02:00
|
|
|
foreach ($commit_phids as $phid) {
|
2015-03-30 15:18:54 +02:00
|
|
|
$revisions_commits[$phid] = $handles->renderHandle($phid);
|
2013-04-13 07:48:16 +02:00
|
|
|
$revision_phid = key($drev_edges[$phid][$commit_drev]);
|
2015-03-30 03:56:28 +02:00
|
|
|
$revision_handle = $handles->getHandleIfExists($revision_phid);
|
2013-04-06 20:40:43 +02:00
|
|
|
if ($revision_handle) {
|
2014-07-18 00:41:08 +02:00
|
|
|
$task_drev = ManiphestTaskHasRevisionEdgeType::EDGECONST;
|
2013-04-13 07:48:16 +02:00
|
|
|
unset($edges[$task_drev][$revision_phid]);
|
2013-04-06 20:40:43 +02:00
|
|
|
$revisions_commits[$phid] = hsprintf(
|
|
|
|
'%s / %s',
|
|
|
|
$revision_handle->renderLink($revision_handle->getName()),
|
|
|
|
$revisions_commits[$phid]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-11 23:03:16 +01:00
|
|
|
foreach ($edge_types as $edge_type => $edge_name) {
|
|
|
|
if ($edges[$edge_type]) {
|
2015-03-30 15:18:54 +02:00
|
|
|
$edge_handles = $viewer->loadHandles(array_keys($edges[$edge_type]));
|
2012-12-11 23:03:16 +01:00
|
|
|
$view->addProperty(
|
|
|
|
$edge_name,
|
2015-03-30 15:18:54 +02:00
|
|
|
$edge_handles->renderList());
|
2012-12-11 23:03:16 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-06 20:40:43 +02:00
|
|
|
if ($revisions_commits) {
|
|
|
|
$view->addProperty(
|
|
|
|
pht('Commits'),
|
|
|
|
phutil_implode_html(phutil_tag('br'), $revisions_commits));
|
|
|
|
}
|
|
|
|
|
2012-12-11 23:03:16 +01:00
|
|
|
$attached = $task->getAttached();
|
2013-08-05 19:27:50 +02:00
|
|
|
if (!is_array($attached)) {
|
|
|
|
$attached = array();
|
|
|
|
}
|
|
|
|
|
2014-07-24 00:05:46 +02:00
|
|
|
$file_infos = idx($attached, PhabricatorFileFilePHIDType::TYPECONST);
|
2012-12-11 23:03:16 +01:00
|
|
|
if ($file_infos) {
|
|
|
|
$file_phids = array_keys($file_infos);
|
|
|
|
|
2013-09-30 18:38:13 +02:00
|
|
|
// TODO: These should probably be handles or something; clean this up
|
|
|
|
// as we sort out file attachments.
|
|
|
|
$files = id(new PhabricatorFileQuery())
|
|
|
|
->setViewer($viewer)
|
|
|
|
->withPHIDs($file_phids)
|
|
|
|
->execute();
|
2012-12-11 23:03:16 +01:00
|
|
|
|
|
|
|
$file_view = new PhabricatorFileLinkListView();
|
|
|
|
$file_view->setFiles($files);
|
|
|
|
|
|
|
|
$view->addProperty(
|
|
|
|
pht('Files'),
|
|
|
|
$file_view->render());
|
|
|
|
}
|
|
|
|
|
2014-09-03 21:49:24 +02:00
|
|
|
$view->invokeWillRenderEvent();
|
|
|
|
|
2013-09-24 20:10:46 +02:00
|
|
|
$field_list->appendFieldsToPropertyList(
|
|
|
|
$task,
|
|
|
|
$viewer,
|
|
|
|
$view);
|
|
|
|
|
2013-10-11 16:53:56 +02:00
|
|
|
return $view;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function buildDescriptionView(
|
|
|
|
ManiphestTask $task,
|
|
|
|
PhabricatorMarkupEngine $engine) {
|
|
|
|
|
|
|
|
$section = null;
|
2012-12-11 23:03:16 +01:00
|
|
|
if (strlen($task->getDescription())) {
|
2013-10-11 16:53:56 +02:00
|
|
|
$section = new PHUIPropertyListView();
|
2013-11-04 20:07:51 +01:00
|
|
|
$section->addSectionHeader(
|
|
|
|
pht('Description'),
|
|
|
|
PHUIPropertyListView::ICON_SUMMARY);
|
2013-10-11 16:53:56 +02:00
|
|
|
$section->addTextContent(
|
2013-01-29 03:46:48 +01:00
|
|
|
phutil_tag(
|
2012-12-11 23:03:16 +01:00
|
|
|
'div',
|
|
|
|
array(
|
|
|
|
'class' => 'phabricator-remarkup',
|
|
|
|
),
|
|
|
|
$engine->getOutput($task, ManiphestTask::MARKUP_FIELD_DESCRIPTION)));
|
2012-07-19 05:41:42 +02:00
|
|
|
}
|
2012-12-11 23:03:16 +01:00
|
|
|
|
2013-10-11 16:53:56 +02:00
|
|
|
return $section;
|
2012-07-19 05:41:42 +02:00
|
|
|
}
|
|
|
|
|
2011-02-08 19:53:59 +01:00
|
|
|
}
|