mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-30 02:32:42 +01:00
Add a configuration option to put Asana tasks into Asana projects
Summary: Request from Asana. Adds an option for adding tasks to projects. Test Plan: Used `bin/feed republish` to create and update Asana tasks with projects configured. Saw them end up in the right projects. Reviewers: btrahan Reviewed By: btrahan CC: aran Differential Revision: https://secure.phabricator.com/D7655
This commit is contained in:
parent
b435c03eca
commit
325c8853c9
2 changed files with 94 additions and 0 deletions
|
@ -21,6 +21,16 @@ final class PhabricatorAsanaConfigOptions
|
|||
'ID here.'.
|
||||
"\n\n".
|
||||
"NOTE: This feature is new and experimental.")),
|
||||
$this->newOption('asana.project-ids', 'wild', null)
|
||||
->setSummary(pht("Optional Asana projects to use as application tags."))
|
||||
->setDescription(
|
||||
pht(
|
||||
'When Phabricator creates tasks in Asana, it can add the tasks '.
|
||||
'to Asana projects based on which application the corresponding '.
|
||||
'object in Phabricator comes from. For example, you can add code '.
|
||||
'reviews in Asana to a "Differential" project.'.
|
||||
"\n\n".
|
||||
'NOTE: This feature is new and experimental.'))
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -31,6 +41,8 @@ final class PhabricatorAsanaConfigOptions
|
|||
switch ($option->getKey()) {
|
||||
case 'asana.workspace-id':
|
||||
break;
|
||||
case 'asana.project-ids':
|
||||
return $this->renderContextualProjectDescription($option, $request);
|
||||
default:
|
||||
return parent::renderContextualDescription($option, $request);
|
||||
}
|
||||
|
@ -89,5 +101,48 @@ final class PhabricatorAsanaConfigOptions
|
|||
$viewer);
|
||||
}
|
||||
|
||||
private function renderContextualProjectDescription(
|
||||
PhabricatorConfigOption $option,
|
||||
AphrontRequest $request) {
|
||||
|
||||
$viewer = $request->getUser();
|
||||
|
||||
$publishers = id(new PhutilSymbolLoader())
|
||||
->setAncestorClass('DoorkeeperFeedStoryPublisher')
|
||||
->loadObjects();
|
||||
|
||||
$out = array();
|
||||
$out[] = pht(
|
||||
'To specify projects to add tasks to, enter a JSON map with publisher '.
|
||||
'class names as keys and a list of project IDs as values. For example, '.
|
||||
'to put Differential tasks into Asana projects with IDs `123` and '.
|
||||
'`456`, enter:'.
|
||||
"\n\n".
|
||||
" lang=txt\n".
|
||||
" {\n".
|
||||
" \"DifferentialDoorkeeperRevisionFeedStoryPublisher\" : [123, 456]\n".
|
||||
" }\n");
|
||||
|
||||
$out[] = pht('Available publishers class names are:');
|
||||
foreach ($publishers as $publisher) {
|
||||
$out[] = ' - `'.get_class($publisher).'`';
|
||||
}
|
||||
|
||||
$out[] = pht(
|
||||
'You can find an Asana project ID by clicking the project in Asana and '.
|
||||
'then examining the URL:'.
|
||||
"\n\n".
|
||||
" lang=txt\n".
|
||||
" https://app.asana.com/0/12345678901234567890/111111111111111111\n".
|
||||
" ^^^^^^^^^^^^^^^^^^^^\n".
|
||||
" This is the ID to use.\n");
|
||||
|
||||
$out = implode("\n", $out);
|
||||
|
||||
return PhabricatorMarkupEngine::renderOneObject(
|
||||
id(new PhabricatorMarkupOneOff())->setContent($out),
|
||||
'default',
|
||||
$viewer);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -110,6 +110,8 @@ final class DoorkeeperFeedWorkerAsana extends DoorkeeperFeedWorker {
|
|||
'assignee' => $owner_asana_id,
|
||||
);
|
||||
|
||||
$projects = $this->getAsanaProjectIDs();
|
||||
|
||||
$extra_data = array();
|
||||
if ($main_edge) {
|
||||
$extra_data = $main_edge['data'];
|
||||
|
@ -164,6 +166,7 @@ final class DoorkeeperFeedWorkerAsana extends DoorkeeperFeedWorker {
|
|||
'POST',
|
||||
array(
|
||||
'workspace' => $workspace_id,
|
||||
'projects' => $projects,
|
||||
// NOTE: We initially create parent tasks in the "Later" state but
|
||||
// don't update it afterward, even if the corresponding object
|
||||
// becomes actionable. The expectation is that users will prioritize
|
||||
|
@ -214,6 +217,9 @@ final class DoorkeeperFeedWorkerAsana extends DoorkeeperFeedWorker {
|
|||
if (empty($extra_data['gone'])) {
|
||||
$this->addFollowers($oauth_token, $task_id, $silent_followers, true);
|
||||
$this->addFollowers($oauth_token, $task_id, $noisy_followers);
|
||||
|
||||
// We're also going to synchronize project data here.
|
||||
$this->addProjects($oauth_token, $task_id, $projects);
|
||||
}
|
||||
|
||||
$dst_phid = $parent_ref->getExternalObject()->getPHID();
|
||||
|
@ -649,4 +655,37 @@ final class DoorkeeperFeedWorkerAsana extends DoorkeeperFeedWorker {
|
|||
$data);
|
||||
}
|
||||
|
||||
private function getAsanaProjectIDs() {
|
||||
$project_ids = array();
|
||||
|
||||
$publisher = $this->getPublisher();
|
||||
$config = PhabricatorEnv::getEnvConfig('asana.project-ids');
|
||||
if (is_array($config)) {
|
||||
$ids = idx($config, get_class($publisher));
|
||||
if (is_array($ids)) {
|
||||
foreach ($ids as $id) {
|
||||
if (is_scalar($id)) {
|
||||
$project_ids[] = $id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $project_ids;
|
||||
}
|
||||
|
||||
private function addProjects(
|
||||
$oauth_token,
|
||||
$task_id,
|
||||
array $project_ids) {
|
||||
foreach ($project_ids as $project_id) {
|
||||
$data = array('project' => $project_id);
|
||||
$this->makeAsanaAPICall(
|
||||
$oauth_token,
|
||||
"tasks/{$task_id}/addProject",
|
||||
'POST',
|
||||
$data);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue