1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-09-20 01:08:50 +02: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:
epriestley 2014-06-25 12:30:20 -07:00
parent ad22508e4f
commit a823d143b4
6 changed files with 72 additions and 62 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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