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
|
|
|
|
|
|
|
private $id;
|
|
|
|
|
2013-09-25 22:44:52 +02:00
|
|
|
public function shouldAllowPublic() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2011-02-08 19:53:59 +01:00
|
|
|
public function willProcessRequest(array $data) {
|
|
|
|
$this->id = $data['id'];
|
|
|
|
}
|
|
|
|
|
|
|
|
public function processRequest() {
|
|
|
|
|
|
|
|
$request = $this->getRequest();
|
|
|
|
$user = $request->getUser();
|
|
|
|
|
|
|
|
$e_title = null;
|
|
|
|
|
|
|
|
$priority_map = ManiphestTaskPriority::getTaskPriorityMap();
|
|
|
|
|
2013-09-25 22:44:14 +02:00
|
|
|
$task = id(new ManiphestTaskQuery())
|
|
|
|
->setViewer($user)
|
|
|
|
->withIDs(array($this->id))
|
|
|
|
->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())
|
|
|
|
->setViewer($user)
|
|
|
|
->withIDs(array($workflow))
|
|
|
|
->executeOne();
|
2011-08-03 23:20:05 +02:00
|
|
|
}
|
|
|
|
|
2013-09-23 23:31:03 +02:00
|
|
|
$transactions = id(new ManiphestTransactionQuery())
|
|
|
|
->setViewer($user)
|
|
|
|
->withObjectPHIDs(array($task->getPHID()))
|
|
|
|
->needComments(true)
|
|
|
|
->execute();
|
2011-02-08 19:53:59 +01:00
|
|
|
|
2013-09-17 00:58:35 +02:00
|
|
|
$field_list = PhabricatorCustomField::getObjectFields(
|
|
|
|
$task,
|
|
|
|
PhabricatorCustomField::ROLE_VIEW);
|
|
|
|
|
|
|
|
foreach ($field_list->getFields() as $field) {
|
|
|
|
$field->setObject($task);
|
|
|
|
$field->setViewer($user);
|
|
|
|
}
|
|
|
|
|
2013-09-17 01:02:27 +02:00
|
|
|
$field_list->readFieldsFromStorage($task);
|
2013-09-17 00:58:35 +02:00
|
|
|
|
|
|
|
$aux_fields = $field_list->getFields();
|
2013-03-08 02:24:58 +01:00
|
|
|
|
2012-07-19 05:41:42 +02:00
|
|
|
$e_commit = PhabricatorEdgeConfig::TYPE_TASK_HAS_COMMIT;
|
|
|
|
$e_dep_on = PhabricatorEdgeConfig::TYPE_TASK_DEPENDS_ON_TASK;
|
|
|
|
$e_dep_by = PhabricatorEdgeConfig::TYPE_TASK_DEPENDED_ON_BY_TASK;
|
2012-07-20 17:59:39 +02:00
|
|
|
$e_rev = PhabricatorEdgeConfig::TYPE_TASK_HAS_RELATED_DREV;
|
2013-07-20 00:59:29 +02:00
|
|
|
$e_mock = PhabricatorEdgeConfig::TYPE_TASK_HAS_MOCK;
|
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
|
|
|
foreach ($task->getCCPHIDs() as $phid) {
|
|
|
|
$phids[$phid] = true;
|
|
|
|
}
|
2011-02-21 05:08:16 +01:00
|
|
|
foreach ($task->getProjectPHIDs() as $phid) {
|
|
|
|
$phids[$phid] = true;
|
|
|
|
}
|
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);
|
2013-03-08 02:24:58 +01:00
|
|
|
|
2012-12-11 23:03:16 +01:00
|
|
|
$this->loadHandles($phids);
|
2011-02-21 05:08:16 +01:00
|
|
|
|
2013-03-08 02:24:58 +01:00
|
|
|
$handles = $this->getLoadedHandles();
|
|
|
|
|
Tweak style on "Create Another Task" button
Summary:
Not totally sure I'm in love with this but I think it's somewhat non-terrible,
despite the lack of lens flare.
Also made "Cancel" take you back to the task if you got to "Create" from "Create
Another Task".
Test Plan:
- Style:
https://secure.phabricator.com/file/view/PHID-FILE-ad37d3c1f3b2c7a7a7d1/
- Hit "Cancel" from "Create Another", got sent back to task.
- Hit "Cancel" from normal create, got sent back to list.
- Tried to save an invalid task after making changes to CC/Projects, changes
were preserved.
Reviewed By: codeblock
Reviewers: hunterbridges, jungejason, tuomaspelkonen, aran, codeblock
CC: aran, epriestley, codeblock
Differential Revision: 736
2011-07-27 19:46:22 +02:00
|
|
|
$context_bar = null;
|
2011-08-03 23:20:05 +02:00
|
|
|
|
|
|
|
if ($parent_task) {
|
|
|
|
$context_bar = new AphrontContextBarView();
|
2013-02-13 23:50:15 +01:00
|
|
|
$context_bar->addButton(phutil_tag(
|
|
|
|
'a',
|
|
|
|
array(
|
|
|
|
'href' => '/maniphest/task/create/?parent='.$parent_task->getID(),
|
|
|
|
'class' => 'green button',
|
|
|
|
),
|
2013-03-13 07:30:03 +01:00
|
|
|
pht('Create Another Subtask')));
|
2013-02-13 23:50:15 +01:00
|
|
|
$context_bar->appendChild(hsprintf(
|
|
|
|
'Created a subtask of <strong>%s</strong>',
|
|
|
|
$this->getHandle($parent_task->getPHID())->renderLink()));
|
2011-08-03 23:20:05 +02:00
|
|
|
} else if ($workflow == 'create') {
|
Tweak style on "Create Another Task" button
Summary:
Not totally sure I'm in love with this but I think it's somewhat non-terrible,
despite the lack of lens flare.
Also made "Cancel" take you back to the task if you got to "Create" from "Create
Another Task".
Test Plan:
- Style:
https://secure.phabricator.com/file/view/PHID-FILE-ad37d3c1f3b2c7a7a7d1/
- Hit "Cancel" from "Create Another", got sent back to task.
- Hit "Cancel" from normal create, got sent back to list.
- Tried to save an invalid task after making changes to CC/Projects, changes
were preserved.
Reviewed By: codeblock
Reviewers: hunterbridges, jungejason, tuomaspelkonen, aran, codeblock
CC: aran, epriestley, codeblock
Differential Revision: 736
2011-07-27 19:46:22 +02:00
|
|
|
$context_bar = new AphrontContextBarView();
|
2013-02-13 23:50:15 +01:00
|
|
|
$context_bar->addButton(phutil_tag('label', array(), 'Create Another'));
|
|
|
|
$context_bar->addButton(phutil_tag(
|
|
|
|
'a',
|
|
|
|
array(
|
|
|
|
'href' => '/maniphest/task/create/?template='.$task->getID(),
|
|
|
|
'class' => 'green button',
|
|
|
|
),
|
2013-03-13 07:30:03 +01:00
|
|
|
pht('Similar Task')));
|
2013-02-13 23:50:15 +01:00
|
|
|
$context_bar->addButton(phutil_tag(
|
|
|
|
'a',
|
|
|
|
array(
|
|
|
|
'href' => '/maniphest/task/create/',
|
|
|
|
'class' => 'green button',
|
|
|
|
),
|
2013-03-13 07:30:03 +01:00
|
|
|
pht('Empty Task')));
|
|
|
|
$context_bar->appendChild(pht('New task created.'));
|
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();
|
2012-09-05 20:40:48 +02:00
|
|
|
$engine->setViewer($user);
|
2012-07-11 20:40:10 +02:00
|
|
|
$engine->addObject($task, ManiphestTask::MARKUP_FIELD_DESCRIPTION);
|
2013-09-23 23:31:03 +02:00
|
|
|
foreach ($transactions as $modern_xaction) {
|
2013-09-23 23:29:40 +02:00
|
|
|
if ($modern_xaction->getComment()) {
|
|
|
|
$engine->addObject(
|
|
|
|
$modern_xaction->getComment(),
|
|
|
|
PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT);
|
2012-07-11 20:40:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-08 02:24:33 +01:00
|
|
|
$engine->process();
|
|
|
|
|
2011-02-08 19:53:59 +01:00
|
|
|
$resolution_types = ManiphestTaskStatus::getTaskStatusMap();
|
|
|
|
|
2013-09-25 20:16:43 +02:00
|
|
|
$transaction_types = array(
|
|
|
|
PhabricatorTransactions::TYPE_COMMENT => pht('Comment'),
|
|
|
|
ManiphestTransaction::TYPE_STATUS => pht('Close Task'),
|
|
|
|
ManiphestTransaction::TYPE_OWNER => pht('Reassign / Claim'),
|
|
|
|
ManiphestTransaction::TYPE_CCS => pht('Add CCs'),
|
|
|
|
ManiphestTransaction::TYPE_PRIORITY => pht('Change Priority'),
|
|
|
|
ManiphestTransaction::TYPE_ATTACH => pht('Upload File'),
|
|
|
|
ManiphestTransaction::TYPE_PROJECTS => pht('Associate Projects'),
|
|
|
|
);
|
|
|
|
|
2011-02-08 19:53:59 +01:00
|
|
|
if ($task->getStatus() == ManiphestTaskStatus::STATUS_OPEN) {
|
|
|
|
$resolution_types = array_select_keys(
|
|
|
|
$resolution_types,
|
|
|
|
array(
|
|
|
|
ManiphestTaskStatus::STATUS_CLOSED_RESOLVED,
|
|
|
|
ManiphestTaskStatus::STATUS_CLOSED_WONTFIX,
|
|
|
|
ManiphestTaskStatus::STATUS_CLOSED_INVALID,
|
|
|
|
ManiphestTaskStatus::STATUS_CLOSED_SPITE,
|
|
|
|
));
|
|
|
|
} else {
|
|
|
|
$resolution_types = array(
|
|
|
|
ManiphestTaskStatus::STATUS_OPEN => 'Reopened',
|
|
|
|
);
|
2013-09-25 20:16:43 +02:00
|
|
|
$transaction_types[ManiphestTransaction::TYPE_STATUS] =
|
2011-02-08 19:53:59 +01:00
|
|
|
'Reopen Task';
|
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(
|
|
|
|
$user->getPHID() => $user->getUsername().' ('.$user->getRealName().')',
|
|
|
|
);
|
|
|
|
|
2011-05-11 01:18:47 +02:00
|
|
|
$draft = id(new PhabricatorDraft())->loadOneWhere(
|
|
|
|
'authorPHID = %s AND draftKey = %s',
|
|
|
|
$user->getPHID(),
|
|
|
|
$task->getPHID());
|
|
|
|
if ($draft) {
|
|
|
|
$draft_text = $draft->getDraft();
|
|
|
|
} else {
|
|
|
|
$draft_text = null;
|
|
|
|
}
|
|
|
|
|
Provide a configuration flag to disable silliness in the UI
Summary: See comments. A few installs have remarked that their organizations
would prefer buttons labled "Submit" to buttons labeled "Clowncopterize".
Test Plan:
- In "serious" mode, verified Differential and Maniphest have serious strings,
tasks can not be closed out of spite, and reset/welcome emails are extremely
serious.
- In unserious mode, verified Differential and Maniphest have normal strings,
tasks can be closed out of spite, and reset/welcome emails are silly.
- This does not disable the "fax these changes" message in Arcanist (no
reasonable way for it to read the config value) or the rainbow syntax
highlighter (already removable though configuration).
Reviewers: moskov, jungejason, nh, tuomaspelkonen, aran
Reviewed By: moskov
CC: aran, moskov
Differential Revision: 1081
2011-11-04 23:16:34 +01:00
|
|
|
$is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
|
|
|
|
|
|
|
|
if ($is_serious) {
|
|
|
|
// Prevent tasks from being closed "out of spite" in serious business
|
|
|
|
// installs.
|
|
|
|
unset($resolution_types[ManiphestTaskStatus::STATUS_CLOSED_SPITE]);
|
|
|
|
}
|
|
|
|
|
2011-02-08 19:53:59 +01:00
|
|
|
$comment_form = new AphrontFormView();
|
|
|
|
$comment_form
|
|
|
|
->setUser($user)
|
|
|
|
->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())
|
2013-03-13 07:30:03 +01:00
|
|
|
->setLabel(pht('Resolution'))
|
2011-02-08 19:53:59 +01:00
|
|
|
->setName('resolution')
|
|
|
|
->setControlID('resolution')
|
|
|
|
->setControlStyle('display: none')
|
|
|
|
->setOptions($resolution_types))
|
|
|
|
->appendChild(
|
|
|
|
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')
|
|
|
|
->setDisableBehavior(true))
|
|
|
|
->appendChild(
|
|
|
|
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')
|
|
|
|
->setDisableBehavior(true))
|
|
|
|
->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()))
|
2011-02-21 05:08:16 +01:00
|
|
|
->appendChild(
|
|
|
|
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')
|
|
|
|
->setDisableBehavior(true))
|
|
|
|
->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())
|
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')
|
|
|
|
->setUser($user))
|
2011-02-08 19:53:59 +01:00
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormSubmitControl())
|
2013-03-13 07:30:03 +01:00
|
|
|
->setValue($is_serious ? pht('Submit') : pht('Avast!')));
|
2011-02-08 19:53:59 +01:00
|
|
|
|
2011-05-11 13:17:48 +02:00
|
|
|
$control_map = array(
|
2013-09-25 20:16:43 +02:00
|
|
|
ManiphestTransaction::TYPE_STATUS => 'resolution',
|
|
|
|
ManiphestTransaction::TYPE_OWNER => 'assign_to',
|
|
|
|
ManiphestTransaction::TYPE_CCS => 'ccs',
|
|
|
|
ManiphestTransaction::TYPE_PRIORITY => 'priority',
|
|
|
|
ManiphestTransaction::TYPE_PROJECTS => 'projects',
|
|
|
|
ManiphestTransaction::TYPE_ATTACH => 'file',
|
2011-05-11 13:17:48 +02:00
|
|
|
);
|
|
|
|
|
2012-04-14 16:05:58 +02:00
|
|
|
$tokenizer_map = array(
|
2013-09-25 20:16:43 +02:00
|
|
|
ManiphestTransaction::TYPE_PROJECTS => array(
|
2012-04-14 16:05:58 +02:00
|
|
|
'id' => 'projects-tokenizer',
|
|
|
|
'src' => '/typeahead/common/projects/',
|
|
|
|
'ondemand' => PhabricatorEnv::getEnvConfig('tokenizer.ondemand'),
|
2013-03-13 07:30:03 +01:00
|
|
|
'placeholder' => pht('Type a project name...'),
|
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',
|
|
|
|
'src' => '/typeahead/common/users/',
|
|
|
|
'value' => $default_claim,
|
|
|
|
'limit' => 1,
|
|
|
|
'ondemand' => PhabricatorEnv::getEnvConfig('tokenizer.ondemand'),
|
2013-03-13 07:30:03 +01:00
|
|
|
'placeholder' => pht('Type a user name...'),
|
2012-04-14 16:05:58 +02:00
|
|
|
),
|
2013-09-25 20:16:43 +02:00
|
|
|
ManiphestTransaction::TYPE_CCS => array(
|
2012-04-14 16:05:58 +02:00
|
|
|
'id' => 'cc-tokenizer',
|
|
|
|
'src' => '/typeahead/common/mailable/',
|
|
|
|
'ondemand' => PhabricatorEnv::getEnvConfig('tokenizer.ondemand'),
|
2013-03-13 07:30:03 +01:00
|
|
|
'placeholder' => pht('Type a user or mailing list...'),
|
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.
|
|
|
|
if ($user->isLoggedIn()) {
|
|
|
|
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
|
|
|
|
2013-09-17 18:12:37 +02:00
|
|
|
$comment_header = id(new PHUIHeaderView())
|
2013-01-25 01:29:47 +01:00
|
|
|
->setHeader($is_serious ? pht('Add Comment') : pht('Weigh In'));
|
2011-02-08 19:53:59 +01:00
|
|
|
|
2013-02-13 23:50:15 +01:00
|
|
|
$preview_panel = hsprintf(
|
Tweak Maniphest CSS, fix remarkup in description change views
Summary:
Various CSS tweaks and fixes:
- Add remarkup styling to description change views, missed this before.
- Fix CSS so that transactions with only one item (e.g., changed priority)
don't have weird floater underneath them.
- Add more space between transaction items.
- Make default background color lighter and less heavy.
- Use beigey color for comment form in Maniphest.
- Share more CSS between Maniphest and Differential (previews, feedback).
- Move "Leap Into Action" call to Differential, replace Maniphest with
thematically-consistent "Weigh In" (obviously, Maniphest has a nautical theme).
Test Plan:
Browsed Maniphest and Differential in a couple browsers, styling all seems
correct.
Reviewed By: tomo
Reviewers: tomo, aran, jungejason, tuomaspelkonen
CC: anjali, aran, tomo
Differential Revision: 328
2011-05-22 17:49:07 +02:00
|
|
|
'<div class="aphront-panel-preview">
|
2011-05-10 17:29:28 +02:00
|
|
|
<div id="transaction-preview">
|
2013-02-13 23:50:15 +01:00
|
|
|
<div class="aphront-panel-preview-loading-text">%s</div>
|
2011-05-10 17:29:28 +02:00
|
|
|
</div>
|
2013-02-13 23:50:15 +01:00
|
|
|
</div>',
|
|
|
|
pht('Loading preview...'));
|
2011-05-10 17:29:28 +02:00
|
|
|
|
2013-09-23 23:29:40 +02:00
|
|
|
$timeline = id(new PhabricatorApplicationTransactionView())
|
|
|
|
->setUser($user)
|
|
|
|
->setObjectPHID($task->getPHID())
|
2013-09-23 23:31:03 +02:00
|
|
|
->setTransactions($transactions)
|
2013-09-23 23:29:40 +02:00
|
|
|
->setMarkupEngine($engine);
|
2011-02-08 19:53:59 +01: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
|
|
|
|
|
|
|
$crumbs = $this->buildApplicationCrumbs();
|
|
|
|
$crumbs->addCrumb(
|
|
|
|
id(new PhabricatorCrumbView())
|
|
|
|
->setName($object_name)
|
2013-03-26 21:15:15 +01:00
|
|
|
->setHref('/'.$object_name))
|
2013-09-13 20:29:08 +02:00
|
|
|
->setActionList($actions);
|
2012-12-11 23:03:16 +01:00
|
|
|
|
|
|
|
$header = $this->buildHeaderView($task);
|
2013-10-11 16:53:56 +02:00
|
|
|
$properties = $this->buildPropertyView(
|
|
|
|
$task, $field_list, $edges, $actions);
|
|
|
|
$description = $this->buildDescriptionView($task, $engine);
|
2012-12-11 23:03:16 +01:00
|
|
|
|
2013-09-25 22:44:52 +02:00
|
|
|
if (!$user->isLoggedIn()) {
|
|
|
|
// TODO: Eventually, everything should run through this. For now, we're
|
|
|
|
// only using it to get a consistent "Login to Comment" button.
|
|
|
|
$comment_form = id(new PhabricatorApplicationTransactionCommentView())
|
|
|
|
->setUser($user)
|
|
|
|
->setRequestURI($request->getRequestURI());
|
|
|
|
$preview_panel = null;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
|
|
|
$comment_box = id(new PHUIObjectBoxView())
|
|
|
|
->setFlush(true)
|
|
|
|
->setHeader($comment_header)
|
Provide more structure to PHUIObjectBoxView
Summary:
Three changes here.
- Add `setActionList()`, and use that to set the action list.
- Add `setPropertyList()`, and use that to set the property list.
These will let us add some apropriate CSS so we can fix the border issue, and get rid of a bunch of goofy `.x + .y` selectors.
- Replace `addContent()` with `appendChild()`.
This is just a consistency thing; `AphrontView` already provides `appendChild()`, and `addContent()` did the same thing.
Test Plan:
- Viewed "All Config".
- Viewed a countdown.
- Viewed a revision (add comment, change list, table of contents, comment, local commits, open revisions affecting these files, update history).
- Viewed Diffusion (browse, change, history, repository, lint).
- Viewed Drydock (resource, lease).
- Viewed Files.
- Viewed Herald.
- Viewed Legalpad.
- Viewed macro (edit, edit audio, view).
- Viewed Maniphest.
- Viewed Applications.
- Viewed Paste.
- Viewed People.
- Viewed Phulux.
- Viewed Pholio.
- Viewed Phame (blog, post).
- Viewed Phortune (account, product).
- Viewed Ponder (questions, answers, comments).
- Viewed Releeph.
- Viewed Projects.
- Viewed Slowvote.
NOTE: Images in Files aren't on a black background anymore -- I assume that's on purpose?
NOTE: Some jankiness in Phortune, I'll clean that up when I get back to it. Not related to this diff.
Reviewers: chad
Reviewed By: chad
CC: aran
Differential Revision: https://secure.phabricator.com/D7174
2013-09-30 18:36:04 +02:00
|
|
|
->appendChild($comment_form);
|
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,
|
Tweak style on "Create Another Task" button
Summary:
Not totally sure I'm in love with this but I think it's somewhat non-terrible,
despite the lack of lens flare.
Also made "Cancel" take you back to the task if you got to "Create" from "Create
Another Task".
Test Plan:
- Style:
https://secure.phabricator.com/file/view/PHID-FILE-ad37d3c1f3b2c7a7a7d1/
- Hit "Cancel" from "Create Another", got sent back to task.
- Hit "Cancel" from normal create, got sent back to list.
- Tried to save an invalid task after making changes to CC/Projects, changes
were preserved.
Reviewed By: codeblock
Reviewers: hunterbridges, jungejason, tuomaspelkonen, aran, codeblock
CC: aran, epriestley, codeblock
Differential Revision: 736
2011-07-27 19:46:22 +02:00
|
|
|
$context_bar,
|
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()),
|
2013-01-25 01:29:47 +01:00
|
|
|
'device' => true,
|
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();
|
|
|
|
$viewer_is_cc = in_array($viewer_phid, $task->getCCPHIDs());
|
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'))
|
|
|
|
->setIcon('edit')
|
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
|
|
|
|
2013-05-04 00:47:39 +02:00
|
|
|
if ($task->getOwnerPHID() === $viewer_phid) {
|
|
|
|
$view->addAction(
|
|
|
|
id(new PhabricatorActionView())
|
|
|
|
->setName(pht('Automatically Subscribed'))
|
|
|
|
->setDisabled(true)
|
2013-06-07 00:06:08 +02:00
|
|
|
->setIcon('enable'));
|
2013-05-04 00:47:39 +02:00
|
|
|
} else {
|
|
|
|
$action = $viewer_is_cc ? 'rem' : 'add';
|
2013-06-07 00:06:08 +02:00
|
|
|
$name = $viewer_is_cc ? pht('Unsubscribe') : pht('Subscribe');
|
|
|
|
$icon = $viewer_is_cc ? 'disable' : 'check';
|
2013-05-04 00:47:39 +02:00
|
|
|
|
|
|
|
$view->addAction(
|
|
|
|
id(new PhabricatorActionView())
|
2013-06-07 00:06:08 +02:00
|
|
|
->setName($name)
|
2013-05-04 00:47:39 +02:00
|
|
|
->setHref("/maniphest/subscribe/{$action}/{$id}/")
|
|
|
|
->setRenderAsForm(true)
|
|
|
|
->setUser($viewer)
|
|
|
|
->setIcon($icon));
|
|
|
|
}
|
|
|
|
|
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)
|
2013-09-25 22:44:52 +02:00
|
|
|
->setIcon('merge')
|
|
|
|
->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}"))
|
|
|
|
->setIcon('fork'));
|
|
|
|
|
|
|
|
$view->addAction(
|
|
|
|
id(new PhabricatorActionView())
|
|
|
|
->setName(pht('Edit Dependencies'))
|
|
|
|
->setHref("/search/attach/{$phid}/TASK/dependencies/")
|
|
|
|
->setWorkflow(true)
|
2013-09-25 22:44:52 +02:00
|
|
|
->setIcon('link')
|
|
|
|
->setDisabled(!$can_edit)
|
2013-10-01 21:01:55 +02:00
|
|
|
->setWorkflow(true));
|
2012-12-11 23:03:16 +01:00
|
|
|
|
|
|
|
$view->addAction(
|
|
|
|
id(new PhabricatorActionView())
|
|
|
|
->setName(pht('Edit Differential Revisions'))
|
|
|
|
->setHref("/search/attach/{$phid}/DREV/")
|
|
|
|
->setWorkflow(true)
|
2013-09-25 22:44:52 +02:00
|
|
|
->setIcon('attach')
|
|
|
|
->setDisabled(!$can_edit)
|
2013-10-01 21:01:55 +02:00
|
|
|
->setWorkflow(true));
|
2012-12-11 23:03:16 +01:00
|
|
|
|
2013-07-20 00:59:29 +02:00
|
|
|
$pholio_app =
|
|
|
|
PhabricatorApplication::getByClass('PhabricatorApplicationPholio');
|
|
|
|
if ($pholio_app->isInstalled()) {
|
|
|
|
$view->addAction(
|
|
|
|
id(new PhabricatorActionView())
|
|
|
|
->setName(pht('Edit Pholio Mocks'))
|
|
|
|
->setHref("/search/attach/{$phid}/MOCK/edge/")
|
|
|
|
->setWorkflow(true)
|
2013-09-25 22:44:52 +02:00
|
|
|
->setIcon('attach')
|
|
|
|
->setDisabled(!$can_edit)
|
2013-10-01 21:01:55 +02:00
|
|
|
->setWorkflow(true));
|
2013-07-20 00:59:29 +02:00
|
|
|
}
|
|
|
|
|
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,
|
2013-10-11 16:53:56 +02:00
|
|
|
PhabricatorActionListView $actions) {
|
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()
|
2013-07-20 00:59:29 +02:00
|
|
|
? $this->getHandle($task->getOwnerPHID())->renderLink()
|
|
|
|
: 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('Subscribers'),
|
|
|
|
$task->getCCPHIDs()
|
2013-07-20 00:59:29 +02:00
|
|
|
? $this->renderHandlesForPHIDs($task->getCCPHIDs(), ',')
|
|
|
|
: phutil_tag('em', array(), pht('None')));
|
2012-12-11 23:03:16 +01:00
|
|
|
|
|
|
|
$view->addProperty(
|
|
|
|
pht('Author'),
|
|
|
|
$this->getHandle($task->getAuthorPHID())->renderLink());
|
|
|
|
|
|
|
|
$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(
|
|
|
|
'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
|
|
|
}
|
|
|
|
|
|
|
|
$view->addProperty(
|
|
|
|
pht('Projects'),
|
|
|
|
$task->getProjectPHIDs()
|
2013-07-20 00:59:29 +02:00
|
|
|
? $this->renderHandlesForPHIDs($task->getProjectPHIDs(), ',')
|
|
|
|
: phutil_tag('em', array(), pht('None')));
|
2012-12-11 23:03:16 +01:00
|
|
|
|
|
|
|
$edge_types = array(
|
|
|
|
PhabricatorEdgeConfig::TYPE_TASK_DEPENDED_ON_BY_TASK
|
2013-07-20 00:59:29 +02:00
|
|
|
=> pht('Dependent Tasks'),
|
2012-12-11 23:03:16 +01:00
|
|
|
PhabricatorEdgeConfig::TYPE_TASK_DEPENDS_ON_TASK
|
2013-07-20 00:59:29 +02:00
|
|
|
=> pht('Depends On'),
|
2012-12-11 23:03:16 +01:00
|
|
|
PhabricatorEdgeConfig::TYPE_TASK_HAS_RELATED_DREV
|
2013-07-20 00:59:29 +02:00
|
|
|
=> pht('Differential Revisions'),
|
|
|
|
PhabricatorEdgeConfig::TYPE_TASK_HAS_MOCK
|
|
|
|
=> pht('Pholio Mocks'),
|
2012-12-11 23:03:16 +01:00
|
|
|
);
|
|
|
|
|
2013-04-06 20:40:43 +02:00
|
|
|
$revisions_commits = array();
|
|
|
|
$handles = $this->getLoadedHandles();
|
|
|
|
|
|
|
|
$commit_phids = array_keys(
|
|
|
|
$edges[PhabricatorEdgeConfig::TYPE_TASK_HAS_COMMIT]);
|
|
|
|
if ($commit_phids) {
|
2013-04-13 07:48:16 +02:00
|
|
|
$commit_drev = PhabricatorEdgeConfig::TYPE_COMMIT_HAS_DREV;
|
|
|
|
$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) {
|
2013-04-06 20:40:43 +02:00
|
|
|
$revisions_commits[$phid] = $handles[$phid]->renderLink();
|
2013-04-13 07:48:16 +02:00
|
|
|
$revision_phid = key($drev_edges[$phid][$commit_drev]);
|
2013-04-06 20:40:43 +02:00
|
|
|
$revision_handle = idx($handles, $revision_phid);
|
|
|
|
if ($revision_handle) {
|
2013-04-13 07:48:16 +02:00
|
|
|
$task_drev = PhabricatorEdgeConfig::TYPE_TASK_HAS_RELATED_DREV;
|
|
|
|
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]) {
|
|
|
|
$view->addProperty(
|
|
|
|
$edge_name,
|
|
|
|
$this->renderHandlesForPHIDs(array_keys($edges[$edge_type])));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2013-07-22 17:02:56 +02:00
|
|
|
$file_infos = idx($attached, PhabricatorFilePHIDTypeFile::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());
|
|
|
|
}
|
|
|
|
|
2013-09-24 20:10:46 +02:00
|
|
|
$field_list->appendFieldsToPropertyList(
|
|
|
|
$task,
|
|
|
|
$viewer,
|
|
|
|
$view);
|
|
|
|
|
2013-02-15 16:47:14 +01:00
|
|
|
$view->invokeWillRenderEvent();
|
|
|
|
|
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();
|
|
|
|
$section->addSectionHeader(pht('Description'));
|
|
|
|
$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
|
|
|
}
|