mirror of
https://we.phorge.it/source/phorge.git
synced 2025-02-08 21:08:29 +01:00
Maniphest - allow for searching for tasks based on dependency relationships
Summary: Fixes T5352. This is very useful for finding things that should be easy to do ("not blocked") as well as things that are important to do ("blocking"). I have wanted to check out the latter case in our installation, though no promises on what I would end up actually doing from that search result list. =D I also think supporting something like T6638 is reasonable but the UI seems trickier to me; its some sort of task tokenizer, which I don't think we've done before? Test Plan: toggled various search options and got reasonable results. When i clicked conflicting things like "blocking" and "not blocking" verified it was like I had not clicked anything at all. Reviewers: chad, epriestley Reviewed By: epriestley Subscribers: Korvin, epriestley Maniphest Tasks: T5352 Differential Revision: https://secure.phabricator.com/D11306
This commit is contained in:
parent
25167776dc
commit
1eb8b6a1b8
2 changed files with 114 additions and 1 deletions
|
@ -53,6 +53,9 @@ final class ManiphestTaskQuery extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
private $needSubscriberPHIDs;
|
private $needSubscriberPHIDs;
|
||||||
private $needProjectPHIDs;
|
private $needProjectPHIDs;
|
||||||
|
|
||||||
|
private $blockingTasks;
|
||||||
|
private $blockedTasks;
|
||||||
|
|
||||||
const DEFAULT_PAGE_SIZE = 1000;
|
const DEFAULT_PAGE_SIZE = 1000;
|
||||||
|
|
||||||
public function withAuthors(array $authors) {
|
public function withAuthors(array $authors) {
|
||||||
|
@ -161,6 +164,34 @@ final class ManiphestTaskQuery extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True returns tasks that are blocking other tasks only.
|
||||||
|
* False returns tasks that are not blocking other tasks only.
|
||||||
|
* Null returns tasks regardless of blocking status.
|
||||||
|
*/
|
||||||
|
public function withBlockingTasks($mode) {
|
||||||
|
$this->blockingTasks = $mode;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function shouldJoinBlockingTasks() {
|
||||||
|
return $this->blockingTasks !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True returns tasks that are blocked by other tasks only.
|
||||||
|
* False returns tasks that are not blocked by other tasks only.
|
||||||
|
* Null returns tasks regardless of blocked by status.
|
||||||
|
*/
|
||||||
|
public function withBlockedTasks($mode) {
|
||||||
|
$this->blockedTasks = $mode;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function shouldJoinBlockedTasks() {
|
||||||
|
return $this->blockedTasks !== null;
|
||||||
|
}
|
||||||
|
|
||||||
public function withDateCreatedBefore($date_created_before) {
|
public function withDateCreatedBefore($date_created_before) {
|
||||||
$this->dateCreatedBefore = $date_created_before;
|
$this->dateCreatedBefore = $date_created_before;
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -207,6 +238,7 @@ final class ManiphestTaskQuery extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
$where[] = $this->buildStatusWhereClause($conn);
|
$where[] = $this->buildStatusWhereClause($conn);
|
||||||
$where[] = $this->buildStatusesWhereClause($conn);
|
$where[] = $this->buildStatusesWhereClause($conn);
|
||||||
$where[] = $this->buildPrioritiesWhereClause($conn);
|
$where[] = $this->buildPrioritiesWhereClause($conn);
|
||||||
|
$where[] = $this->buildDependenciesWhereClause($conn);
|
||||||
$where[] = $this->buildAuthorWhereClause($conn);
|
$where[] = $this->buildAuthorWhereClause($conn);
|
||||||
$where[] = $this->buildOwnerWhereClause($conn);
|
$where[] = $this->buildOwnerWhereClause($conn);
|
||||||
$where[] = $this->buildProjectWhereClause($conn);
|
$where[] = $this->buildProjectWhereClause($conn);
|
||||||
|
@ -520,6 +552,38 @@ final class ManiphestTaskQuery extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
$fulltext_results);
|
$fulltext_results);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function buildDependenciesWhereClause(
|
||||||
|
AphrontDatabaseConnection $conn) {
|
||||||
|
|
||||||
|
if (!$this->shouldJoinBlockedTasks() &&
|
||||||
|
!$this->shouldJoinBlockingTasks()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parts = array();
|
||||||
|
if ($this->blockingTasks === true) {
|
||||||
|
$parts[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'blocking.dst IS NOT NULL');
|
||||||
|
} else if ($this->blockingTasks === false) {
|
||||||
|
$parts[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'blocking.dst IS NULL');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->blockedTasks === true) {
|
||||||
|
$parts[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'blocked.dst IS NOT NULL');
|
||||||
|
} else if ($this->blockedTasks === false) {
|
||||||
|
$parts[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'blocked.dst IS NULL');
|
||||||
|
}
|
||||||
|
|
||||||
|
return '('.implode(') OR (', $parts).')';
|
||||||
|
}
|
||||||
|
|
||||||
private function buildProjectWhereClause(AphrontDatabaseConnection $conn) {
|
private function buildProjectWhereClause(AphrontDatabaseConnection $conn) {
|
||||||
if (!$this->projectPHIDs && !$this->includeNoProject) {
|
if (!$this->projectPHIDs && !$this->includeNoProject) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -699,6 +763,23 @@ final class ManiphestTaskQuery extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
|
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->shouldJoinBlockingTasks()) {
|
||||||
|
$joins[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'LEFT JOIN %T blocking ON blocking.src = task.phid '.
|
||||||
|
'AND blocking.type = %d',
|
||||||
|
$edge_table,
|
||||||
|
ManiphestTaskDependedOnByTaskEdgeType::EDGECONST);
|
||||||
|
}
|
||||||
|
if ($this->shouldJoinBlockedTasks()) {
|
||||||
|
$joins[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'LEFT JOIN %T blocked ON blocked.src = task.phid '.
|
||||||
|
'AND blocked.type = %d',
|
||||||
|
$edge_table,
|
||||||
|
ManiphestTaskDependsOnTaskEdgeType::EDGECONST);
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->anyProjectPHIDs || $this->anyUserProjectPHIDs) {
|
if ($this->anyProjectPHIDs || $this->anyUserProjectPHIDs) {
|
||||||
$joins[] = qsprintf(
|
$joins[] = qsprintf(
|
||||||
$conn_r,
|
$conn_r,
|
||||||
|
@ -766,6 +847,8 @@ final class ManiphestTaskQuery extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
private function buildGroupClause(AphrontDatabaseConnection $conn_r) {
|
private function buildGroupClause(AphrontDatabaseConnection $conn_r) {
|
||||||
$joined_multiple_rows = (count($this->projectPHIDs) > 1) ||
|
$joined_multiple_rows = (count($this->projectPHIDs) > 1) ||
|
||||||
(count($this->anyProjectPHIDs) > 1) ||
|
(count($this->anyProjectPHIDs) > 1) ||
|
||||||
|
$this->shouldJoinBlockingTasks() ||
|
||||||
|
$this->shouldJoinBlockedTasks() ||
|
||||||
($this->getApplicationSearchMayJoinMultipleRows());
|
($this->getApplicationSearchMayJoinMultipleRows());
|
||||||
|
|
||||||
$joined_project_name = ($this->groupBy == self::GROUP_PROJECT);
|
$joined_project_name = ($this->groupBy == self::GROUP_PROJECT);
|
||||||
|
|
|
@ -67,6 +67,13 @@ final class ManiphestTaskSearchEngine
|
||||||
'priorities',
|
'priorities',
|
||||||
$this->readListFromRequest($request, 'priorities'));
|
$this->readListFromRequest($request, 'priorities'));
|
||||||
|
|
||||||
|
$saved->setParameter(
|
||||||
|
'blocking',
|
||||||
|
$this->readBoolFromRequest($request, 'blocking'));
|
||||||
|
$saved->setParameter(
|
||||||
|
'blocked',
|
||||||
|
$this->readBoolFromRequest($request, 'blocked'));
|
||||||
|
|
||||||
$saved->setParameter('group', $request->getStr('group'));
|
$saved->setParameter('group', $request->getStr('group'));
|
||||||
$saved->setParameter('order', $request->getStr('order'));
|
$saved->setParameter('order', $request->getStr('order'));
|
||||||
|
|
||||||
|
@ -152,6 +159,10 @@ final class ManiphestTaskSearchEngine
|
||||||
$query->withPriorities($priorities);
|
$query->withPriorities($priorities);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$query->withBlockingTasks($saved->getParameter('blocking'));
|
||||||
|
$query->withBlockedTasks($saved->getParameter('blocked'));
|
||||||
|
|
||||||
$this->applyOrderByToQuery(
|
$this->applyOrderByToQuery(
|
||||||
$query,
|
$query,
|
||||||
$this->getOrderValues(),
|
$this->getOrderValues(),
|
||||||
|
@ -302,6 +313,23 @@ final class ManiphestTaskSearchEngine
|
||||||
isset($priorities[$pri]));
|
isset($priorities[$pri]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$blocking_control = id(new AphrontFormSelectControl())
|
||||||
|
->setLabel(pht('Blocking'))
|
||||||
|
->setName('blocking')
|
||||||
|
->setValue($this->getBoolFromQuery($saved, 'blocking'))
|
||||||
|
->setOptions(array(
|
||||||
|
'' => pht('Show All Tasks'),
|
||||||
|
'true' => pht('Show Tasks Blocking Other Tasks'),
|
||||||
|
'false' => pht('Show Tasks Not Blocking Other Tasks'),));
|
||||||
|
$blocked_control = id(new AphrontFormSelectControl())
|
||||||
|
->setLabel(pht('Blocked'))
|
||||||
|
->setName('blocked')
|
||||||
|
->setValue($this->getBoolFromQuery($saved, 'blocked'))
|
||||||
|
->setOptions(array(
|
||||||
|
'' => pht('Show All Tasks'),
|
||||||
|
'true' => pht('Show Tasks Blocked By Other Tasks'),
|
||||||
|
'false' => pht('Show Tasks Not Blocked By Other Tasks'),));
|
||||||
|
|
||||||
$ids = $saved->getParameter('ids', array());
|
$ids = $saved->getParameter('ids', array());
|
||||||
|
|
||||||
$builtin_orders = $this->getOrderOptions();
|
$builtin_orders = $this->getOrderOptions();
|
||||||
|
@ -377,7 +405,9 @@ final class ManiphestTaskSearchEngine
|
||||||
->setLabel(pht('Contains Words'))
|
->setLabel(pht('Contains Words'))
|
||||||
->setValue($saved->getParameter('fulltext')))
|
->setValue($saved->getParameter('fulltext')))
|
||||||
->appendChild($status_control)
|
->appendChild($status_control)
|
||||||
->appendChild($priority_control);
|
->appendChild($priority_control)
|
||||||
|
->appendChild($blocking_control)
|
||||||
|
->appendChild($blocked_control);
|
||||||
|
|
||||||
if (!$this->getIsBoardView()) {
|
if (!$this->getIsBoardView()) {
|
||||||
$form
|
$form
|
||||||
|
|
Loading…
Add table
Reference in a new issue