mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 14:52:41 +01:00
Workboards - let users delete columns
Summary: Fixes T4408. I had to add a "status" to colum. I think we'll need this once we get fancier anyway but for now we have "active" and deleted. Test Plan: deleted a column. noted reloaded workboard with all those tasks back in the default colun. loaded a task and saw the initial transaction had a "Disabled" icon next to the deleted workboard. also saw the new transaction back to the default column worked. Reviewers: epriestley Reviewed By: epriestley Subscribers: epriestley, Korvin Maniphest Tasks: T4408 Differential Revision: https://secure.phabricator.com/D8544
This commit is contained in:
parent
1e8ed3e5ff
commit
809e5a0389
9 changed files with 153 additions and 1 deletions
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE {$NAMESPACE}_project.project_column
|
||||
ADD COLUMN status INT UNSIGNED NOT NULL AFTER name;
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE {$NAMESPACE}_project.project_column
|
||||
ADD KEY `key_status` (`projectPHID`,`status`,`sequence`);
|
|
@ -1843,6 +1843,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorProject' => 'applications/project/storage/PhabricatorProject.php',
|
||||
'PhabricatorProjectArchiveController' => 'applications/project/controller/PhabricatorProjectArchiveController.php',
|
||||
'PhabricatorProjectBoardController' => 'applications/project/controller/PhabricatorProjectBoardController.php',
|
||||
'PhabricatorProjectBoardDeleteController' => 'applications/project/controller/PhabricatorProjectBoardDeleteController.php',
|
||||
'PhabricatorProjectBoardEditController' => 'applications/project/controller/PhabricatorProjectBoardEditController.php',
|
||||
'PhabricatorProjectColumn' => 'applications/project/storage/PhabricatorProjectColumn.php',
|
||||
'PhabricatorProjectColumnQuery' => 'applications/project/query/PhabricatorProjectColumnQuery.php',
|
||||
|
@ -4609,6 +4610,7 @@ phutil_register_library_map(array(
|
|||
),
|
||||
'PhabricatorProjectArchiveController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectBoardController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectBoardDeleteController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectBoardEditController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectColumn' =>
|
||||
array(
|
||||
|
|
|
@ -53,6 +53,8 @@ final class PhabricatorApplicationProject extends PhabricatorApplication {
|
|||
'move/(?P<id>[1-9]\d*)/' => 'PhabricatorProjectMoveController',
|
||||
'board/(?P<projectID>[1-9]\d*)/edit/(?:(?P<id>\d+)/)?'
|
||||
=> 'PhabricatorProjectBoardEditController',
|
||||
'board/(?P<projectID>[1-9]\d*)/delete/(?:(?P<id>\d+)/)?'
|
||||
=> 'PhabricatorProjectBoardDeleteController',
|
||||
'update/(?P<id>[1-9]\d*)/(?P<action>[^/]+)/'
|
||||
=> 'PhabricatorProjectUpdateController',
|
||||
'history/(?P<id>[1-9]\d*)/' => 'PhabricatorProjectHistoryController',
|
||||
|
|
|
@ -30,6 +30,7 @@ final class PhabricatorProjectBoardController
|
|||
$columns = id(new PhabricatorProjectColumnQuery())
|
||||
->setViewer($viewer)
|
||||
->withProjectPHIDs(array($project->getPHID()))
|
||||
->withStatuses(array(PhabricatorProjectColumn::STATUS_ACTIVE))
|
||||
->execute();
|
||||
|
||||
$columns = mpull($columns, null, 'getSequence');
|
||||
|
@ -168,6 +169,13 @@ final class PhabricatorProjectBoardController
|
|||
->setHref($this->getApplicationURI('board/'.$this->id.'/edit/'))
|
||||
->setIcon('create')
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit))
|
||||
->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Delete Column'))
|
||||
->setHref($this->getApplicationURI('board/'.$this->id.'/delete/'))
|
||||
->setIcon('delete')
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
|
||||
$plist = id(new PHUIPropertyListView());
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorProjectBoardDeleteController
|
||||
extends PhabricatorProjectController {
|
||||
|
||||
private $id;
|
||||
private $projectID;
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->projectID = $data['projectID'];
|
||||
$this->id = idx($data, 'id');
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
$viewer = $request->getUser();
|
||||
|
||||
$project = id(new PhabricatorProjectQuery())
|
||||
->setViewer($viewer)
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->withIDs(array($this->projectID))
|
||||
->executeOne();
|
||||
|
||||
if (!$project) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$columns = id(new PhabricatorProjectColumnQuery())
|
||||
->setViewer($viewer)
|
||||
->withProjectPHIDs(array($project->getPHID()))
|
||||
->withStatuses(array(PhabricatorProjectColumn::STATUS_ACTIVE))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT))
|
||||
->execute();
|
||||
|
||||
if (!$columns) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$columns = mpull($columns, null, 'getSequence');
|
||||
$columns = mfilter($columns, 'isDefaultColumn', true);
|
||||
ksort($columns);
|
||||
$options = mpull($columns, 'getName', 'getPHID');
|
||||
|
||||
$view_uri = $this->getApplicationURI('/board/'.$this->projectID.'/');
|
||||
$error_view = null;
|
||||
if ($request->isFormPost()) {
|
||||
$columns = mpull($columns, null, 'getPHID');
|
||||
$column_phid = $request->getStr('columnPHID');
|
||||
$column = $columns[$column_phid];
|
||||
|
||||
$has_task_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
|
||||
$column_phid,
|
||||
PhabricatorEdgeConfig::TYPE_COLUMN_HAS_OBJECT);
|
||||
|
||||
if ($has_task_phids) {
|
||||
$error_view = id(new AphrontErrorView())
|
||||
->setTitle(pht('Column has Tasks!'))
|
||||
->setErrors(array(pht('A column can not be deleted if it has tasks '.
|
||||
'in it. Please remove the tasks and try '.
|
||||
'again.')));
|
||||
} else {
|
||||
$column->setStatus(PhabricatorProjectColumn::STATUS_DELETED);
|
||||
$column->save();
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($view_uri);
|
||||
}
|
||||
}
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->appendChild($error_view)
|
||||
->appendChild(id(new AphrontFormSelectControl())
|
||||
->setName('columnPHID')
|
||||
->setValue(head_key($options))
|
||||
->setOptions($options)
|
||||
->setLabel(pht('Column')));
|
||||
|
||||
$title = pht('Delete Column');
|
||||
$submit = $title;
|
||||
|
||||
$form->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue($submit)
|
||||
->addCancelButton($view_uri));
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(
|
||||
$project->getName(),
|
||||
$this->getApplicationURI('view/'.$project->getID().'/'));
|
||||
$crumbs->addTextCrumb(
|
||||
pht('Board'),
|
||||
$this->getApplicationURI('board/'.$project->getID().'/'));
|
||||
$crumbs->addTextCrumb($title);
|
||||
|
||||
$form_box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText($title)
|
||||
->setForm($form);
|
||||
|
||||
return $this->buildApplicationPage(
|
||||
array(
|
||||
$crumbs,
|
||||
$form_box,
|
||||
),
|
||||
array(
|
||||
'title' => $title,
|
||||
'device' => true,
|
||||
));
|
||||
}
|
||||
}
|
|
@ -34,6 +34,8 @@ final class PhabricatorProjectPHIDTypeColumn extends PhabricatorPHIDType {
|
|||
|
||||
$handle->setName($column->getDisplayName());
|
||||
$handle->setURI('/project/board/'.$column->getProject()->getID().'/');
|
||||
$handle->setDisabled(
|
||||
$column->getStatus() == PhabricatorProjectColumn::STATUS_DELETED);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ final class PhabricatorProjectColumnQuery
|
|||
private $ids;
|
||||
private $phids;
|
||||
private $projectPHIDs;
|
||||
private $statuses;
|
||||
|
||||
public function withIDs(array $ids) {
|
||||
$this->ids = $ids;
|
||||
|
@ -22,6 +23,11 @@ final class PhabricatorProjectColumnQuery
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function withStatuses(array $status) {
|
||||
$this->statuses = $status;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function loadPage() {
|
||||
$table = new PhabricatorProjectColumn();
|
||||
$conn_r = $table->establishConnection('r');
|
||||
|
@ -87,6 +93,13 @@ final class PhabricatorProjectColumnQuery
|
|||
$this->projectPHIDs);
|
||||
}
|
||||
|
||||
if ($this->statuses !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn_r,
|
||||
'status IN (%Ld)',
|
||||
$this->statuses);
|
||||
}
|
||||
|
||||
$where[] = $this->buildPagingClause($conn_r);
|
||||
|
||||
return $this->formatWhereClause($where);
|
||||
|
|
|
@ -4,7 +4,11 @@ final class PhabricatorProjectColumn
|
|||
extends PhabricatorProjectDAO
|
||||
implements PhabricatorPolicyInterface {
|
||||
|
||||
const STATUS_ACTIVE = 0;
|
||||
const STATUS_DELETED = 1;
|
||||
|
||||
protected $name;
|
||||
protected $status;
|
||||
protected $projectPHID;
|
||||
protected $sequence;
|
||||
|
||||
|
@ -12,7 +16,8 @@ final class PhabricatorProjectColumn
|
|||
|
||||
public static function initializeNewColumn(PhabricatorUser $user) {
|
||||
return id(new PhabricatorProjectColumn())
|
||||
->setName('');
|
||||
->setName('')
|
||||
->setStatus(self::STATUS_ACTIVE);
|
||||
}
|
||||
|
||||
public function getConfiguration() {
|
||||
|
|
Loading…
Reference in a new issue