mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 08:52:39 +01:00
"Hide" columns instead of "Deleting" them
Summary: Fixes T5342. Fixes T5161. Previously, we were a bit strict about deleting columns because you could orphan tasks. Let users recover these columns more easily so they can't shoot themselves in the foot. - Change "Delete" language to "Hide". - Add a button to let you see hidden columns. - Remove restriction that you can only delete empty columns. The new button is a little funky, but maybe it merges into the "Add Column" button and that becomes a dropdown with board actions? The rest of this feels OK to me. Test Plan: See screenshot. Reviewers: chad Reviewed By: chad Subscribers: epriestley Maniphest Tasks: T5342, T5161 Differential Revision: https://secure.phabricator.com/D9719
This commit is contained in:
parent
ad22508e4f
commit
a823d143b4
6 changed files with 72 additions and 62 deletions
|
@ -41,34 +41,16 @@ final class PhabricatorProjectBoardDeleteController
|
||||||
return new Aphront404Response();
|
return new Aphront404Response();
|
||||||
}
|
}
|
||||||
|
|
||||||
$error_view = null;
|
|
||||||
$column_phid = $column->getPHID();
|
$column_phid = $column->getPHID();
|
||||||
$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!'));
|
|
||||||
if ($column->isDeleted()) {
|
|
||||||
$error_view->setErrors(array(pht(
|
|
||||||
'A column can not be activated if it has tasks '.
|
|
||||||
'in it. Please remove the tasks and try again.')));
|
|
||||||
} else {
|
|
||||||
$error_view->setErrors(array(pht(
|
|
||||||
'A column can not be deleted if it has tasks '.
|
|
||||||
'in it. Please remove the tasks and try again.')));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$view_uri = $this->getApplicationURI(
|
$view_uri = $this->getApplicationURI(
|
||||||
'/board/'.$this->projectID.'/column/'.$this->id.'/');
|
'/board/'.$this->projectID.'/column/'.$this->id.'/');
|
||||||
|
|
||||||
if ($request->isFormPost() && !$error_view) {
|
if ($request->isFormPost()) {
|
||||||
if ($column->isDeleted()) {
|
if ($column->isHidden()) {
|
||||||
$new_status = PhabricatorProjectColumn::STATUS_ACTIVE;
|
$new_status = PhabricatorProjectColumn::STATUS_ACTIVE;
|
||||||
} else {
|
} else {
|
||||||
$new_status = PhabricatorProjectColumn::STATUS_DELETED;
|
$new_status = PhabricatorProjectColumn::STATUS_HIDDEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
$type_status = PhabricatorProjectColumnTransaction::TYPE_STATUS;
|
$type_status = PhabricatorProjectColumnTransaction::TYPE_STATUS;
|
||||||
|
@ -85,31 +67,29 @@ final class PhabricatorProjectBoardDeleteController
|
||||||
return id(new AphrontRedirectResponse())->setURI($view_uri);
|
return id(new AphrontRedirectResponse())->setURI($view_uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($column->isDeleted()) {
|
if ($column->isHidden()) {
|
||||||
$title = pht('Activate Column');
|
$title = pht('Show Column');
|
||||||
} else {
|
} else {
|
||||||
$title = pht('Delete Column');
|
$title = pht('Hide Column');
|
||||||
}
|
|
||||||
$submit = $title;
|
|
||||||
if ($error_view) {
|
|
||||||
$body = $error_view;
|
|
||||||
} else if ($column->isDeleted()) {
|
|
||||||
$body = pht('Are you sure you want to activate this column?');
|
|
||||||
} else {
|
|
||||||
$body = pht('Are you sure you want to delete this column?');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$dialog = id(new AphrontDialogView())
|
if ($column->isHidden()) {
|
||||||
->setUser($viewer)
|
$body = pht(
|
||||||
|
'Are you sure you want to show this column?');
|
||||||
|
} else {
|
||||||
|
$body = pht(
|
||||||
|
'Are you sure you want to hide this column? It will no longer '.
|
||||||
|
'appear on the workboard.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$dialog = $this->newDialog()
|
||||||
->setWidth(AphrontDialogView::WIDTH_FORM)
|
->setWidth(AphrontDialogView::WIDTH_FORM)
|
||||||
->setTitle($title)
|
->setTitle($title)
|
||||||
->appendChild($body)
|
->appendChild($body)
|
||||||
->setDisableWorkflowOnCancel(true)
|
->setDisableWorkflowOnCancel(true)
|
||||||
->addSubmitButton($title)
|
->addCancelButton($view_uri)
|
||||||
->addCancelButton($view_uri);
|
->addSubmitButton($title);
|
||||||
|
|
||||||
return id(new AphrontDialogResponse())
|
|
||||||
->setDialog($dialog);
|
|
||||||
|
|
||||||
|
return $dialog;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@ final class PhabricatorProjectBoardViewController
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
$viewer = $request->getUser();
|
$viewer = $request->getUser();
|
||||||
|
|
||||||
|
$show_hidden = $request->getBool('hidden');
|
||||||
|
|
||||||
$project = id(new PhabricatorProjectQuery())
|
$project = id(new PhabricatorProjectQuery())
|
||||||
->setViewer($viewer)
|
->setViewer($viewer)
|
||||||
->needImages(true);
|
->needImages(true);
|
||||||
|
@ -39,12 +41,16 @@ final class PhabricatorProjectBoardViewController
|
||||||
|
|
||||||
$this->setProject($project);
|
$this->setProject($project);
|
||||||
|
|
||||||
$columns = id(new PhabricatorProjectColumnQuery())
|
$column_query = id(new PhabricatorProjectColumnQuery())
|
||||||
->setViewer($viewer)
|
->setViewer($viewer)
|
||||||
->withProjectPHIDs(array($project->getPHID()))
|
->withProjectPHIDs(array($project->getPHID()));
|
||||||
->withStatuses(array(PhabricatorProjectColumn::STATUS_ACTIVE))
|
|
||||||
->execute();
|
|
||||||
|
|
||||||
|
if (!$show_hidden) {
|
||||||
|
$column_query->withStatuses(
|
||||||
|
array(PhabricatorProjectColumn::STATUS_ACTIVE));
|
||||||
|
}
|
||||||
|
|
||||||
|
$columns = $column_query->execute();
|
||||||
$columns = mpull($columns, null, 'getSequence');
|
$columns = mpull($columns, null, 'getSequence');
|
||||||
|
|
||||||
// If there's no default column, create one now.
|
// If there's no default column, create one now.
|
||||||
|
@ -168,9 +174,11 @@ final class PhabricatorProjectBoardViewController
|
||||||
$panel = id(new PHUIWorkpanelView())
|
$panel = id(new PHUIWorkpanelView())
|
||||||
->setHeader($column->getDisplayName())
|
->setHeader($column->getDisplayName())
|
||||||
->setHeaderColor($column->getHeaderColor());
|
->setHeaderColor($column->getHeaderColor());
|
||||||
|
|
||||||
if (!$column->isDefaultColumn()) {
|
if (!$column->isDefaultColumn()) {
|
||||||
$panel->setEditURI($board_uri.'column/'.$column->getID().'/');
|
$panel->setEditURI($board_uri.'column/'.$column->getID().'/');
|
||||||
}
|
}
|
||||||
|
|
||||||
$panel->setHeaderAction(id(new PHUIIconView())
|
$panel->setHeaderAction(id(new PHUIIconView())
|
||||||
->setIconFont('fa-plus')
|
->setIconFont('fa-plus')
|
||||||
->setHref('/maniphest/task/create/')
|
->setHref('/maniphest/task/create/')
|
||||||
|
@ -187,6 +195,7 @@ final class PhabricatorProjectBoardViewController
|
||||||
array(
|
array(
|
||||||
'columnPHID' => $column->getPHID(),
|
'columnPHID' => $column->getPHID(),
|
||||||
));
|
));
|
||||||
|
|
||||||
$task_phids = idx($task_map, $column->getPHID(), array());
|
$task_phids = idx($task_map, $column->getPHID(), array());
|
||||||
foreach (array_select_keys($tasks, $task_phids) as $task) {
|
foreach (array_select_keys($tasks, $task_phids) as $task) {
|
||||||
$owner = null;
|
$owner = null;
|
||||||
|
@ -282,8 +291,6 @@ final class PhabricatorProjectBoardViewController
|
||||||
->setWorkflow(true)
|
->setWorkflow(true)
|
||||||
->setName(pht('Advanced Filter...'));
|
->setName(pht('Advanced Filter...'));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$filter_menu = id(new PhabricatorActionListView())
|
$filter_menu = id(new PhabricatorActionListView())
|
||||||
->setUser($viewer);
|
->setUser($viewer);
|
||||||
foreach ($items as $item) {
|
foreach ($items as $item) {
|
||||||
|
@ -296,7 +303,6 @@ final class PhabricatorProjectBoardViewController
|
||||||
->setTag('a')
|
->setTag('a')
|
||||||
->setHref('#')
|
->setHref('#')
|
||||||
->addSigil('boards-filter-menu')
|
->addSigil('boards-filter-menu')
|
||||||
|
|
||||||
->setMetadata(
|
->setMetadata(
|
||||||
array(
|
array(
|
||||||
'items' => hsprintf('%s', $filter_menu),
|
'items' => hsprintf('%s', $filter_menu),
|
||||||
|
@ -309,12 +315,33 @@ final class PhabricatorProjectBoardViewController
|
||||||
),
|
),
|
||||||
$project->getName());
|
$project->getName());
|
||||||
|
|
||||||
|
if ($show_hidden) {
|
||||||
|
$hidden_uri = $request->getRequestURI()
|
||||||
|
->setQueryParam('hidden', null);
|
||||||
|
$hidden_icon = id(new PHUIIconView())
|
||||||
|
->setIconFont('fa-eye-slash bluegrey');
|
||||||
|
$hidden_text = pht('Hide Hidden Columns');
|
||||||
|
} else {
|
||||||
|
$hidden_uri = $request->getRequestURI()
|
||||||
|
->setQueryParam('hidden', 'true');
|
||||||
|
$hidden_icon = id(new PHUIIconView())
|
||||||
|
->setIconFont('fa-eye bluegrey');
|
||||||
|
$hidden_text = pht('Show Hidden Columns');
|
||||||
|
}
|
||||||
|
|
||||||
|
$hidden_button = id(new PHUIButtonView())
|
||||||
|
->setText($hidden_text)
|
||||||
|
->setIcon($hidden_icon)
|
||||||
|
->setTag('a')
|
||||||
|
->setHref($hidden_uri);
|
||||||
|
|
||||||
$header = id(new PHUIHeaderView())
|
$header = id(new PHUIHeaderView())
|
||||||
->setHeader($header_link)
|
->setHeader($header_link)
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
->setNoBackground(true)
|
->setNoBackground(true)
|
||||||
->setImage($project->getProfileImageURI())
|
->setImage($project->getProfileImageURI())
|
||||||
->setImageURL($this->getApplicationURI('view/'.$project->getID().'/'))
|
->setImageURL($this->getApplicationURI('view/'.$project->getID().'/'))
|
||||||
|
->addActionLink($hidden_button)
|
||||||
->addActionLink($filter_button)
|
->addActionLink($filter_button)
|
||||||
->addActionLink($add_button)
|
->addActionLink($add_button)
|
||||||
->setPolicyObject($project);
|
->setPolicyObject($project);
|
||||||
|
|
|
@ -88,8 +88,8 @@ final class PhabricatorProjectColumnDetailController
|
||||||
->setHeader($column->getName())
|
->setHeader($column->getName())
|
||||||
->setPolicyObject($column);
|
->setPolicyObject($column);
|
||||||
|
|
||||||
if ($column->isDeleted()) {
|
if ($column->isHidden()) {
|
||||||
$header->setStatus('fa-ban', 'dark', pht('Deleted'));
|
$header->setStatus('fa-ban', 'dark', pht('Hidden'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $header;
|
return $header;
|
||||||
|
@ -113,25 +113,25 @@ final class PhabricatorProjectColumnDetailController
|
||||||
|
|
||||||
$actions->addAction(
|
$actions->addAction(
|
||||||
id(new PhabricatorActionView())
|
id(new PhabricatorActionView())
|
||||||
->setName(pht('Edit column'))
|
->setName(pht('Edit Column'))
|
||||||
->setIcon('fa-pencil')
|
->setIcon('fa-pencil')
|
||||||
->setHref($this->getApplicationURI($base_uri.'edit/'.$id.'/'))
|
->setHref($this->getApplicationURI($base_uri.'edit/'.$id.'/'))
|
||||||
->setDisabled(!$can_edit)
|
->setDisabled(!$can_edit)
|
||||||
->setWorkflow(!$can_edit));
|
->setWorkflow(!$can_edit));
|
||||||
|
|
||||||
if (!$column->isDeleted()) {
|
if (!$column->isHidden()) {
|
||||||
$actions->addAction(
|
$actions->addAction(
|
||||||
id(new PhabricatorActionView())
|
id(new PhabricatorActionView())
|
||||||
->setName(pht('Delete column'))
|
->setName(pht('Hide Column'))
|
||||||
->setIcon('fa-times')
|
->setIcon('fa-eye-slash')
|
||||||
->setHref($this->getApplicationURI($base_uri.'delete/'.$id.'/'))
|
->setHref($this->getApplicationURI($base_uri.'delete/'.$id.'/'))
|
||||||
->setDisabled(!$can_edit)
|
->setDisabled(!$can_edit)
|
||||||
->setWorkflow(true));
|
->setWorkflow(true));
|
||||||
} else {
|
} else {
|
||||||
$actions->addAction(
|
$actions->addAction(
|
||||||
id(new PhabricatorActionView())
|
id(new PhabricatorActionView())
|
||||||
->setName(pht('Activate column'))
|
->setName(pht('Show Column'))
|
||||||
->setIcon('fa-play-circle-o')
|
->setIcon('fa-eye')
|
||||||
->setHref($this->getApplicationURI($base_uri.'delete/'.$id.'/'))
|
->setHref($this->getApplicationURI($base_uri.'delete/'.$id.'/'))
|
||||||
->setDisabled(!$can_edit)
|
->setDisabled(!$can_edit)
|
||||||
->setWorkflow(true));
|
->setWorkflow(true));
|
||||||
|
|
|
@ -38,8 +38,7 @@ final class PhabricatorProjectPHIDTypeColumn extends PhabricatorPHIDType {
|
||||||
|
|
||||||
$handle->setName($column->getDisplayName());
|
$handle->setName($column->getDisplayName());
|
||||||
$handle->setURI('/project/board/'.$column->getProject()->getID().'/');
|
$handle->setURI('/project/board/'.$column->getProject()->getID().'/');
|
||||||
$handle->setDisabled(
|
$handle->setDisabled($column->isHidden());
|
||||||
$column->getStatus() == PhabricatorProjectColumn::STATUS_DELETED);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ final class PhabricatorProjectColumn
|
||||||
PhabricatorDestructableInterface {
|
PhabricatorDestructableInterface {
|
||||||
|
|
||||||
const STATUS_ACTIVE = 0;
|
const STATUS_ACTIVE = 0;
|
||||||
const STATUS_DELETED = 1;
|
const STATUS_HIDDEN = 1;
|
||||||
|
|
||||||
protected $name;
|
protected $name;
|
||||||
protected $status;
|
protected $status;
|
||||||
|
@ -45,8 +45,8 @@ final class PhabricatorProjectColumn
|
||||||
return ($this->getSequence() == 0);
|
return ($this->getSequence() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isDeleted() {
|
public function isHidden() {
|
||||||
return ($this->getStatus() == self::STATUS_DELETED);
|
return ($this->getStatus() == self::STATUS_HIDDEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDisplayName() {
|
public function getDisplayName() {
|
||||||
|
@ -57,6 +57,10 @@ final class PhabricatorProjectColumn
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getHeaderColor() {
|
public function getHeaderColor() {
|
||||||
|
if ($this->isHidden()) {
|
||||||
|
return PHUIActionHeaderView::HEADER_LIGHTRED;
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->isDefaultColumn()) {
|
if ($this->isDefaultColumn()) {
|
||||||
return PHUIActionHeaderView::HEADER_DARK_GREY;
|
return PHUIActionHeaderView::HEADER_DARK_GREY;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,11 +36,11 @@ final class PhabricatorProjectColumnTransaction
|
||||||
switch ($new) {
|
switch ($new) {
|
||||||
case PhabricatorProjectColumn::STATUS_ACTIVE:
|
case PhabricatorProjectColumn::STATUS_ACTIVE:
|
||||||
return pht(
|
return pht(
|
||||||
'%s activated this column.',
|
'%s marked this column visible.',
|
||||||
$author_handle);
|
$author_handle);
|
||||||
case PhabricatorProjectColumn::STATUS_DELETED:
|
case PhabricatorProjectColumn::STATUS_HIDDEN:
|
||||||
return pht(
|
return pht(
|
||||||
'%s deleted this column.',
|
'%s marked this column hidden.',
|
||||||
$author_handle);
|
$author_handle);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue