@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+97
+2
src/__phutil_library_map__.php
··· 1525 1525 'ManiphestTaskStatusHeraldAction' => 'applications/maniphest/herald/ManiphestTaskStatusHeraldAction.php', 1526 1526 'ManiphestTaskStatusHeraldField' => 'applications/maniphest/herald/ManiphestTaskStatusHeraldField.php', 1527 1527 'ManiphestTaskStatusTestCase' => 'applications/maniphest/constants/__tests__/ManiphestTaskStatusTestCase.php', 1528 + 'ManiphestTaskSubtypeDatasource' => 'applications/maniphest/typeahead/ManiphestTaskSubtypeDatasource.php', 1528 1529 'ManiphestTaskTestCase' => 'applications/maniphest/__tests__/ManiphestTaskTestCase.php', 1529 1530 'ManiphestTaskTitleHeraldField' => 'applications/maniphest/herald/ManiphestTaskTitleHeraldField.php', 1530 1531 'ManiphestTransaction' => 'applications/maniphest/storage/ManiphestTransaction.php', ··· 6424 6425 'ManiphestTaskStatusHeraldAction' => 'HeraldAction', 6425 6426 'ManiphestTaskStatusHeraldField' => 'ManiphestTaskHeraldField', 6426 6427 'ManiphestTaskStatusTestCase' => 'PhabricatorTestCase', 6428 + 'ManiphestTaskSubtypeDatasource' => 'PhabricatorTypeaheadDatasource', 6427 6429 'ManiphestTaskTestCase' => 'PhabricatorTestCase', 6428 6430 'ManiphestTaskTitleHeraldField' => 'ManiphestTaskHeraldField', 6429 6431 'ManiphestTransaction' => 'PhabricatorApplicationTransaction',
+18
src/applications/maniphest/query/ManiphestTaskSearchEngine.php
··· 44 44 } 45 45 46 46 protected function buildCustomSearchFields() { 47 + // Hide the "Subtypes" constraint from the web UI if the install only 48 + // defines one task subtype, since it isn't of any use in this case. 49 + $subtype_map = id(new ManiphestTask())->newEditEngineSubtypeMap(); 50 + $hide_subtypes = (count($subtype_map) == 1); 51 + 47 52 return array( 48 53 id(new PhabricatorOwnersSearchField()) 49 54 ->setLabel(pht('Assigned To')) ··· 73 78 pht('Search for tasks with given priorities.')) 74 79 ->setConduitParameterType(new ConduitIntListParameterType()) 75 80 ->setDatasource(new ManiphestTaskPriorityDatasource()), 81 + id(new PhabricatorSearchDatasourceField()) 82 + ->setLabel(pht('Subtypes')) 83 + ->setKey('subtypes') 84 + ->setAliases(array('subtype')) 85 + ->setDescription( 86 + pht('Search for tasks with given subtypes.')) 87 + ->setDatasource(new ManiphestTaskSubtypeDatasource()) 88 + ->setIsHidden($hide_subtypes), 76 89 id(new PhabricatorSearchTextField()) 77 90 ->setLabel(pht('Contains Words')) 78 91 ->setKey('fulltext'), ··· 130 143 'subscriberPHIDs', 131 144 'statuses', 132 145 'priorities', 146 + 'subtypes', 133 147 'fulltext', 134 148 'hasParents', 135 149 'hasSubtasks', ··· 176 190 177 191 if ($map['priorities']) { 178 192 $query->withPriorities($map['priorities']); 193 + } 194 + 195 + if ($map['subtypes']) { 196 + $query->withSubtypes($map['subtypes']); 179 197 } 180 198 181 199 if ($map['createdStart']) {
+44
src/applications/maniphest/typeahead/ManiphestTaskSubtypeDatasource.php
··· 1 + <?php 2 + 3 + final class ManiphestTaskSubtypeDatasource 4 + extends PhabricatorTypeaheadDatasource { 5 + 6 + public function getBrowseTitle() { 7 + return pht('Browse Subtypes'); 8 + } 9 + 10 + public function getPlaceholderText() { 11 + return pht('Type a task subtype name...'); 12 + } 13 + 14 + public function getDatasourceApplicationClass() { 15 + return 'PhabricatorManiphestApplication'; 16 + } 17 + 18 + public function loadResults() { 19 + $results = $this->buildResults(); 20 + return $this->filterResultsAgainstTokens($results); 21 + } 22 + 23 + protected function renderSpecialTokens(array $values) { 24 + return $this->renderTokensFromResults($this->buildResults(), $values); 25 + } 26 + 27 + private function buildResults() { 28 + $results = array(); 29 + 30 + $subtype_map = id(new ManiphestTask())->newEditEngineSubtypeMap(); 31 + foreach ($subtype_map as $key => $subtype) { 32 + 33 + $result = id(new PhabricatorTypeaheadResult()) 34 + ->setIcon($subtype->getIcon()) 35 + ->setPHID($key) 36 + ->setName($subtype->getName()); 37 + 38 + $results[$key] = $result; 39 + } 40 + 41 + return $results; 42 + } 43 + 44 + }
+29
src/applications/search/field/PhabricatorSearchField.php
··· 17 17 private $aliases = array(); 18 18 private $errors = array(); 19 19 private $description; 20 + private $isHidden; 20 21 21 22 22 23 /* -( Configuring Fields )------------------------------------------------- */ ··· 188 189 } 189 190 190 191 192 + /** 193 + * Hide this field from the web UI. 194 + * 195 + * @param bool True to hide the field from the web UI. 196 + * @return this 197 + * @task config 198 + */ 199 + public function setIsHidden($is_hidden) { 200 + $this->isHidden = $is_hidden; 201 + return $this; 202 + } 203 + 204 + 205 + /** 206 + * Should this field be hidden from the web UI? 207 + * 208 + * @return bool True to hide the field in the web UI. 209 + * @task config 210 + */ 211 + public function getIsHidden() { 212 + return $this->isHidden; 213 + } 214 + 215 + 191 216 /* -( Handling Errors )---------------------------------------------------- */ 192 217 193 218 ··· 273 298 274 299 275 300 protected function renderControl() { 301 + if ($this->getIsHidden()) { 302 + return null; 303 + } 304 + 276 305 $control = $this->newControl(); 277 306 278 307 if (!$control) {
+4
src/applications/transactions/editengine/PhabricatorEditEngineSubtype.php
··· 27 27 return $this->name; 28 28 } 29 29 30 + public function getIcon() { 31 + return 'fa-drivers-license-o'; 32 + } 33 + 30 34 public static function validateSubtypeKey($subtype) { 31 35 if (strlen($subtype) > 64) { 32 36 throw new Exception(