mirror of
https://we.phorge.it/source/phorge.git
synced 2025-01-29 16:08:22 +01:00
Render parent and child tasks in Maniphest with a graph trace
Summary: Ref T4788. This seems reasonable locally, but not sure how it will feel on real data. Might need some tweaks, or might just be a terrible idea. Test Plan: {F1708059} Reviewers: chad Reviewed By: chad Maniphest Tasks: T4788 Differential Revision: https://secure.phabricator.com/D16214
This commit is contained in:
parent
cc7ae60aaf
commit
0a132e468f
7 changed files with 135 additions and 15 deletions
|
@ -1430,6 +1430,7 @@ phutil_register_library_map(array(
|
|||
'ManiphestTaskEditBulkJobType' => 'applications/maniphest/bulk/ManiphestTaskEditBulkJobType.php',
|
||||
'ManiphestTaskEditController' => 'applications/maniphest/controller/ManiphestTaskEditController.php',
|
||||
'ManiphestTaskFulltextEngine' => 'applications/maniphest/search/ManiphestTaskFulltextEngine.php',
|
||||
'ManiphestTaskGraph' => 'infrastructure/graph/ManiphestTaskGraph.php',
|
||||
'ManiphestTaskHasCommitEdgeType' => 'applications/maniphest/edge/ManiphestTaskHasCommitEdgeType.php',
|
||||
'ManiphestTaskHasCommitRelationship' => 'applications/maniphest/relationship/ManiphestTaskHasCommitRelationship.php',
|
||||
'ManiphestTaskHasDuplicateTaskEdgeType' => 'applications/maniphest/edge/ManiphestTaskHasDuplicateTaskEdgeType.php',
|
||||
|
@ -5947,6 +5948,7 @@ phutil_register_library_map(array(
|
|||
'ManiphestTaskEditBulkJobType' => 'PhabricatorWorkerBulkJobType',
|
||||
'ManiphestTaskEditController' => 'ManiphestController',
|
||||
'ManiphestTaskFulltextEngine' => 'PhabricatorFulltextEngine',
|
||||
'ManiphestTaskGraph' => 'PhabricatorObjectGraph',
|
||||
'ManiphestTaskHasCommitEdgeType' => 'PhabricatorEdgeType',
|
||||
'ManiphestTaskHasCommitRelationship' => 'ManiphestTaskRelationship',
|
||||
'ManiphestTaskHasDuplicateTaskEdgeType' => 'PhabricatorEdgeType',
|
||||
|
|
|
@ -31,8 +31,6 @@ final class ManiphestTaskDetailController extends ManiphestController {
|
|||
->setTargetObject($task);
|
||||
|
||||
$e_commit = ManiphestTaskHasCommitEdgeType::EDGECONST;
|
||||
$e_dep_on = ManiphestTaskDependsOnTaskEdgeType::EDGECONST;
|
||||
$e_dep_by = ManiphestTaskDependedOnByTaskEdgeType::EDGECONST;
|
||||
$e_rev = ManiphestTaskHasRevisionEdgeType::EDGECONST;
|
||||
$e_mock = ManiphestTaskHasMockEdgeType::EDGECONST;
|
||||
|
||||
|
@ -43,8 +41,6 @@ final class ManiphestTaskDetailController extends ManiphestController {
|
|||
->withEdgeTypes(
|
||||
array(
|
||||
$e_commit,
|
||||
$e_dep_on,
|
||||
$e_dep_by,
|
||||
$e_rev,
|
||||
$e_mock,
|
||||
));
|
||||
|
@ -91,6 +87,15 @@ final class ManiphestTaskDetailController extends ManiphestController {
|
|||
->addPropertySection(pht('Description'), $description)
|
||||
->addPropertySection(pht('Details'), $details);
|
||||
|
||||
$task_graph = id(new ManiphestTaskGraph())
|
||||
->setViewer($viewer)
|
||||
->setSeedPHID($task->getPHID())
|
||||
->loadGraph();
|
||||
if (!$task_graph->isEmpty()) {
|
||||
$graph_table = $task_graph->newGraphTable();
|
||||
$view->addPropertySection(pht('Task Graph'), $graph_table);
|
||||
}
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
|
@ -186,9 +191,7 @@ final class ManiphestTaskDetailController extends ManiphestController {
|
|||
$edit_uri = $this->getApplicationURI($edit_uri);
|
||||
}
|
||||
|
||||
$task_submenu = array();
|
||||
|
||||
$task_submenu[] = id(new PhabricatorActionView())
|
||||
$subtask_item = id(new PhabricatorActionView())
|
||||
->setName(pht('Create Subtask'))
|
||||
->setHref($edit_uri)
|
||||
->setIcon('fa-level-down')
|
||||
|
@ -200,6 +203,7 @@ final class ManiphestTaskDetailController extends ManiphestController {
|
|||
$task);
|
||||
|
||||
$submenu_actions = array(
|
||||
$subtask_item,
|
||||
ManiphestTaskHasParentRelationship::RELATIONSHIPKEY,
|
||||
ManiphestTaskHasSubtaskRelationship::RELATIONSHIPKEY,
|
||||
ManiphestTaskMergeInRelationship::RELATIONSHIPKEY,
|
||||
|
@ -280,10 +284,6 @@ final class ManiphestTaskDetailController extends ManiphestController {
|
|||
}
|
||||
|
||||
$edge_types = array(
|
||||
ManiphestTaskDependedOnByTaskEdgeType::EDGECONST
|
||||
=> pht('Parent Tasks'),
|
||||
ManiphestTaskDependsOnTaskEdgeType::EDGECONST
|
||||
=> pht('Subtasks'),
|
||||
ManiphestTaskHasRevisionEdgeType::EDGECONST
|
||||
=> pht('Differential Revisions'),
|
||||
ManiphestTaskHasMockEdgeType::EDGECONST
|
||||
|
|
|
@ -179,6 +179,10 @@ final class ManiphestTask extends ManiphestDAO
|
|||
return 'T'.$this->getID();
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
return '/'.$this->getMonogram();
|
||||
}
|
||||
|
||||
public function attachGroupByProjectPHID($phid) {
|
||||
$this->groupByProjectPHID = $phid;
|
||||
return $this;
|
||||
|
|
|
@ -52,6 +52,12 @@ final class PhabricatorObjectRelationshipList extends Phobject {
|
|||
$actions = array();
|
||||
|
||||
foreach ($keys as $key) {
|
||||
// If we're passed a menu item, just include it verbatim.
|
||||
if ($key instanceof PhabricatorActionView) {
|
||||
$actions[] = $key;
|
||||
continue;
|
||||
}
|
||||
|
||||
$relationship = $this->getRelationship($key);
|
||||
if (!$relationship) {
|
||||
throw new Exception(
|
||||
|
|
|
@ -137,12 +137,31 @@ final class PHUIDiffGraphView extends Phobject {
|
|||
);
|
||||
}
|
||||
|
||||
// If this is the last page in history, replace the "o" with an "x" so we
|
||||
// do not draw a connecting line downward, and replace "^" with an "X" for
|
||||
// repositories with exactly one commit.
|
||||
// If this is the last page in history, replace any "o" characters at the
|
||||
// bottom of columns with "x" characters so we do not draw a connecting
|
||||
// line downward, and replace "^" with an "X" for repositories with
|
||||
// exactly one commit.
|
||||
if ($this->getIsTail() && $graph) {
|
||||
$terminated = array();
|
||||
foreach (array_reverse(array_keys($graph)) as $key) {
|
||||
$line = $graph[$key]['line'];
|
||||
$len = strlen($line);
|
||||
for ($ii = 0; $ii < $len; $ii++) {
|
||||
if (isset($terminated[$ii])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$c = $line[$ii];
|
||||
if ($c == 'o') {
|
||||
$terminated[$ii] = true;
|
||||
$graph[$key]['line'][$ii] = 'x';
|
||||
} else if ($c != ' ') {
|
||||
$terminated[$ii] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$last = array_pop($graph);
|
||||
$last['line'] = str_replace('o', 'x', $last['line']);
|
||||
$last['line'] = str_replace('^', 'X', $last['line']);
|
||||
$graph[] = $last;
|
||||
}
|
||||
|
|
87
src/infrastructure/graph/ManiphestTaskGraph.php
Normal file
87
src/infrastructure/graph/ManiphestTaskGraph.php
Normal file
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
final class ManiphestTaskGraph
|
||||
extends PhabricatorObjectGraph {
|
||||
|
||||
protected function getEdgeTypes() {
|
||||
return array(
|
||||
ManiphestTaskDependedOnByTaskEdgeType::EDGECONST,
|
||||
ManiphestTaskDependsOnTaskEdgeType::EDGECONST,
|
||||
);
|
||||
}
|
||||
|
||||
protected function getParentEdgeType() {
|
||||
return ManiphestTaskDependsOnTaskEdgeType::EDGECONST;
|
||||
}
|
||||
|
||||
protected function newQuery() {
|
||||
return new ManiphestTaskQuery();
|
||||
}
|
||||
|
||||
protected function newTableRow($phid, $object, $trace) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
if ($object) {
|
||||
$status = $object->getStatus();
|
||||
$priority = $object->getPriority();
|
||||
$status_icon = ManiphestTaskStatus::getStatusIcon($status);
|
||||
$status_name = ManiphestTaskStatus::getTaskStatusName($status);
|
||||
$priority_color = ManiphestTaskPriority::getTaskPriorityColor($priority);
|
||||
|
||||
|
||||
$status = array(
|
||||
id(new PHUIIconView())->setIcon($status_icon, $priority_color),
|
||||
' ',
|
||||
$status_name,
|
||||
);
|
||||
|
||||
$owner_phid = $object->getOwnerPHID();
|
||||
if ($owner_phid) {
|
||||
$assigned = $viewer->renderHandle($owner_phid);
|
||||
} else {
|
||||
$assigned = phutil_tag('em', array(), pht('None'));
|
||||
}
|
||||
|
||||
$link = phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $object->getURI(),
|
||||
),
|
||||
array(
|
||||
$object->getMonogram(),
|
||||
' ',
|
||||
$object->getTitle(),
|
||||
));
|
||||
} else {
|
||||
$status = null;
|
||||
$assigned = null;
|
||||
$link = $viewer->renderHandle($phid);
|
||||
}
|
||||
|
||||
return array(
|
||||
$trace,
|
||||
$status,
|
||||
$assigned,
|
||||
$link,
|
||||
);
|
||||
}
|
||||
|
||||
protected function newTable(AphrontTableView $table) {
|
||||
return $table
|
||||
->setHeaders(
|
||||
array(
|
||||
null,
|
||||
pht('Status'),
|
||||
pht('Assigned'),
|
||||
pht('Task'),
|
||||
))
|
||||
->setColumnClasses(
|
||||
array(
|
||||
'threads',
|
||||
null,
|
||||
null,
|
||||
'wide',
|
||||
));
|
||||
}
|
||||
|
||||
}
|
|
@ -55,6 +55,8 @@ abstract class PhabricatorObjectGraph
|
|||
|
||||
$map = array();
|
||||
foreach ($nodes as $node) {
|
||||
$map[$node] = array();
|
||||
|
||||
foreach ($edge_types as $edge_type) {
|
||||
$dst_phids = $query->getDestinationPHIDs(
|
||||
array($node),
|
||||
|
|
Loading…
Add table
Reference in a new issue