mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-19 12:00:55 +01:00
Implement open() and closed() Maniphest tokenizer status functions, plus cleanup
Summary: Ref T4100. - Make it easy to choose all open or closed tasks. - Make "special" tokenizers composable. - Get `viewer()` generating documentation properly. Test Plan: - Ran queries with new tokens. - Browsed new tokens. - Viewed docs on new tokens. - Used plain status tokens. Reviewers: btrahan Reviewed By: btrahan Subscribers: chad, epriestley Maniphest Tasks: T4100 Differential Revision: https://secure.phabricator.com/D12530
This commit is contained in:
parent
ccd6770a09
commit
f64ca87bfe
9 changed files with 244 additions and 8 deletions
|
@ -1045,6 +1045,7 @@ phutil_register_library_map(array(
|
|||
'ManiphestStatusEmailCommand' => 'applications/maniphest/command/ManiphestStatusEmailCommand.php',
|
||||
'ManiphestSubpriorityController' => 'applications/maniphest/controller/ManiphestSubpriorityController.php',
|
||||
'ManiphestTask' => 'applications/maniphest/storage/ManiphestTask.php',
|
||||
'ManiphestTaskClosedStatusDatasource' => 'applications/maniphest/typeahead/ManiphestTaskClosedStatusDatasource.php',
|
||||
'ManiphestTaskDependedOnByTaskEdgeType' => 'applications/maniphest/edge/ManiphestTaskDependedOnByTaskEdgeType.php',
|
||||
'ManiphestTaskDependsOnTaskEdgeType' => 'applications/maniphest/edge/ManiphestTaskDependsOnTaskEdgeType.php',
|
||||
'ManiphestTaskDetailController' => 'applications/maniphest/controller/ManiphestTaskDetailController.php',
|
||||
|
@ -1055,6 +1056,7 @@ phutil_register_library_map(array(
|
|||
'ManiphestTaskListController' => 'applications/maniphest/controller/ManiphestTaskListController.php',
|
||||
'ManiphestTaskListView' => 'applications/maniphest/view/ManiphestTaskListView.php',
|
||||
'ManiphestTaskMailReceiver' => 'applications/maniphest/mail/ManiphestTaskMailReceiver.php',
|
||||
'ManiphestTaskOpenStatusDatasource' => 'applications/maniphest/typeahead/ManiphestTaskOpenStatusDatasource.php',
|
||||
'ManiphestTaskOwner' => 'applications/maniphest/constants/ManiphestTaskOwner.php',
|
||||
'ManiphestTaskPHIDType' => 'applications/maniphest/phid/ManiphestTaskPHIDType.php',
|
||||
'ManiphestTaskPriority' => 'applications/maniphest/constants/ManiphestTaskPriority.php',
|
||||
|
@ -1064,6 +1066,7 @@ phutil_register_library_map(array(
|
|||
'ManiphestTaskSearchEngine' => 'applications/maniphest/query/ManiphestTaskSearchEngine.php',
|
||||
'ManiphestTaskStatus' => 'applications/maniphest/constants/ManiphestTaskStatus.php',
|
||||
'ManiphestTaskStatusDatasource' => 'applications/maniphest/typeahead/ManiphestTaskStatusDatasource.php',
|
||||
'ManiphestTaskStatusFunctionDatasource' => 'applications/maniphest/typeahead/ManiphestTaskStatusFunctionDatasource.php',
|
||||
'ManiphestTaskStatusTestCase' => 'applications/maniphest/constants/__tests__/ManiphestTaskStatusTestCase.php',
|
||||
'ManiphestTaskTestCase' => 'applications/maniphest/__tests__/ManiphestTaskTestCase.php',
|
||||
'ManiphestTransaction' => 'applications/maniphest/storage/ManiphestTransaction.php',
|
||||
|
@ -4335,6 +4338,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorApplicationTransactionInterface',
|
||||
'PhabricatorProjectInterface',
|
||||
),
|
||||
'ManiphestTaskClosedStatusDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||
'ManiphestTaskDependedOnByTaskEdgeType' => 'PhabricatorEdgeType',
|
||||
'ManiphestTaskDependsOnTaskEdgeType' => 'PhabricatorEdgeType',
|
||||
'ManiphestTaskDetailController' => 'ManiphestController',
|
||||
|
@ -4345,6 +4349,7 @@ phutil_register_library_map(array(
|
|||
'ManiphestTaskListController' => 'ManiphestController',
|
||||
'ManiphestTaskListView' => 'ManiphestView',
|
||||
'ManiphestTaskMailReceiver' => 'PhabricatorObjectMailReceiver',
|
||||
'ManiphestTaskOpenStatusDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||
'ManiphestTaskOwner' => 'ManiphestConstants',
|
||||
'ManiphestTaskPHIDType' => 'PhabricatorPHIDType',
|
||||
'ManiphestTaskPriority' => 'ManiphestConstants',
|
||||
|
@ -4354,6 +4359,7 @@ phutil_register_library_map(array(
|
|||
'ManiphestTaskSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'ManiphestTaskStatus' => 'ManiphestConstants',
|
||||
'ManiphestTaskStatusDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||
'ManiphestTaskStatusFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
|
||||
'ManiphestTaskStatusTestCase' => 'PhabricatorTestCase',
|
||||
'ManiphestTaskTestCase' => 'PhabricatorTestCase',
|
||||
'ManiphestTransaction' => 'PhabricatorApplicationTransaction',
|
||||
|
|
|
@ -139,7 +139,10 @@ final class ManiphestTaskSearchEngine
|
|||
$query->withOwners($assigned_phids);
|
||||
}
|
||||
|
||||
$datasource = id(new ManiphestTaskStatusFunctionDatasource())
|
||||
->setViewer($this->requireViewer());
|
||||
$statuses = $saved->getParameter('statuses');
|
||||
$statuses = $datasource->evaluateTokens($statuses);
|
||||
if ($statuses) {
|
||||
$query->withStatuses($statuses);
|
||||
}
|
||||
|
@ -274,7 +277,7 @@ final class ManiphestTaskSearchEngine
|
|||
->setValue($subscriber_phids))
|
||||
->appendControl(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setDatasource(new ManiphestTaskStatusDatasource())
|
||||
->setDatasource(new ManiphestTaskStatusFunctionDatasource())
|
||||
->setLabel(pht('Statuses'))
|
||||
->setName('statuses')
|
||||
->setValue($statuses))
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
|
||||
final class ManiphestTaskClosedStatusDatasource
|
||||
extends PhabricatorTypeaheadDatasource {
|
||||
|
||||
const FUNCTION_TOKEN = 'closed()';
|
||||
|
||||
public function getBrowseTitle() {
|
||||
return pht('Browse Any Closed Status');
|
||||
}
|
||||
|
||||
public function getPlaceholderText() {
|
||||
return pht('Type closed()...');
|
||||
}
|
||||
|
||||
public function getDatasourceApplicationClass() {
|
||||
return 'PhabricatorManiphestApplication';
|
||||
}
|
||||
|
||||
public function getDatasourceFunctions() {
|
||||
return array(
|
||||
'closed' => array(
|
||||
'name' => pht('Any Closed Status'),
|
||||
'summary' => pht('Find results with any closed status.'),
|
||||
'description' => pht(
|
||||
'This function includes results which have any closed status.'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
public function loadResults() {
|
||||
$results = array(
|
||||
$this->buildClosedResult(),
|
||||
);
|
||||
return $this->filterResultsAgainstTokens($results);
|
||||
}
|
||||
|
||||
protected function evaluateFunction($function, array $argv_list) {
|
||||
$results = array();
|
||||
|
||||
$map = ManiphestTaskStatus::getTaskStatusMap();
|
||||
foreach ($argv_list as $argv) {
|
||||
foreach ($map as $status => $name) {
|
||||
if (!ManiphestTaskStatus::isOpenStatus($status)) {
|
||||
$results[] = $status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
public function renderFunctionTokens($function, array $argv_list) {
|
||||
$results = array();
|
||||
|
||||
foreach ($argv_list as $argv) {
|
||||
$results[] = PhabricatorTypeaheadTokenView::newFromTypeaheadResult(
|
||||
$this->buildClosedResult());
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
private function buildClosedResult() {
|
||||
$name = pht('Any Closed Status');
|
||||
return $this->newFunctionResult()
|
||||
->setName($name.' closed')
|
||||
->setDisplayName($name)
|
||||
->setPHID(self::FUNCTION_TOKEN)
|
||||
->setUnique(true);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
|
||||
final class ManiphestTaskOpenStatusDatasource
|
||||
extends PhabricatorTypeaheadDatasource {
|
||||
|
||||
const FUNCTION_TOKEN = 'open()';
|
||||
|
||||
public function getBrowseTitle() {
|
||||
return pht('Browse Any Open Status');
|
||||
}
|
||||
|
||||
public function getPlaceholderText() {
|
||||
return pht('Type open()...');
|
||||
}
|
||||
|
||||
public function getDatasourceApplicationClass() {
|
||||
return 'PhabricatorManiphestApplication';
|
||||
}
|
||||
|
||||
public function getDatasourceFunctions() {
|
||||
return array(
|
||||
'open' => array(
|
||||
'name' => pht('Any Open Status'),
|
||||
'summary' => pht('Find results with any open status.'),
|
||||
'description' => pht(
|
||||
'This function includes results which have any open status.'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
public function loadResults() {
|
||||
$results = array(
|
||||
$this->buildOpenResult(),
|
||||
);
|
||||
return $this->filterResultsAgainstTokens($results);
|
||||
}
|
||||
|
||||
protected function evaluateFunction($function, array $argv_list) {
|
||||
$results = array();
|
||||
|
||||
$map = ManiphestTaskStatus::getTaskStatusMap();
|
||||
foreach ($argv_list as $argv) {
|
||||
foreach ($map as $status => $name) {
|
||||
if (ManiphestTaskStatus::isOpenStatus($status)) {
|
||||
$results[] = $status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
public function renderFunctionTokens($function, array $argv_list) {
|
||||
$results = array();
|
||||
|
||||
foreach ($argv_list as $argv) {
|
||||
$results[] = PhabricatorTypeaheadTokenView::newFromTypeaheadResult(
|
||||
$this->buildOpenResult());
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
private function buildOpenResult() {
|
||||
$name = pht('Any Open Status');
|
||||
return $this->newFunctionResult()
|
||||
->setName($name.' open')
|
||||
->setDisplayName($name)
|
||||
->setPHID(self::FUNCTION_TOKEN)
|
||||
->setUnique(true);
|
||||
}
|
||||
|
||||
}
|
|
@ -20,7 +20,8 @@ final class ManiphestTaskStatusDatasource
|
|||
return $this->filterResultsAgainstTokens($results);
|
||||
}
|
||||
|
||||
public function renderTokens(array $values) {
|
||||
|
||||
protected function renderSpecialTokens(array $values) {
|
||||
return $this->renderTokensFromResults($this->buildResults(), $values);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
final class ManiphestTaskStatusFunctionDatasource
|
||||
extends PhabricatorTypeaheadCompositeDatasource {
|
||||
|
||||
public function getBrowseTitle() {
|
||||
return pht('Browse Statuses');
|
||||
}
|
||||
|
||||
public function getPlaceholderText() {
|
||||
return pht('Type a task status name or function...');
|
||||
}
|
||||
|
||||
public function getComponentDatasources() {
|
||||
return array(
|
||||
new ManiphestTaskStatusDatasource(),
|
||||
new ManiphestTaskClosedStatusDatasource(),
|
||||
new ManiphestTaskOpenStatusDatasource(),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -15,6 +15,26 @@ final class PhabricatorViewerDatasource
|
|||
return 'PhabricatorPeopleApplication';
|
||||
}
|
||||
|
||||
public function getDatasourceFunctions() {
|
||||
return array(
|
||||
'viewer' => array(
|
||||
'name' => pht('Current Viewer'),
|
||||
'summary' => pht('Use the current viewing user.'),
|
||||
'description' => pht(
|
||||
'This function allows you to change the behavior of a query '.
|
||||
'based on who is running it. When you use this function, you will '.
|
||||
'be the current viewer, so it works like you typed your own '.
|
||||
'username.'.
|
||||
"\n\n".
|
||||
'However, if you save a query using this function and send it '.
|
||||
'to someone else, it will work like //their// username was the '.
|
||||
'one that was typed. This can be useful for building dashboard '.
|
||||
'panels that always show relevant information to the user who '.
|
||||
'is looking at them.'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
public function loadResults() {
|
||||
if ($this->getViewer()->getPHID()) {
|
||||
$results = array($this->renderViewerFunctionToken());
|
||||
|
@ -30,7 +50,7 @@ final class PhabricatorViewerDatasource
|
|||
return false;
|
||||
}
|
||||
|
||||
return ($function == 'viewer');
|
||||
return parent::canEvaluateFunction($function);
|
||||
}
|
||||
|
||||
protected function evaluateFunction($function, array $argv_list) {
|
||||
|
|
|
@ -162,5 +162,20 @@ abstract class PhabricatorTypeaheadCompositeDatasource
|
|||
return parent::renderFunctionTokens($function, $argv_list);
|
||||
}
|
||||
|
||||
protected function renderSpecialTokens(array $values) {
|
||||
$result = array();
|
||||
foreach ($this->getUsableDatasources() as $source) {
|
||||
$special = $source->renderSpecialTokens($values);
|
||||
foreach ($special as $key => $token) {
|
||||
$result[$key] = $token;
|
||||
unset($values[$key]);
|
||||
}
|
||||
if (!$values) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -229,6 +229,24 @@ abstract class PhabricatorTypeaheadDatasource extends Phobject {
|
|||
}
|
||||
}
|
||||
|
||||
// Give special non-function tokens which are also not PHIDs (like statuses
|
||||
// and priorities) an opportunity to render.
|
||||
$type_unknown = PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN;
|
||||
$special = array();
|
||||
foreach ($values as $key => $value) {
|
||||
if (phid_get_type($value) == $type_unknown) {
|
||||
$special[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
if ($special) {
|
||||
$special_tokens = $this->renderSpecialTokens($special);
|
||||
foreach ($special_tokens as $key => $token) {
|
||||
$tokens[$key] = $token;
|
||||
unset($phids[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($phids) {
|
||||
$handles = $this->getViewer()->loadHandles($phids);
|
||||
foreach ($phids as $key => $phid) {
|
||||
|
@ -265,6 +283,10 @@ abstract class PhabricatorTypeaheadDatasource extends Phobject {
|
|||
return array_select_keys($tokens, array_keys($values));
|
||||
}
|
||||
|
||||
protected function renderSpecialTokens(array $values) {
|
||||
return array();
|
||||
}
|
||||
|
||||
/* -( Token Functions )---------------------------------------------------- */
|
||||
|
||||
|
||||
|
@ -424,12 +446,13 @@ abstract class PhabricatorTypeaheadDatasource extends Phobject {
|
|||
}
|
||||
|
||||
protected function renderTokensFromResults(array $results, array $values) {
|
||||
$results = array_select_keys($results, $values);
|
||||
|
||||
$tokens = array();
|
||||
foreach ($results as $result) {
|
||||
$tokens[] = PhabricatorTypeaheadTokenView::newFromTypeaheadResult(
|
||||
$result);
|
||||
foreach ($values as $key => $value) {
|
||||
if (empty($results[$value])) {
|
||||
continue;
|
||||
}
|
||||
$tokens[$key] = PhabricatorTypeaheadTokenView::newFromTypeaheadResult(
|
||||
$results[$value]);
|
||||
}
|
||||
|
||||
return $tokens;
|
||||
|
|
Loading…
Reference in a new issue