mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-18 19:40:55 +01:00
Modularize "add projects" and "remove projects" Herald actions
Summary: Ref T8726. Convert these to be modular. Test Plan: - Created rules using these actions. - Upgraded them. - Verified they still work. {F659266} Reviewers: btrahan Reviewed By: btrahan Subscribers: joshuaspence, epriestley Maniphest Tasks: T8726 Differential Revision: https://secure.phabricator.com/D13705
This commit is contained in:
parent
51fead17cf
commit
3782992670
7 changed files with 273 additions and 58 deletions
11
resources/sql/autopatches/20150724.herald.3.sql
Normal file
11
resources/sql/autopatches/20150724.herald.3.sql
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
UPDATE {$NAMESPACE}_herald.herald_actionrecord a
|
||||||
|
JOIN {$NAMESPACE}_herald.herald_rule r
|
||||||
|
ON a.ruleID = r.id
|
||||||
|
SET a.action = 'projects.add'
|
||||||
|
WHERE a.action = 'addprojects';
|
||||||
|
|
||||||
|
UPDATE {$NAMESPACE}_herald.herald_actionrecord a
|
||||||
|
JOIN {$NAMESPACE}_herald.herald_rule r
|
||||||
|
ON a.ruleID = r.id
|
||||||
|
SET a.action = 'projects.remove'
|
||||||
|
WHERE a.action = 'removeprojects';
|
|
@ -2540,6 +2540,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorPolicyType' => 'applications/policy/constants/PhabricatorPolicyType.php',
|
'PhabricatorPolicyType' => 'applications/policy/constants/PhabricatorPolicyType.php',
|
||||||
'PhabricatorPonderApplication' => 'applications/ponder/application/PhabricatorPonderApplication.php',
|
'PhabricatorPonderApplication' => 'applications/ponder/application/PhabricatorPonderApplication.php',
|
||||||
'PhabricatorProject' => 'applications/project/storage/PhabricatorProject.php',
|
'PhabricatorProject' => 'applications/project/storage/PhabricatorProject.php',
|
||||||
|
'PhabricatorProjectAddHeraldAction' => 'applications/project/herald/PhabricatorProjectAddHeraldAction.php',
|
||||||
'PhabricatorProjectApplication' => 'applications/project/application/PhabricatorProjectApplication.php',
|
'PhabricatorProjectApplication' => 'applications/project/application/PhabricatorProjectApplication.php',
|
||||||
'PhabricatorProjectArchiveController' => 'applications/project/controller/PhabricatorProjectArchiveController.php',
|
'PhabricatorProjectArchiveController' => 'applications/project/controller/PhabricatorProjectArchiveController.php',
|
||||||
'PhabricatorProjectBoardController' => 'applications/project/controller/PhabricatorProjectBoardController.php',
|
'PhabricatorProjectBoardController' => 'applications/project/controller/PhabricatorProjectBoardController.php',
|
||||||
|
@ -2572,6 +2573,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorProjectEditPictureController' => 'applications/project/controller/PhabricatorProjectEditPictureController.php',
|
'PhabricatorProjectEditPictureController' => 'applications/project/controller/PhabricatorProjectEditPictureController.php',
|
||||||
'PhabricatorProjectEditorTestCase' => 'applications/project/editor/__tests__/PhabricatorProjectEditorTestCase.php',
|
'PhabricatorProjectEditorTestCase' => 'applications/project/editor/__tests__/PhabricatorProjectEditorTestCase.php',
|
||||||
'PhabricatorProjectFeedController' => 'applications/project/controller/PhabricatorProjectFeedController.php',
|
'PhabricatorProjectFeedController' => 'applications/project/controller/PhabricatorProjectFeedController.php',
|
||||||
|
'PhabricatorProjectHeraldAction' => 'applications/project/herald/PhabricatorProjectHeraldAction.php',
|
||||||
'PhabricatorProjectIcon' => 'applications/project/icon/PhabricatorProjectIcon.php',
|
'PhabricatorProjectIcon' => 'applications/project/icon/PhabricatorProjectIcon.php',
|
||||||
'PhabricatorProjectInterface' => 'applications/project/interface/PhabricatorProjectInterface.php',
|
'PhabricatorProjectInterface' => 'applications/project/interface/PhabricatorProjectInterface.php',
|
||||||
'PhabricatorProjectListController' => 'applications/project/controller/PhabricatorProjectListController.php',
|
'PhabricatorProjectListController' => 'applications/project/controller/PhabricatorProjectListController.php',
|
||||||
|
@ -2593,6 +2595,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorProjectProjectHasObjectEdgeType' => 'applications/project/edge/PhabricatorProjectProjectHasObjectEdgeType.php',
|
'PhabricatorProjectProjectHasObjectEdgeType' => 'applications/project/edge/PhabricatorProjectProjectHasObjectEdgeType.php',
|
||||||
'PhabricatorProjectProjectPHIDType' => 'applications/project/phid/PhabricatorProjectProjectPHIDType.php',
|
'PhabricatorProjectProjectPHIDType' => 'applications/project/phid/PhabricatorProjectProjectPHIDType.php',
|
||||||
'PhabricatorProjectQuery' => 'applications/project/query/PhabricatorProjectQuery.php',
|
'PhabricatorProjectQuery' => 'applications/project/query/PhabricatorProjectQuery.php',
|
||||||
|
'PhabricatorProjectRemoveHeraldAction' => 'applications/project/herald/PhabricatorProjectRemoveHeraldAction.php',
|
||||||
'PhabricatorProjectSchemaSpec' => 'applications/project/storage/PhabricatorProjectSchemaSpec.php',
|
'PhabricatorProjectSchemaSpec' => 'applications/project/storage/PhabricatorProjectSchemaSpec.php',
|
||||||
'PhabricatorProjectSearchEngine' => 'applications/project/query/PhabricatorProjectSearchEngine.php',
|
'PhabricatorProjectSearchEngine' => 'applications/project/query/PhabricatorProjectSearchEngine.php',
|
||||||
'PhabricatorProjectSearchField' => 'applications/project/searchfield/PhabricatorProjectSearchField.php',
|
'PhabricatorProjectSearchField' => 'applications/project/searchfield/PhabricatorProjectSearchField.php',
|
||||||
|
@ -6496,6 +6499,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorCustomFieldInterface',
|
'PhabricatorCustomFieldInterface',
|
||||||
'PhabricatorDestructibleInterface',
|
'PhabricatorDestructibleInterface',
|
||||||
),
|
),
|
||||||
|
'PhabricatorProjectAddHeraldAction' => 'PhabricatorProjectHeraldAction',
|
||||||
'PhabricatorProjectApplication' => 'PhabricatorApplication',
|
'PhabricatorProjectApplication' => 'PhabricatorApplication',
|
||||||
'PhabricatorProjectArchiveController' => 'PhabricatorProjectController',
|
'PhabricatorProjectArchiveController' => 'PhabricatorProjectController',
|
||||||
'PhabricatorProjectBoardController' => 'PhabricatorProjectController',
|
'PhabricatorProjectBoardController' => 'PhabricatorProjectController',
|
||||||
|
@ -6539,6 +6543,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorProjectEditPictureController' => 'PhabricatorProjectController',
|
'PhabricatorProjectEditPictureController' => 'PhabricatorProjectController',
|
||||||
'PhabricatorProjectEditorTestCase' => 'PhabricatorTestCase',
|
'PhabricatorProjectEditorTestCase' => 'PhabricatorTestCase',
|
||||||
'PhabricatorProjectFeedController' => 'PhabricatorProjectController',
|
'PhabricatorProjectFeedController' => 'PhabricatorProjectController',
|
||||||
|
'PhabricatorProjectHeraldAction' => 'HeraldAction',
|
||||||
'PhabricatorProjectIcon' => 'Phobject',
|
'PhabricatorProjectIcon' => 'Phobject',
|
||||||
'PhabricatorProjectListController' => 'PhabricatorProjectController',
|
'PhabricatorProjectListController' => 'PhabricatorProjectController',
|
||||||
'PhabricatorProjectLogicalAndDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
|
'PhabricatorProjectLogicalAndDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
|
||||||
|
@ -6559,6 +6564,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorProjectProjectHasObjectEdgeType' => 'PhabricatorEdgeType',
|
'PhabricatorProjectProjectHasObjectEdgeType' => 'PhabricatorEdgeType',
|
||||||
'PhabricatorProjectProjectPHIDType' => 'PhabricatorPHIDType',
|
'PhabricatorProjectProjectPHIDType' => 'PhabricatorPHIDType',
|
||||||
'PhabricatorProjectQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhabricatorProjectQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
|
'PhabricatorProjectRemoveHeraldAction' => 'PhabricatorProjectHeraldAction',
|
||||||
'PhabricatorProjectSchemaSpec' => 'PhabricatorConfigSchemaSpec',
|
'PhabricatorProjectSchemaSpec' => 'PhabricatorConfigSchemaSpec',
|
||||||
'PhabricatorProjectSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
'PhabricatorProjectSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||||
'PhabricatorProjectSearchField' => 'PhabricatorSearchTokenizerField',
|
'PhabricatorProjectSearchField' => 'PhabricatorSearchTokenizerField',
|
||||||
|
|
|
@ -28,8 +28,6 @@ abstract class HeraldAdapter extends Phobject {
|
||||||
|
|
||||||
const ACTION_AUDIT = 'audit';
|
const ACTION_AUDIT = 'audit';
|
||||||
const ACTION_ASSIGN_TASK = 'assigntask';
|
const ACTION_ASSIGN_TASK = 'assigntask';
|
||||||
const ACTION_ADD_PROJECTS = 'addprojects';
|
|
||||||
const ACTION_REMOVE_PROJECTS = 'removeprojects';
|
|
||||||
const ACTION_ADD_REVIEWERS = 'addreviewers';
|
const ACTION_ADD_REVIEWERS = 'addreviewers';
|
||||||
const ACTION_ADD_BLOCKING_REVIEWERS = 'addblockingreviewers';
|
const ACTION_ADD_BLOCKING_REVIEWERS = 'addblockingreviewers';
|
||||||
const ACTION_APPLY_BUILD_PLANS = 'applybuildplans';
|
const ACTION_APPLY_BUILD_PLANS = 'applybuildplans';
|
||||||
|
@ -707,15 +705,6 @@ abstract class HeraldAdapter extends Phobject {
|
||||||
|
|
||||||
$actions = $custom_actions;
|
$actions = $custom_actions;
|
||||||
|
|
||||||
$object = $this->newObject();
|
|
||||||
|
|
||||||
if (($object instanceof PhabricatorProjectInterface)) {
|
|
||||||
if ($rule_type == HeraldRuleTypeConfig::RULE_TYPE_GLOBAL) {
|
|
||||||
$actions[] = self::ACTION_ADD_PROJECTS;
|
|
||||||
$actions[] = self::ACTION_REMOVE_PROJECTS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($this->getActionsForRuleType($rule_type) as $key => $action) {
|
foreach ($this->getActionsForRuleType($rule_type) as $key => $action) {
|
||||||
$actions[] = $key;
|
$actions[] = $key;
|
||||||
}
|
}
|
||||||
|
@ -730,8 +719,6 @@ abstract class HeraldAdapter extends Phobject {
|
||||||
$standard = array(
|
$standard = array(
|
||||||
self::ACTION_AUDIT => pht('Trigger an Audit by'),
|
self::ACTION_AUDIT => pht('Trigger an Audit by'),
|
||||||
self::ACTION_ASSIGN_TASK => pht('Assign task to'),
|
self::ACTION_ASSIGN_TASK => pht('Assign task to'),
|
||||||
self::ACTION_ADD_PROJECTS => pht('Add projects'),
|
|
||||||
self::ACTION_REMOVE_PROJECTS => pht('Remove projects'),
|
|
||||||
self::ACTION_ADD_REVIEWERS => pht('Add reviewers'),
|
self::ACTION_ADD_REVIEWERS => pht('Add reviewers'),
|
||||||
self::ACTION_ADD_BLOCKING_REVIEWERS => pht('Add blocking reviewers'),
|
self::ACTION_ADD_BLOCKING_REVIEWERS => pht('Add blocking reviewers'),
|
||||||
self::ACTION_APPLY_BUILD_PLANS => pht('Run build plans'),
|
self::ACTION_APPLY_BUILD_PLANS => pht('Run build plans'),
|
||||||
|
@ -829,17 +816,9 @@ abstract class HeraldAdapter extends Phobject {
|
||||||
case self::ACTION_ADD_REVIEWERS:
|
case self::ACTION_ADD_REVIEWERS:
|
||||||
case self::ACTION_ADD_BLOCKING_REVIEWERS:
|
case self::ACTION_ADD_BLOCKING_REVIEWERS:
|
||||||
return new HeraldEmptyFieldValue();
|
return new HeraldEmptyFieldValue();
|
||||||
case self::ACTION_ADD_PROJECTS:
|
|
||||||
case self::ACTION_REMOVE_PROJECTS:
|
|
||||||
return $this->buildTokenizerFieldValue(
|
|
||||||
new PhabricatorProjectDatasource());
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch ($action) {
|
switch ($action) {
|
||||||
case self::ACTION_ADD_PROJECTS:
|
|
||||||
case self::ACTION_REMOVE_PROJECTS:
|
|
||||||
return $this->buildTokenizerFieldValue(
|
|
||||||
new PhabricatorProjectDatasource());
|
|
||||||
case self::ACTION_ASSIGN_TASK:
|
case self::ACTION_ASSIGN_TASK:
|
||||||
return $this->buildTokenizerFieldValue(
|
return $this->buildTokenizerFieldValue(
|
||||||
new PhabricatorPeopleDatasource());
|
new PhabricatorPeopleDatasource());
|
||||||
|
@ -1200,14 +1179,6 @@ abstract class HeraldAdapter extends Phobject {
|
||||||
$rule_type));
|
$rule_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ($action) {
|
|
||||||
case self::ACTION_ADD_PROJECTS:
|
|
||||||
case self::ACTION_REMOVE_PROJECTS:
|
|
||||||
return $this->applyProjectsEffect($effect);
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = $this->handleCustomHeraldEffect($effect);
|
$result = $this->handleCustomHeraldEffect($effect);
|
||||||
|
|
||||||
if (!$result) {
|
if (!$result) {
|
||||||
|
@ -1222,35 +1193,6 @@ abstract class HeraldAdapter extends Phobject {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @task apply
|
|
||||||
*/
|
|
||||||
private function applyProjectsEffect(HeraldEffect $effect) {
|
|
||||||
|
|
||||||
if ($effect->getAction() == self::ACTION_ADD_PROJECTS) {
|
|
||||||
$kind = '+';
|
|
||||||
} else {
|
|
||||||
$kind = '-';
|
|
||||||
}
|
|
||||||
|
|
||||||
$project_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
|
|
||||||
$project_phids = $effect->getTarget();
|
|
||||||
$xaction = $this->newTransaction()
|
|
||||||
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
|
|
||||||
->setMetadataValue('edge:type', $project_type)
|
|
||||||
->setNewValue(
|
|
||||||
array(
|
|
||||||
$kind => array_fuse($project_phids),
|
|
||||||
));
|
|
||||||
|
|
||||||
$this->queueTransaction($xaction);
|
|
||||||
|
|
||||||
return new HeraldApplyTranscript(
|
|
||||||
$effect,
|
|
||||||
true,
|
|
||||||
pht('Added projects.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function loadEdgePHIDs($type) {
|
public function loadEdgePHIDs($type) {
|
||||||
if (!isset($this->edgeCache[$type])) {
|
if (!isset($this->edgeCache[$type])) {
|
||||||
$phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
|
$phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorProjectAddHeraldAction
|
||||||
|
extends PhabricatorProjectHeraldAction {
|
||||||
|
|
||||||
|
const ACTIONCONST = 'projects.add';
|
||||||
|
|
||||||
|
public function getHeraldActionName() {
|
||||||
|
return pht('Add projects');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function applyEffect($object, HeraldEffect $effect) {
|
||||||
|
return $this->applyProjects($effect->getTarget(), $is_add = true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHeraldActionStandardType() {
|
||||||
|
return self::STANDARD_PHID_LIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getDatasource() {
|
||||||
|
return new PhabricatorProjectDatasource();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderActionDescription($value) {
|
||||||
|
return pht('Add projects: %s.', $this->renderHandleList($value));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,180 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
abstract class PhabricatorProjectHeraldAction
|
||||||
|
extends HeraldAction {
|
||||||
|
|
||||||
|
const DO_NO_TARGETS = 'do.no-targets';
|
||||||
|
const DO_INVALID = 'do.invalid';
|
||||||
|
const DO_ALREADY_ASSOCIATED = 'do.already-associated';
|
||||||
|
const DO_ALREADY_UNASSOCIATED = 'do.already-unassociated';
|
||||||
|
const DO_ADD_PROJECTS = 'do.add-projects';
|
||||||
|
const DO_REMOVE_PROJECTS = 'do.remove-projects';
|
||||||
|
|
||||||
|
public function getActionGroupKey() {
|
||||||
|
return HeraldSupportActionGroup::ACTIONGROUPKEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function supportsObject($object) {
|
||||||
|
return ($object instanceof PhabricatorProjectInterface);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function supportsRuleType($rule_type) {
|
||||||
|
return ($rule_type == HeraldRuleTypeConfig::RULE_TYPE_GLOBAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function applyProjects(array $phids, $is_add) {
|
||||||
|
$phids = array_fuse($phids);
|
||||||
|
$adapter = $this->getAdapter();
|
||||||
|
|
||||||
|
if (!$phids) {
|
||||||
|
$this->logEffect(self::DO_NO_TARGETS);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$projects = id(new PhabricatorProjectQuery())
|
||||||
|
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||||
|
->withPHIDs($phids)
|
||||||
|
->execute();
|
||||||
|
$projects = mpull($projects, null, 'getPHID');
|
||||||
|
|
||||||
|
$invalid = array();
|
||||||
|
foreach ($phids as $phid) {
|
||||||
|
if (empty($projects[$phid])) {
|
||||||
|
$invalid[] = $phid;
|
||||||
|
unset($phids[$phid]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($invalid) {
|
||||||
|
$this->logEffect(self::DO_INVALID, $invalid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$phids) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$project_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
|
||||||
|
|
||||||
|
$current = $adapter->loadEdgePHIDs($project_type);
|
||||||
|
|
||||||
|
if ($is_add) {
|
||||||
|
$already = array();
|
||||||
|
foreach ($phids as $phid) {
|
||||||
|
if (isset($current[$phid])) {
|
||||||
|
$already[$phid] = $phid;
|
||||||
|
unset($phids[$phid]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($already) {
|
||||||
|
$this->logEffect(self::DO_ALREADY_ASSOCIATED, $already);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$already = array();
|
||||||
|
foreach ($phids as $phid) {
|
||||||
|
if (empty($current[$phid])) {
|
||||||
|
$already[$phid] = $phid;
|
||||||
|
unset($phids[$phid]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($already) {
|
||||||
|
$this->logEffect(self::DO_ALREADY_UNASSOCIATED, $already);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$phids) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($is_add) {
|
||||||
|
$kind = '+';
|
||||||
|
} else {
|
||||||
|
$kind = '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
$xaction = $adapter->newTransaction()
|
||||||
|
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
|
||||||
|
->setMetadataValue('edge:type', $project_type)
|
||||||
|
->setNewValue(
|
||||||
|
array(
|
||||||
|
$kind => $phids,
|
||||||
|
));
|
||||||
|
|
||||||
|
$adapter->queueTransaction($xaction);
|
||||||
|
|
||||||
|
if ($is_add) {
|
||||||
|
$this->logEffect(self::DO_ADD_PROJECTS, $phids);
|
||||||
|
} else {
|
||||||
|
$this->logEffect(self::DO_REMOVE_PROJECTS, $phids);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getActionEffectMap() {
|
||||||
|
return array(
|
||||||
|
self::DO_NO_TARGETS => array(
|
||||||
|
'icon' => 'fa-ban',
|
||||||
|
'color' => 'grey',
|
||||||
|
'name' => pht('No Targets'),
|
||||||
|
),
|
||||||
|
self::DO_INVALID => array(
|
||||||
|
'icon' => 'fa-ban',
|
||||||
|
'color' => 'red',
|
||||||
|
'name' => pht('Invalid Targets'),
|
||||||
|
),
|
||||||
|
self::DO_ALREADY_ASSOCIATED => array(
|
||||||
|
'icon' => 'fa-chevron-right',
|
||||||
|
'color' => 'grey',
|
||||||
|
'name' => pht('Already Associated'),
|
||||||
|
),
|
||||||
|
self::DO_ALREADY_UNASSOCIATED => array(
|
||||||
|
'icon' => 'fa-chevron-right',
|
||||||
|
'color' => 'grey',
|
||||||
|
'name' => pht('Already Unassociated'),
|
||||||
|
),
|
||||||
|
self::DO_ADD_PROJECTS => array(
|
||||||
|
'icon' => 'fa-briefcase',
|
||||||
|
'color' => 'green',
|
||||||
|
'name' => pht('Added Projects'),
|
||||||
|
),
|
||||||
|
self::DO_REMOVE_PROJECTS => array(
|
||||||
|
'icon' => 'fa-minus-circle',
|
||||||
|
'color' => 'green',
|
||||||
|
'name' => pht('Removed Projects'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderActionEffectDescription($type, $data) {
|
||||||
|
switch ($type) {
|
||||||
|
case self::DO_NO_TARGETS:
|
||||||
|
return pht('Rule lists no projects.');
|
||||||
|
case self::DO_INVALID:
|
||||||
|
return pht(
|
||||||
|
'Declined to act on %s invalid project(s): %s.',
|
||||||
|
new PhutilNumber(count($data)),
|
||||||
|
$this->renderHandleList($data));
|
||||||
|
case self::DO_ALREADY_ASSOCIATED:
|
||||||
|
return pht(
|
||||||
|
'%s project(s) are already associated: %s.',
|
||||||
|
new PhutilNumber(count($data)),
|
||||||
|
$this->renderHandleList($data));
|
||||||
|
case self::DO_ALREADY_UNASSOCIATED:
|
||||||
|
return pht(
|
||||||
|
'%s project(s) are not associated: %s.',
|
||||||
|
new PhutilNumber(count($data)),
|
||||||
|
$this->renderHandleList($data));
|
||||||
|
case self::DO_ADD_PROJECTS:
|
||||||
|
return pht(
|
||||||
|
'Added %s project(s): %s.',
|
||||||
|
new PhutilNumber(count($data)),
|
||||||
|
$this->renderHandleList($data));
|
||||||
|
case self::DO_REMOVE_PROJECTS:
|
||||||
|
return pht(
|
||||||
|
'Removed %s project(s): %s.',
|
||||||
|
new PhutilNumber(count($data)),
|
||||||
|
$this->renderHandleList($data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorProjectRemoveHeraldAction
|
||||||
|
extends PhabricatorProjectHeraldAction {
|
||||||
|
|
||||||
|
const ACTIONCONST = 'projects.remove';
|
||||||
|
|
||||||
|
public function getHeraldActionName() {
|
||||||
|
return pht('Remove projects');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function applyEffect($object, HeraldEffect $effect) {
|
||||||
|
return $this->applyProjects($effect->getTarget(), $is_add = false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHeraldActionStandardType() {
|
||||||
|
return self::STANDARD_PHID_LIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getDatasource() {
|
||||||
|
return new PhabricatorProjectDatasource();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderActionDescription($value) {
|
||||||
|
return pht('Remove projects: %s.', $this->renderHandleList($value));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1303,6 +1303,26 @@ final class PhabricatorUSEnglishTranslation
|
||||||
'preferences: %2$s.',
|
'preferences: %2$s.',
|
||||||
),
|
),
|
||||||
|
|
||||||
|
'%s project(s) are not associated: %s.' => array(
|
||||||
|
'A project is not associated: %2$s.',
|
||||||
|
'Projects are not associated: %2$s.',
|
||||||
|
),
|
||||||
|
|
||||||
|
'%s project(s) are already associated: %s.' => array(
|
||||||
|
'A project is already associated: %2$s.',
|
||||||
|
'Projects are already associated: %2$s.',
|
||||||
|
),
|
||||||
|
|
||||||
|
'Added %s project(s): %s.' => array(
|
||||||
|
'Added a project: %2$s.',
|
||||||
|
'Added projects: %2$s.',
|
||||||
|
),
|
||||||
|
|
||||||
|
'Removed %s project(s): %s.' => array(
|
||||||
|
'Removed a project: %2$s.',
|
||||||
|
'Removed projects: %2$s.',
|
||||||
|
),
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue