1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-19 03:50:54 +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:
epriestley 2016-02-08 11:24:32 -08:00
parent 9c95b387bd
commit 3682cc9bb2
7 changed files with 201 additions and 9 deletions

View file

@ -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',

View file

@ -84,6 +84,8 @@ final class PhabricatorProjectApplication extends PhabricatorApplication {
=> 'PhabricatorProjectBoardImportController',
'reorder/'
=> 'PhabricatorProjectBoardReorderController',
'disable/'
=> 'PhabricatorProjectBoardDisableController',
),
'update/(?P<id>[1-9]\d*)/(?P<action>[^/]+)/'
=> 'PhabricatorProjectUpdateController',

View file

@ -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'));
}
}

View file

@ -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);
}
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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();