mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-21 13:00:56 +01:00
Allow workboards to be disabled, hiding "(Backlog)" column annotations
Summary: Fixes T7410. - Adds a "Disable Workboard" action to the "Manage Backlog" menu. - We'll probably move this somewhere else if/when that column gets too messy. - Disabling a board hides it, prevents it from being recreated by non-editors, and hides the "Project (Backlog)" annotations. - Resotring a board puts it back in pristine condition. Test Plan: - Disabled a board. - Verified "(Backlog)" annotations vanished. - Enabled a board. Reviewers: chad Reviewed By: chad Subscribers: mbishopim3 Maniphest Tasks: T7410 Differential Revision: https://secure.phabricator.com/D15215
This commit is contained in:
parent
9c95b387bd
commit
3682cc9bb2
7 changed files with 201 additions and 9 deletions
|
@ -2860,6 +2860,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorProjectApplication' => 'applications/project/application/PhabricatorProjectApplication.php',
|
||||
'PhabricatorProjectArchiveController' => 'applications/project/controller/PhabricatorProjectArchiveController.php',
|
||||
'PhabricatorProjectBoardController' => 'applications/project/controller/PhabricatorProjectBoardController.php',
|
||||
'PhabricatorProjectBoardDisableController' => 'applications/project/controller/PhabricatorProjectBoardDisableController.php',
|
||||
'PhabricatorProjectBoardImportController' => 'applications/project/controller/PhabricatorProjectBoardImportController.php',
|
||||
'PhabricatorProjectBoardReorderController' => 'applications/project/controller/PhabricatorProjectBoardReorderController.php',
|
||||
'PhabricatorProjectBoardViewController' => 'applications/project/controller/PhabricatorProjectBoardViewController.php',
|
||||
|
@ -7274,6 +7275,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorProjectApplication' => 'PhabricatorApplication',
|
||||
'PhabricatorProjectArchiveController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectBoardController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectBoardDisableController' => 'PhabricatorProjectBoardController',
|
||||
'PhabricatorProjectBoardImportController' => 'PhabricatorProjectBoardController',
|
||||
'PhabricatorProjectBoardReorderController' => 'PhabricatorProjectBoardController',
|
||||
'PhabricatorProjectBoardViewController' => 'PhabricatorProjectBoardController',
|
||||
|
|
|
@ -84,6 +84,8 @@ final class PhabricatorProjectApplication extends PhabricatorApplication {
|
|||
=> 'PhabricatorProjectBoardImportController',
|
||||
'reorder/'
|
||||
=> 'PhabricatorProjectBoardReorderController',
|
||||
'disable/'
|
||||
=> 'PhabricatorProjectBoardDisableController',
|
||||
),
|
||||
'update/(?P<id>[1-9]\d*)/(?P<action>[^/]+)/'
|
||||
=> 'PhabricatorProjectUpdateController',
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorProjectBoardDisableController
|
||||
extends PhabricatorProjectBoardController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getUser();
|
||||
$project_id = $request->getURIData('projectID');
|
||||
|
||||
$project = id(new PhabricatorProjectQuery())
|
||||
->setViewer($viewer)
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->withIDs(array($project_id))
|
||||
->executeOne();
|
||||
if (!$project) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
if (!$project->getHasWorkboard()) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$this->setProject($project);
|
||||
$id = $project->getID();
|
||||
|
||||
$board_uri = $this->getApplicationURI("board/{$id}/");
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$xactions = array();
|
||||
|
||||
$xactions[] = id(new PhabricatorProjectTransaction())
|
||||
->setTransactionType(PhabricatorProjectTransaction::TYPE_HASWORKBOARD)
|
||||
->setNewValue(0);
|
||||
|
||||
id(new PhabricatorProjectTransactionEditor())
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContinueOnMissingFields(true)
|
||||
->applyTransactions($project, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI($board_uri);
|
||||
}
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Disable Workboard'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Disabling a workboard hides the board. Objects on the board '.
|
||||
'will no longer be annotated with column names in other '.
|
||||
'applications. You can restore the workboard later.'))
|
||||
->addCancelButton($board_uri)
|
||||
->addSubmitButton(pht('Disable Workboard'));
|
||||
}
|
||||
|
||||
}
|
|
@ -121,19 +121,28 @@ final class PhabricatorProjectBoardViewController
|
|||
->setViewer($viewer)
|
||||
->setBoardPHIDs(array($board_phid))
|
||||
->setObjectPHIDs(array_keys($tasks))
|
||||
->setFetchAllBoards(true)
|
||||
->executeLayout();
|
||||
|
||||
$columns = $layout_engine->getColumns($board_phid);
|
||||
if (!$columns) {
|
||||
if (!$columns || !$project->getHasWorkboard()) {
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$project,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
if (!$columns) {
|
||||
if (!$can_edit) {
|
||||
$content = $this->buildNoAccessContent($project);
|
||||
} else {
|
||||
$content = $this->buildInitializeContent($project);
|
||||
}
|
||||
} else {
|
||||
if (!$can_edit) {
|
||||
$content = $this->buildDisabledContent($project);
|
||||
} else {
|
||||
$content = $this->buildEnableContent($project);
|
||||
}
|
||||
}
|
||||
|
||||
if ($content instanceof AphrontResponse) {
|
||||
return $content;
|
||||
|
@ -544,6 +553,12 @@ final class PhabricatorProjectBoardViewController
|
|||
$request = $this->getRequest();
|
||||
$viewer = $request->getUser();
|
||||
|
||||
$id = $project->getID();
|
||||
|
||||
$disable_uri = $this->getApplicationURI("board/{$id}/disable/");
|
||||
$add_uri = $this->getApplicationURI("board/{$id}/edit/");
|
||||
$reorder_uri = $this->getApplicationURI("board/{$id}/reorder/");
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$project,
|
||||
|
@ -554,14 +569,14 @@ final class PhabricatorProjectBoardViewController
|
|||
$manage_items[] = id(new PhabricatorActionView())
|
||||
->setIcon('fa-plus')
|
||||
->setName(pht('Add Column'))
|
||||
->setHref($this->getApplicationURI('board/'.$this->id.'/edit/'))
|
||||
->setHref($add_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit);
|
||||
|
||||
$manage_items[] = id(new PhabricatorActionView())
|
||||
->setIcon('fa-exchange')
|
||||
->setName(pht('Reorder Columns'))
|
||||
->setHref($this->getApplicationURI('board/'.$this->id.'/reorder/'))
|
||||
->setHref($reorder_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true);
|
||||
|
||||
|
@ -595,6 +610,13 @@ final class PhabricatorProjectBoardViewController
|
|||
->setHref($batch_edit_uri)
|
||||
->setDisabled(!$can_batch_edit);
|
||||
|
||||
$manage_items[] = id(new PhabricatorActionView())
|
||||
->setIcon('fa-ban')
|
||||
->setName(pht('Disable Workboard'))
|
||||
->setHref($disable_uri)
|
||||
->setWorkflow(true)
|
||||
->setDisabled(!$can_edit);
|
||||
|
||||
$manage_menu = id(new PhabricatorActionListView())
|
||||
->setUser($viewer);
|
||||
foreach ($manage_items as $item) {
|
||||
|
@ -852,4 +874,59 @@ final class PhabricatorProjectBoardViewController
|
|||
->addCancelButton($profile_uri);
|
||||
}
|
||||
|
||||
|
||||
private function buildEnableContent(PhabricatorProject $project) {
|
||||
$request = $this->getRequest();
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$id = $project->getID();
|
||||
$profile_uri = $this->getApplicationURI("profile/{$id}/");
|
||||
$board_uri = $this->getApplicationURI("board/{$id}/");
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$xactions = array();
|
||||
|
||||
$xactions[] = id(new PhabricatorProjectTransaction())
|
||||
->setTransactionType(PhabricatorProjectTransaction::TYPE_HASWORKBOARD)
|
||||
->setNewValue(1);
|
||||
|
||||
id(new PhabricatorProjectTransactionEditor())
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContinueOnMissingFields(true)
|
||||
->applyTransactions($project, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI($board_uri);
|
||||
}
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Workboard Disabled'))
|
||||
->addHiddenInput('initialize', 1)
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'This workboard has been disabled, but can be restored to its '.
|
||||
'former glory.'))
|
||||
->addCancelButton($profile_uri)
|
||||
->addSubmitButton(pht('Enable Workboard'));
|
||||
}
|
||||
|
||||
private function buildDisabledContent(PhabricatorProject $project) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$id = $project->getID();
|
||||
|
||||
$profile_uri = $this->getApplicationURI("profile/{$id}/");
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Workboard Disabled'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'This workboard has been disabled, and you do not have permission '.
|
||||
'to enable it. Only users who can edit this project can restore '.
|
||||
'the workboard.'))
|
||||
->addCancelButton($profile_uri);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ final class PhabricatorProjectTransactionEditor
|
|||
$types[] = PhabricatorProjectTransaction::TYPE_LOCKED;
|
||||
$types[] = PhabricatorProjectTransaction::TYPE_PARENT;
|
||||
$types[] = PhabricatorProjectTransaction::TYPE_MILESTONE;
|
||||
$types[] = PhabricatorProjectTransaction::TYPE_HASWORKBOARD;
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
@ -65,6 +66,8 @@ final class PhabricatorProjectTransactionEditor
|
|||
return $object->getColor();
|
||||
case PhabricatorProjectTransaction::TYPE_LOCKED:
|
||||
return (int)$object->getIsMembershipLocked();
|
||||
case PhabricatorProjectTransaction::TYPE_HASWORKBOARD:
|
||||
return (int)$object->getHasWorkboard();
|
||||
case PhabricatorProjectTransaction::TYPE_PARENT:
|
||||
case PhabricatorProjectTransaction::TYPE_MILESTONE:
|
||||
return null;
|
||||
|
@ -87,6 +90,8 @@ final class PhabricatorProjectTransactionEditor
|
|||
case PhabricatorProjectTransaction::TYPE_PARENT:
|
||||
case PhabricatorProjectTransaction::TYPE_MILESTONE:
|
||||
return $xaction->getNewValue();
|
||||
case PhabricatorProjectTransaction::TYPE_HASWORKBOARD:
|
||||
return (int)$xaction->getNewValue();
|
||||
case PhabricatorProjectTransaction::TYPE_SLUGS:
|
||||
return $this->normalizeSlugs($xaction->getNewValue());
|
||||
}
|
||||
|
@ -131,6 +136,9 @@ final class PhabricatorProjectTransactionEditor
|
|||
$object->setMilestoneNumber($number);
|
||||
$object->setParentProjectPHID($xaction->getNewValue());
|
||||
return;
|
||||
case PhabricatorProjectTransaction::TYPE_HASWORKBOARD:
|
||||
$object->setHasWorkboard($xaction->getNewValue());
|
||||
return;
|
||||
}
|
||||
|
||||
return parent::applyCustomInternalTransaction($object, $xaction);
|
||||
|
@ -172,6 +180,7 @@ final class PhabricatorProjectTransactionEditor
|
|||
case PhabricatorProjectTransaction::TYPE_LOCKED:
|
||||
case PhabricatorProjectTransaction::TYPE_PARENT:
|
||||
case PhabricatorProjectTransaction::TYPE_MILESTONE:
|
||||
case PhabricatorProjectTransaction::TYPE_HASWORKBOARD:
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ final class PhabricatorBoardLayoutEngine extends Phobject {
|
|||
private $columnMap = array();
|
||||
private $objectColumnMap = array();
|
||||
private $boardLayout = array();
|
||||
private $fetchAllBoards;
|
||||
|
||||
private $remQueue = array();
|
||||
private $addQueue = array();
|
||||
|
@ -40,6 +41,18 @@ final class PhabricatorBoardLayoutEngine extends Phobject {
|
|||
return $this->objectPHIDs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all boards, even if the board is disabled.
|
||||
*/
|
||||
public function setFetchAllBoards($fetch_all) {
|
||||
$this->fetchAllBoards = $fetch_all;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getFetchAllBoards() {
|
||||
return $this->fetchAllBoards;
|
||||
}
|
||||
|
||||
public function executeLayout() {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
|
@ -301,11 +314,13 @@ final class PhabricatorBoardLayoutEngine extends Phobject {
|
|||
->execute();
|
||||
$boards = mpull($boards, null, 'getPHID');
|
||||
|
||||
if (!$this->fetchAllBoards) {
|
||||
foreach ($boards as $key => $board) {
|
||||
if (!$board->getHasWorkboard()) {
|
||||
unset($boards[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $boards;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ final class PhabricatorProjectTransaction
|
|||
const TYPE_LOCKED = 'project:locked';
|
||||
const TYPE_PARENT = 'project:parent';
|
||||
const TYPE_MILESTONE = 'project:milestone';
|
||||
const TYPE_HASWORKBOARD = 'project:hasworkboard';
|
||||
|
||||
// NOTE: This is deprecated, members are just a normal edge now.
|
||||
const TYPE_MEMBERS = 'project:members';
|
||||
|
@ -246,6 +247,17 @@ final class PhabricatorProjectTransaction
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case self::TYPE_HASWORKBOARD:
|
||||
if ($new) {
|
||||
return pht(
|
||||
'%s enabled the workboard for this project.',
|
||||
$author_handle);
|
||||
} else {
|
||||
return pht(
|
||||
'%s disabled the workboard for this project.',
|
||||
$author_handle);
|
||||
}
|
||||
}
|
||||
|
||||
return parent::getTitle();
|
||||
|
@ -366,6 +378,20 @@ final class PhabricatorProjectTransaction
|
|||
$object_handle,
|
||||
$this->renderSlugList($rem));
|
||||
}
|
||||
|
||||
case self::TYPE_HASWORKBOARD:
|
||||
if ($new) {
|
||||
return pht(
|
||||
'%s enabled the workboard for %s.',
|
||||
$author_handle,
|
||||
$object_handle);
|
||||
} else {
|
||||
return pht(
|
||||
'%s disabled the workboard for %s.',
|
||||
$author_handle,
|
||||
$object_handle);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return parent::getTitleForFeed();
|
||||
|
|
Loading…
Reference in a new issue