mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-30 02:32:42 +01:00
Allow tasks to be searched by subtype
Summary: Ref T12314. Allow tasks to be queried by subtype using a typeahead. Open to a better default icon. I'll probably let you configure them later. Just hide this constraint if there's only one subtype. Test Plan: - Searched for subtypes. - Verified that the control hides if there is only one subtype. {F3492293} Reviewers: chad Reviewed By: chad Maniphest Tasks: T12314 Differential Revision: https://secure.phabricator.com/D17444
This commit is contained in:
parent
4a061b1def
commit
4948a21959
5 changed files with 97 additions and 0 deletions
|
@ -1525,6 +1525,7 @@ phutil_register_library_map(array(
|
||||||
'ManiphestTaskStatusHeraldAction' => 'applications/maniphest/herald/ManiphestTaskStatusHeraldAction.php',
|
'ManiphestTaskStatusHeraldAction' => 'applications/maniphest/herald/ManiphestTaskStatusHeraldAction.php',
|
||||||
'ManiphestTaskStatusHeraldField' => 'applications/maniphest/herald/ManiphestTaskStatusHeraldField.php',
|
'ManiphestTaskStatusHeraldField' => 'applications/maniphest/herald/ManiphestTaskStatusHeraldField.php',
|
||||||
'ManiphestTaskStatusTestCase' => 'applications/maniphest/constants/__tests__/ManiphestTaskStatusTestCase.php',
|
'ManiphestTaskStatusTestCase' => 'applications/maniphest/constants/__tests__/ManiphestTaskStatusTestCase.php',
|
||||||
|
'ManiphestTaskSubtypeDatasource' => 'applications/maniphest/typeahead/ManiphestTaskSubtypeDatasource.php',
|
||||||
'ManiphestTaskTestCase' => 'applications/maniphest/__tests__/ManiphestTaskTestCase.php',
|
'ManiphestTaskTestCase' => 'applications/maniphest/__tests__/ManiphestTaskTestCase.php',
|
||||||
'ManiphestTaskTitleHeraldField' => 'applications/maniphest/herald/ManiphestTaskTitleHeraldField.php',
|
'ManiphestTaskTitleHeraldField' => 'applications/maniphest/herald/ManiphestTaskTitleHeraldField.php',
|
||||||
'ManiphestTransaction' => 'applications/maniphest/storage/ManiphestTransaction.php',
|
'ManiphestTransaction' => 'applications/maniphest/storage/ManiphestTransaction.php',
|
||||||
|
@ -6424,6 +6425,7 @@ phutil_register_library_map(array(
|
||||||
'ManiphestTaskStatusHeraldAction' => 'HeraldAction',
|
'ManiphestTaskStatusHeraldAction' => 'HeraldAction',
|
||||||
'ManiphestTaskStatusHeraldField' => 'ManiphestTaskHeraldField',
|
'ManiphestTaskStatusHeraldField' => 'ManiphestTaskHeraldField',
|
||||||
'ManiphestTaskStatusTestCase' => 'PhabricatorTestCase',
|
'ManiphestTaskStatusTestCase' => 'PhabricatorTestCase',
|
||||||
|
'ManiphestTaskSubtypeDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||||
'ManiphestTaskTestCase' => 'PhabricatorTestCase',
|
'ManiphestTaskTestCase' => 'PhabricatorTestCase',
|
||||||
'ManiphestTaskTitleHeraldField' => 'ManiphestTaskHeraldField',
|
'ManiphestTaskTitleHeraldField' => 'ManiphestTaskHeraldField',
|
||||||
'ManiphestTransaction' => 'PhabricatorApplicationTransaction',
|
'ManiphestTransaction' => 'PhabricatorApplicationTransaction',
|
||||||
|
|
|
@ -44,6 +44,11 @@ final class ManiphestTaskSearchEngine
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildCustomSearchFields() {
|
protected function buildCustomSearchFields() {
|
||||||
|
// Hide the "Subtypes" constraint from the web UI if the install only
|
||||||
|
// defines one task subtype, since it isn't of any use in this case.
|
||||||
|
$subtype_map = id(new ManiphestTask())->newEditEngineSubtypeMap();
|
||||||
|
$hide_subtypes = (count($subtype_map) == 1);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
id(new PhabricatorOwnersSearchField())
|
id(new PhabricatorOwnersSearchField())
|
||||||
->setLabel(pht('Assigned To'))
|
->setLabel(pht('Assigned To'))
|
||||||
|
@ -73,6 +78,14 @@ final class ManiphestTaskSearchEngine
|
||||||
pht('Search for tasks with given priorities.'))
|
pht('Search for tasks with given priorities.'))
|
||||||
->setConduitParameterType(new ConduitIntListParameterType())
|
->setConduitParameterType(new ConduitIntListParameterType())
|
||||||
->setDatasource(new ManiphestTaskPriorityDatasource()),
|
->setDatasource(new ManiphestTaskPriorityDatasource()),
|
||||||
|
id(new PhabricatorSearchDatasourceField())
|
||||||
|
->setLabel(pht('Subtypes'))
|
||||||
|
->setKey('subtypes')
|
||||||
|
->setAliases(array('subtype'))
|
||||||
|
->setDescription(
|
||||||
|
pht('Search for tasks with given subtypes.'))
|
||||||
|
->setDatasource(new ManiphestTaskSubtypeDatasource())
|
||||||
|
->setIsHidden($hide_subtypes),
|
||||||
id(new PhabricatorSearchTextField())
|
id(new PhabricatorSearchTextField())
|
||||||
->setLabel(pht('Contains Words'))
|
->setLabel(pht('Contains Words'))
|
||||||
->setKey('fulltext'),
|
->setKey('fulltext'),
|
||||||
|
@ -130,6 +143,7 @@ final class ManiphestTaskSearchEngine
|
||||||
'subscriberPHIDs',
|
'subscriberPHIDs',
|
||||||
'statuses',
|
'statuses',
|
||||||
'priorities',
|
'priorities',
|
||||||
|
'subtypes',
|
||||||
'fulltext',
|
'fulltext',
|
||||||
'hasParents',
|
'hasParents',
|
||||||
'hasSubtasks',
|
'hasSubtasks',
|
||||||
|
@ -178,6 +192,10 @@ final class ManiphestTaskSearchEngine
|
||||||
$query->withPriorities($map['priorities']);
|
$query->withPriorities($map['priorities']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($map['subtypes']) {
|
||||||
|
$query->withSubtypes($map['subtypes']);
|
||||||
|
}
|
||||||
|
|
||||||
if ($map['createdStart']) {
|
if ($map['createdStart']) {
|
||||||
$query->withDateCreatedAfter($map['createdStart']);
|
$query->withDateCreatedAfter($map['createdStart']);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class ManiphestTaskSubtypeDatasource
|
||||||
|
extends PhabricatorTypeaheadDatasource {
|
||||||
|
|
||||||
|
public function getBrowseTitle() {
|
||||||
|
return pht('Browse Subtypes');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPlaceholderText() {
|
||||||
|
return pht('Type a task subtype name...');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDatasourceApplicationClass() {
|
||||||
|
return 'PhabricatorManiphestApplication';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loadResults() {
|
||||||
|
$results = $this->buildResults();
|
||||||
|
return $this->filterResultsAgainstTokens($results);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderSpecialTokens(array $values) {
|
||||||
|
return $this->renderTokensFromResults($this->buildResults(), $values);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildResults() {
|
||||||
|
$results = array();
|
||||||
|
|
||||||
|
$subtype_map = id(new ManiphestTask())->newEditEngineSubtypeMap();
|
||||||
|
foreach ($subtype_map as $key => $subtype) {
|
||||||
|
|
||||||
|
$result = id(new PhabricatorTypeaheadResult())
|
||||||
|
->setIcon($subtype->getIcon())
|
||||||
|
->setPHID($key)
|
||||||
|
->setName($subtype->getName());
|
||||||
|
|
||||||
|
$results[$key] = $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -17,6 +17,7 @@ abstract class PhabricatorSearchField extends Phobject {
|
||||||
private $aliases = array();
|
private $aliases = array();
|
||||||
private $errors = array();
|
private $errors = array();
|
||||||
private $description;
|
private $description;
|
||||||
|
private $isHidden;
|
||||||
|
|
||||||
|
|
||||||
/* -( Configuring Fields )------------------------------------------------- */
|
/* -( Configuring Fields )------------------------------------------------- */
|
||||||
|
@ -188,6 +189,30 @@ abstract class PhabricatorSearchField extends Phobject {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide this field from the web UI.
|
||||||
|
*
|
||||||
|
* @param bool True to hide the field from the web UI.
|
||||||
|
* @return this
|
||||||
|
* @task config
|
||||||
|
*/
|
||||||
|
public function setIsHidden($is_hidden) {
|
||||||
|
$this->isHidden = $is_hidden;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should this field be hidden from the web UI?
|
||||||
|
*
|
||||||
|
* @return bool True to hide the field in the web UI.
|
||||||
|
* @task config
|
||||||
|
*/
|
||||||
|
public function getIsHidden() {
|
||||||
|
return $this->isHidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -( Handling Errors )---------------------------------------------------- */
|
/* -( Handling Errors )---------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
@ -273,6 +298,10 @@ abstract class PhabricatorSearchField extends Phobject {
|
||||||
|
|
||||||
|
|
||||||
protected function renderControl() {
|
protected function renderControl() {
|
||||||
|
if ($this->getIsHidden()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
$control = $this->newControl();
|
$control = $this->newControl();
|
||||||
|
|
||||||
if (!$control) {
|
if (!$control) {
|
||||||
|
|
|
@ -27,6 +27,10 @@ final class PhabricatorEditEngineSubtype
|
||||||
return $this->name;
|
return $this->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getIcon() {
|
||||||
|
return 'fa-drivers-license-o';
|
||||||
|
}
|
||||||
|
|
||||||
public static function validateSubtypeKey($subtype) {
|
public static function validateSubtypeKey($subtype) {
|
||||||
if (strlen($subtype) > 64) {
|
if (strlen($subtype) > 64) {
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
|
|
Loading…
Reference in a new issue