mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 00:42:41 +01:00
Implement the "!priority" and "!status" mail commands
Summary: Ref T7199. Adds "!priority" and "!status". Test Plan: - Used `!priority` and `!status` to adjust tasks. - Changed config and provided keywords. {F355976} Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T7199 Differential Revision: https://secure.phabricator.com/D12248
This commit is contained in:
parent
be1fbba698
commit
52eab87608
6 changed files with 220 additions and 0 deletions
|
@ -1034,6 +1034,7 @@ phutil_register_library_map(array(
|
||||||
'ManiphestInfoConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestInfoConduitAPIMethod.php',
|
'ManiphestInfoConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestInfoConduitAPIMethod.php',
|
||||||
'ManiphestNameIndex' => 'applications/maniphest/storage/ManiphestNameIndex.php',
|
'ManiphestNameIndex' => 'applications/maniphest/storage/ManiphestNameIndex.php',
|
||||||
'ManiphestNameIndexEventListener' => 'applications/maniphest/event/ManiphestNameIndexEventListener.php',
|
'ManiphestNameIndexEventListener' => 'applications/maniphest/event/ManiphestNameIndexEventListener.php',
|
||||||
|
'ManiphestPriorityEmailCommand' => 'applications/maniphest/command/ManiphestPriorityEmailCommand.php',
|
||||||
'ManiphestQueryConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestQueryConduitAPIMethod.php',
|
'ManiphestQueryConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestQueryConduitAPIMethod.php',
|
||||||
'ManiphestQueryStatusesConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestQueryStatusesConduitAPIMethod.php',
|
'ManiphestQueryStatusesConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestQueryStatusesConduitAPIMethod.php',
|
||||||
'ManiphestRemarkupRule' => 'applications/maniphest/remarkup/ManiphestRemarkupRule.php',
|
'ManiphestRemarkupRule' => 'applications/maniphest/remarkup/ManiphestRemarkupRule.php',
|
||||||
|
@ -1042,6 +1043,7 @@ phutil_register_library_map(array(
|
||||||
'ManiphestSchemaSpec' => 'applications/maniphest/storage/ManiphestSchemaSpec.php',
|
'ManiphestSchemaSpec' => 'applications/maniphest/storage/ManiphestSchemaSpec.php',
|
||||||
'ManiphestSearchIndexer' => 'applications/maniphest/search/ManiphestSearchIndexer.php',
|
'ManiphestSearchIndexer' => 'applications/maniphest/search/ManiphestSearchIndexer.php',
|
||||||
'ManiphestStatusConfigOptionType' => 'applications/maniphest/config/ManiphestStatusConfigOptionType.php',
|
'ManiphestStatusConfigOptionType' => 'applications/maniphest/config/ManiphestStatusConfigOptionType.php',
|
||||||
|
'ManiphestStatusEmailCommand' => 'applications/maniphest/command/ManiphestStatusEmailCommand.php',
|
||||||
'ManiphestSubpriorityController' => 'applications/maniphest/controller/ManiphestSubpriorityController.php',
|
'ManiphestSubpriorityController' => 'applications/maniphest/controller/ManiphestSubpriorityController.php',
|
||||||
'ManiphestTask' => 'applications/maniphest/storage/ManiphestTask.php',
|
'ManiphestTask' => 'applications/maniphest/storage/ManiphestTask.php',
|
||||||
'ManiphestTaskDependedOnByTaskEdgeType' => 'applications/maniphest/edge/ManiphestTaskDependedOnByTaskEdgeType.php',
|
'ManiphestTaskDependedOnByTaskEdgeType' => 'applications/maniphest/edge/ManiphestTaskDependedOnByTaskEdgeType.php',
|
||||||
|
@ -4284,6 +4286,7 @@ phutil_register_library_map(array(
|
||||||
'ManiphestInfoConduitAPIMethod' => 'ManiphestConduitAPIMethod',
|
'ManiphestInfoConduitAPIMethod' => 'ManiphestConduitAPIMethod',
|
||||||
'ManiphestNameIndex' => 'ManiphestDAO',
|
'ManiphestNameIndex' => 'ManiphestDAO',
|
||||||
'ManiphestNameIndexEventListener' => 'PhabricatorEventListener',
|
'ManiphestNameIndexEventListener' => 'PhabricatorEventListener',
|
||||||
|
'ManiphestPriorityEmailCommand' => 'ManiphestEmailCommand',
|
||||||
'ManiphestQueryConduitAPIMethod' => 'ManiphestConduitAPIMethod',
|
'ManiphestQueryConduitAPIMethod' => 'ManiphestConduitAPIMethod',
|
||||||
'ManiphestQueryStatusesConduitAPIMethod' => 'ManiphestConduitAPIMethod',
|
'ManiphestQueryStatusesConduitAPIMethod' => 'ManiphestConduitAPIMethod',
|
||||||
'ManiphestRemarkupRule' => 'PhabricatorObjectRemarkupRule',
|
'ManiphestRemarkupRule' => 'PhabricatorObjectRemarkupRule',
|
||||||
|
@ -4292,6 +4295,7 @@ phutil_register_library_map(array(
|
||||||
'ManiphestSchemaSpec' => 'PhabricatorConfigSchemaSpec',
|
'ManiphestSchemaSpec' => 'PhabricatorConfigSchemaSpec',
|
||||||
'ManiphestSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
|
'ManiphestSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
|
||||||
'ManiphestStatusConfigOptionType' => 'PhabricatorConfigJSONOptionType',
|
'ManiphestStatusConfigOptionType' => 'PhabricatorConfigJSONOptionType',
|
||||||
|
'ManiphestStatusEmailCommand' => 'ManiphestEmailCommand',
|
||||||
'ManiphestSubpriorityController' => 'ManiphestController',
|
'ManiphestSubpriorityController' => 'ManiphestController',
|
||||||
'ManiphestTask' => array(
|
'ManiphestTask' => array(
|
||||||
'ManiphestDAO',
|
'ManiphestDAO',
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class ManiphestPriorityEmailCommand
|
||||||
|
extends ManiphestEmailCommand {
|
||||||
|
|
||||||
|
public function getCommand() {
|
||||||
|
return 'priority';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCommandSyntax() {
|
||||||
|
return '**!priority** //priority//';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCommandSummary() {
|
||||||
|
return pht('Change the priority of a task.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCommandDescription() {
|
||||||
|
$names = ManiphestTaskPriority::getTaskPriorityMap();
|
||||||
|
$keywords = ManiphestTaskPriority::getTaskPriorityKeywordsMap();
|
||||||
|
|
||||||
|
$table = array();
|
||||||
|
$table[] = '| '.pht('Priority').' | '.pht('Keywords');
|
||||||
|
$table[] = '|---|---|';
|
||||||
|
foreach ($keywords as $priority => $words) {
|
||||||
|
$words = implode(', ', $words);
|
||||||
|
$table[] = '| '.$names[$priority].' | '.$words;
|
||||||
|
}
|
||||||
|
$table = implode("\n", $table);
|
||||||
|
|
||||||
|
return pht(
|
||||||
|
'To change the priority of a task, specify the desired priority, like '.
|
||||||
|
'`!priority high`. This table shows the configured names for priority '.
|
||||||
|
'levels.'.
|
||||||
|
"\n\n%s\n\n".
|
||||||
|
'If you specify an invalid priority, the command is ignored. This '.
|
||||||
|
'command has no effect if you do not specify a priority.',
|
||||||
|
$table);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildTransactions(
|
||||||
|
PhabricatorUser $viewer,
|
||||||
|
PhabricatorApplicationTransactionInterface $object,
|
||||||
|
PhabricatorMetaMTAReceivedMail $mail,
|
||||||
|
$command,
|
||||||
|
array $argv) {
|
||||||
|
$xactions = array();
|
||||||
|
|
||||||
|
$target = phutil_utf8_strtolower(head($argv));
|
||||||
|
$priority = null;
|
||||||
|
|
||||||
|
$keywords = ManiphestTaskPriority::getTaskPriorityKeywordsMap();
|
||||||
|
foreach ($keywords as $key => $words) {
|
||||||
|
foreach ($words as $word) {
|
||||||
|
if ($word == $target) {
|
||||||
|
$priority = $key;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($priority === null) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$xactions[] = $object->getApplicationTransactionTemplate()
|
||||||
|
->setTransactionType(ManiphestTransaction::TYPE_PRIORITY)
|
||||||
|
->setNewValue($priority);
|
||||||
|
|
||||||
|
return $xactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class ManiphestStatusEmailCommand
|
||||||
|
extends ManiphestEmailCommand {
|
||||||
|
|
||||||
|
public function getCommand() {
|
||||||
|
return 'status';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCommandSyntax() {
|
||||||
|
return '**!status** //status//';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCommandSummary() {
|
||||||
|
return pht('Change the status of a task.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCommandDescription() {
|
||||||
|
$names = ManiphestTaskStatus::getTaskStatusMap();
|
||||||
|
$keywords = ManiphestTaskStatus::getTaskStatusKeywordsMap();
|
||||||
|
|
||||||
|
$table = array();
|
||||||
|
$table[] = '| '.pht('Status').' | '.pht('Keywords');
|
||||||
|
$table[] = '|---|---|';
|
||||||
|
foreach ($keywords as $status => $words) {
|
||||||
|
$words = implode(', ', $words);
|
||||||
|
$table[] = '| '.$names[$status].' | '.$words;
|
||||||
|
}
|
||||||
|
$table = implode("\n", $table);
|
||||||
|
|
||||||
|
return pht(
|
||||||
|
'To change the status of a task, specify the desired status, like '.
|
||||||
|
'`!status invalid`. This table shows the configured names for statuses.'.
|
||||||
|
"\n\n%s\n\n".
|
||||||
|
'If you specify an invalid status, the command is ignored. This '.
|
||||||
|
'command has no effect if you do not specify a status.',
|
||||||
|
$table);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildTransactions(
|
||||||
|
PhabricatorUser $viewer,
|
||||||
|
PhabricatorApplicationTransactionInterface $object,
|
||||||
|
PhabricatorMetaMTAReceivedMail $mail,
|
||||||
|
$command,
|
||||||
|
array $argv) {
|
||||||
|
$xactions = array();
|
||||||
|
|
||||||
|
$target = phutil_utf8_strtolower(head($argv));
|
||||||
|
$status = null;
|
||||||
|
|
||||||
|
$keywords = ManiphestTaskStatus::getTaskStatusKeywordsMap();
|
||||||
|
foreach ($keywords as $key => $words) {
|
||||||
|
foreach ($words as $word) {
|
||||||
|
if ($word == $target) {
|
||||||
|
$status = $key;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($status === null) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$xactions[] = $object->getApplicationTransactionTemplate()
|
||||||
|
->setTransactionType(ManiphestTransaction::TYPE_STATUS)
|
||||||
|
->setNewValue($status);
|
||||||
|
|
||||||
|
return $xactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -26,31 +26,37 @@ final class PhabricatorManiphestConfigOptions
|
||||||
'name' => pht('Unbreak Now!'),
|
'name' => pht('Unbreak Now!'),
|
||||||
'short' => pht('Unbreak!'),
|
'short' => pht('Unbreak!'),
|
||||||
'color' => 'indigo',
|
'color' => 'indigo',
|
||||||
|
'keywords' => array('unbreak'),
|
||||||
),
|
),
|
||||||
90 => array(
|
90 => array(
|
||||||
'name' => pht('Needs Triage'),
|
'name' => pht('Needs Triage'),
|
||||||
'short' => pht('Triage'),
|
'short' => pht('Triage'),
|
||||||
'color' => 'violet',
|
'color' => 'violet',
|
||||||
|
'keywords' => array('triage'),
|
||||||
),
|
),
|
||||||
80 => array(
|
80 => array(
|
||||||
'name' => pht('High'),
|
'name' => pht('High'),
|
||||||
'short' => pht('High'),
|
'short' => pht('High'),
|
||||||
'color' => 'red',
|
'color' => 'red',
|
||||||
|
'keywords' => array('high'),
|
||||||
),
|
),
|
||||||
50 => array(
|
50 => array(
|
||||||
'name' => pht('Normal'),
|
'name' => pht('Normal'),
|
||||||
'short' => pht('Normal'),
|
'short' => pht('Normal'),
|
||||||
'color' => 'orange',
|
'color' => 'orange',
|
||||||
|
'keywords' => array('normal'),
|
||||||
),
|
),
|
||||||
25 => array(
|
25 => array(
|
||||||
'name' => pht('Low'),
|
'name' => pht('Low'),
|
||||||
'short' => pht('Low'),
|
'short' => pht('Low'),
|
||||||
'color' => 'yellow',
|
'color' => 'yellow',
|
||||||
|
'keywords' => array('low'),
|
||||||
),
|
),
|
||||||
0 => array(
|
0 => array(
|
||||||
'name' => pht('Wishlist'),
|
'name' => pht('Wishlist'),
|
||||||
'short' => pht('Wish'),
|
'short' => pht('Wish'),
|
||||||
'color' => 'sky',
|
'color' => 'sky',
|
||||||
|
'keywords' => array('wish', 'wishlist'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -80,6 +86,7 @@ final class PhabricatorManiphestConfigOptions
|
||||||
'as resolved',
|
'as resolved',
|
||||||
'as fixed',
|
'as fixed',
|
||||||
),
|
),
|
||||||
|
'keywords' => array('closed', 'fixed', 'resolved'),
|
||||||
),
|
),
|
||||||
'wontfix' => array(
|
'wontfix' => array(
|
||||||
'name' => pht('Wontfix'),
|
'name' => pht('Wontfix'),
|
||||||
|
@ -182,6 +189,9 @@ The keys you can provide in a specification are:
|
||||||
providing "as invalid" here will allow users to move tasks
|
providing "as invalid" here will allow users to move tasks
|
||||||
to this status by writing `Closes T123 as invalid`, even if another status
|
to this status by writing `Closes T123 as invalid`, even if another status
|
||||||
is selected by the "Closes" prefix.
|
is selected by the "Closes" prefix.
|
||||||
|
- `keywords` //Optional list<string>.// Allows you to specify a list
|
||||||
|
of keywords which can be used with `!status` commands in email to select
|
||||||
|
this status.
|
||||||
|
|
||||||
Statuses will appear in the UI in the order specified. Note the status marked
|
Statuses will appear in the UI in the order specified. Note the status marked
|
||||||
`special` as `duplicate` is not settable directly and will not appear in UI
|
`special` as `duplicate` is not settable directly and will not appear in UI
|
||||||
|
@ -257,6 +267,9 @@ EOTEXT
|
||||||
' - `short` Alternate shorter name, used in UIs where there is '.
|
' - `short` Alternate shorter name, used in UIs where there is '.
|
||||||
' not much space available.'."\n".
|
' not much space available.'."\n".
|
||||||
' - `color` A color for this priority, like "red" or "blue".'.
|
' - `color` A color for this priority, like "red" or "blue".'.
|
||||||
|
' - `keywords` An optional list of keywords which can '.
|
||||||
|
' be used to select this priority when using `!priority` '.
|
||||||
|
' commands in email.'.
|
||||||
"\n\n".
|
"\n\n".
|
||||||
'You can choose which priority is the default for newly created '.
|
'You can choose which priority is the default for newly created '.
|
||||||
'tasks with `maniphest.default-priority`.')),
|
'tasks with `maniphest.default-priority`.')),
|
||||||
|
|
|
@ -16,6 +16,32 @@ final class ManiphestTaskPriority extends ManiphestConstants {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the priorities and their command keywords.
|
||||||
|
*
|
||||||
|
* @return map Priorities to lists of command keywords.
|
||||||
|
*/
|
||||||
|
public static function getTaskPriorityKeywordsMap() {
|
||||||
|
$map = self::getConfig();
|
||||||
|
foreach ($map as $key => $spec) {
|
||||||
|
$words = idx($spec, 'keywords', array());
|
||||||
|
if (!is_array($words)) {
|
||||||
|
$words = array($words);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($words as $word_key => $word) {
|
||||||
|
$words[$word_key] = phutil_utf8_strtolower($word);
|
||||||
|
}
|
||||||
|
|
||||||
|
$words = array_unique($words);
|
||||||
|
|
||||||
|
$map[$key] = $words;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $map;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the priorities and their related short (one-word) descriptions.
|
* Get the priorities and their related short (one-word) descriptions.
|
||||||
*
|
*
|
||||||
|
|
|
@ -38,6 +38,37 @@ final class ManiphestTaskStatus extends ManiphestConstants {
|
||||||
return ipull(self::getEnabledStatusMap(), 'name');
|
return ipull(self::getEnabledStatusMap(), 'name');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the statuses and their command keywords.
|
||||||
|
*
|
||||||
|
* @return map Statuses to lists of command keywords.
|
||||||
|
*/
|
||||||
|
public static function getTaskStatusKeywordsMap() {
|
||||||
|
$map = self::getEnabledStatusMap();
|
||||||
|
foreach ($map as $key => $spec) {
|
||||||
|
$words = idx($spec, 'keywords', array());
|
||||||
|
if (!is_array($words)) {
|
||||||
|
$words = array($words);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For statuses, we include the status name because it's usually
|
||||||
|
// at least somewhat meaningful.
|
||||||
|
$words[] = $key;
|
||||||
|
|
||||||
|
foreach ($words as $word_key => $word) {
|
||||||
|
$words[$word_key] = phutil_utf8_strtolower($word);
|
||||||
|
}
|
||||||
|
|
||||||
|
$words = array_unique($words);
|
||||||
|
|
||||||
|
$map[$key] = $words;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $map;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static function getTaskStatusName($status) {
|
public static function getTaskStatusName($status) {
|
||||||
return self::getStatusAttribute($status, 'name', pht('Unknown Status'));
|
return self::getStatusAttribute($status, 'name', pht('Unknown Status'));
|
||||||
}
|
}
|
||||||
|
@ -231,6 +262,7 @@ final class ManiphestTaskStatus extends ManiphestConstants {
|
||||||
'silly' => 'optional bool',
|
'silly' => 'optional bool',
|
||||||
'prefixes' => 'optional list<string>',
|
'prefixes' => 'optional list<string>',
|
||||||
'suffixes' => 'optional list<string>',
|
'suffixes' => 'optional list<string>',
|
||||||
|
'keywords' => 'optional list<string>',
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue