1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-01 19:22:42 +01:00

Add ability to archive a Dashboard

Summary: Let's people archive unused Dashboards (if they have permission).

Test Plan: Archive and Unarchive a dashboard, view history, view search, build new filters.

Reviewers: btrahan, epriestley

Reviewed By: epriestley

Subscribers: epriestley, Korvin

Maniphest Tasks: T6443

Differential Revision: https://secure.phabricator.com/D13683
This commit is contained in:
Chad Little 2015-07-23 14:22:56 -07:00
parent e0861bf240
commit c22d6c7beb
9 changed files with 169 additions and 4 deletions

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_dashboard.dashboard
ADD status VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT};

View file

@ -0,0 +1,2 @@
UPDATE {$NAMESPACE}_dashboard.dashboard
SET status = 'open';

View file

@ -67,6 +67,7 @@ final class PhabricatorDashboardEditController
} }
$v_name = $dashboard->getName(); $v_name = $dashboard->getName();
$v_stat = $dashboard->getStatus();
$v_layout_mode = $dashboard->getLayoutConfigObject()->getLayoutMode(); $v_layout_mode = $dashboard->getLayoutConfigObject()->getLayoutMode();
$e_name = true; $e_name = true;
@ -77,11 +78,13 @@ final class PhabricatorDashboardEditController
$v_view_policy = $request->getStr('viewPolicy'); $v_view_policy = $request->getStr('viewPolicy');
$v_edit_policy = $request->getStr('editPolicy'); $v_edit_policy = $request->getStr('editPolicy');
$v_projects = $request->getArr('projects'); $v_projects = $request->getArr('projects');
$v_stat = $request->getStr('status');
$xactions = array(); $xactions = array();
$type_name = PhabricatorDashboardTransaction::TYPE_NAME; $type_name = PhabricatorDashboardTransaction::TYPE_NAME;
$type_layout_mode = PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE; $type_layout_mode = PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE;
$type_stat = PhabricatorDashboardTransaction::TYPE_STATUS;
$type_view_policy = PhabricatorTransactions::TYPE_VIEW_POLICY; $type_view_policy = PhabricatorTransactions::TYPE_VIEW_POLICY;
$type_edit_policy = PhabricatorTransactions::TYPE_EDIT_POLICY; $type_edit_policy = PhabricatorTransactions::TYPE_EDIT_POLICY;
@ -97,6 +100,9 @@ final class PhabricatorDashboardEditController
$xactions[] = id(new PhabricatorDashboardTransaction()) $xactions[] = id(new PhabricatorDashboardTransaction())
->setTransactionType($type_edit_policy) ->setTransactionType($type_edit_policy)
->setNewValue($v_edit_policy); ->setNewValue($v_edit_policy);
$xactions[] = id(new PhabricatorDashboardTransaction())
->setTransactionType($type_stat)
->setNewValue($v_stat);
$proj_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST; $proj_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
$xactions[] = id(new PhabricatorDashboardTransaction()) $xactions[] = id(new PhabricatorDashboardTransaction())
@ -157,7 +163,13 @@ final class PhabricatorDashboardEditController
->setLabel(pht('Layout Mode')) ->setLabel(pht('Layout Mode'))
->setName('layout_mode') ->setName('layout_mode')
->setValue($v_layout_mode) ->setValue($v_layout_mode)
->setOptions($layout_mode_options)); ->setOptions($layout_mode_options))
->appendChild(
id(new AphrontFormSelectControl())
->setLabel(pht('Status'))
->setName('status')
->setValue($v_stat)
->setOptions($dashboard->getStatusNameMap()));
$form->appendControl( $form->appendControl(
id(new AphrontFormTokenizerControl()) id(new AphrontFormTokenizerControl())

View file

@ -81,10 +81,23 @@ final class PhabricatorDashboardManageController
private function buildHeaderView(PhabricatorDashboard $dashboard) { private function buildHeaderView(PhabricatorDashboard $dashboard) {
$viewer = $this->getRequest()->getUser(); $viewer = $this->getRequest()->getUser();
if ($dashboard->isClosed()) {
$status_icon = 'fa-ban';
$status_color = 'dark';
} else {
$status_icon = 'fa-check';
$status_color = 'bluegrey';
}
$status_name = idx(
PhabricatorDashboard::getStatusNameMap(),
$dashboard->getStatus());
return id(new PHUIHeaderView()) return id(new PHUIHeaderView())
->setUser($viewer) ->setUser($viewer)
->setHeader($dashboard->getName()) ->setHeader($dashboard->getName())
->setPolicyObject($dashboard); ->setPolicyObject($dashboard)
->setStatus($status_icon, $status_color, $status_name);
} }
private function buildActionView(PhabricatorDashboard $dashboard) { private function buildActionView(PhabricatorDashboard $dashboard) {

View file

@ -51,6 +51,7 @@ final class PhabricatorDashboardTransactionEditor
$types[] = PhabricatorTransactions::TYPE_EDGE; $types[] = PhabricatorTransactions::TYPE_EDGE;
$types[] = PhabricatorDashboardTransaction::TYPE_NAME; $types[] = PhabricatorDashboardTransaction::TYPE_NAME;
$types[] = PhabricatorDashboardTransaction::TYPE_STATUS;
$types[] = PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE; $types[] = PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE;
return $types; return $types;
@ -65,6 +66,11 @@ final class PhabricatorDashboardTransactionEditor
return null; return null;
} }
return $object->getName(); return $object->getName();
case PhabricatorDashboardTransaction::TYPE_STATUS:
if ($this->getIsNewObject()) {
return null;
}
return $object->getStatus();
case PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE: case PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE:
if ($this->getIsNewObject()) { if ($this->getIsNewObject()) {
return null; return null;
@ -81,6 +87,7 @@ final class PhabricatorDashboardTransactionEditor
PhabricatorApplicationTransaction $xaction) { PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) { switch ($xaction->getTransactionType()) {
case PhabricatorDashboardTransaction::TYPE_NAME: case PhabricatorDashboardTransaction::TYPE_NAME:
case PhabricatorDashboardTransaction::TYPE_STATUS:
case PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE: case PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE:
return $xaction->getNewValue(); return $xaction->getNewValue();
} }
@ -94,6 +101,9 @@ final class PhabricatorDashboardTransactionEditor
case PhabricatorDashboardTransaction::TYPE_NAME: case PhabricatorDashboardTransaction::TYPE_NAME:
$object->setName($xaction->getNewValue()); $object->setName($xaction->getNewValue());
return; return;
case PhabricatorDashboardTransaction::TYPE_STATUS:
$object->setStatus($xaction->getNewValue());
return;
case PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE: case PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE:
$old_layout = $object->getLayoutConfigObject(); $old_layout = $object->getLayoutConfigObject();
$new_layout = clone $old_layout; $new_layout = clone $old_layout;
@ -120,6 +130,7 @@ final class PhabricatorDashboardTransactionEditor
switch ($xaction->getTransactionType()) { switch ($xaction->getTransactionType()) {
case PhabricatorDashboardTransaction::TYPE_NAME: case PhabricatorDashboardTransaction::TYPE_NAME:
case PhabricatorDashboardTransaction::TYPE_STATUS:
case PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE: case PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE:
return; return;
} }

View file

@ -5,6 +5,7 @@ final class PhabricatorDashboardQuery
private $ids; private $ids;
private $phids; private $phids;
private $statuses;
private $needPanels; private $needPanels;
private $needProjects; private $needProjects;
@ -19,6 +20,11 @@ final class PhabricatorDashboardQuery
return $this; return $this;
} }
public function withStatuses(array $statuses) {
$this->statuses = $statuses;
return $this;
}
public function needPanels($need_panels) { public function needPanels($need_panels) {
$this->needPanels = $need_panels; $this->needPanels = $need_panels;
return $this; return $this;
@ -108,6 +114,13 @@ final class PhabricatorDashboardQuery
$this->phids); $this->phids);
} }
if ($this->statuses !== null) {
$where[] = qsprintf(
$conn,
'status IN (%Ls)',
$this->statuses);
}
return $where; return $where;
} }

View file

@ -17,7 +17,12 @@ final class PhabricatorDashboardSearchEngine
} }
protected function buildCustomSearchFields() { protected function buildCustomSearchFields() {
return array(); return array(
id(new PhabricatorSearchCheckboxesField())
->setKey('statuses')
->setLabel(pht('Status'))
->setOptions(PhabricatorDashboard::getStatusNameMap()),
);
} }
protected function getURI($path) { protected function getURI($path) {
@ -26,18 +31,24 @@ final class PhabricatorDashboardSearchEngine
protected function getBuiltinQueryNames() { protected function getBuiltinQueryNames() {
return array( return array(
'open' => pht('Active Dashboards'),
'all' => pht('All Dashboards'), 'all' => pht('All Dashboards'),
); );
} }
public function buildSavedQueryFromBuiltin($query_key) { public function buildSavedQueryFromBuiltin($query_key) {
$query = $this->newSavedQuery(); $query = $this->newSavedQuery();
$query->setQueryKey($query_key); $query->setQueryKey($query_key);
switch ($query_key) { switch ($query_key) {
case 'all': case 'all':
return $query; return $query;
case 'open':
return $query->setParameter(
'statuses',
array(
PhabricatorDashboard::STATUS_ACTIVE,
));
} }
return parent::buildSavedQueryFromBuiltin($query_key); return parent::buildSavedQueryFromBuiltin($query_key);
@ -45,6 +56,11 @@ final class PhabricatorDashboardSearchEngine
protected function buildQueryFromParameters(array $map) { protected function buildQueryFromParameters(array $map) {
$query = $this->newQuery(); $query = $this->newQuery();
if ($map['statuses']) {
$query->withStatuses($map['statuses']);
}
return $query; return $query;
} }
@ -124,6 +140,30 @@ final class PhabricatorDashboardSearchEngine
->setSlim(true) ->setSlim(true)
->setHandles($project_handles)); ->setHandles($project_handles));
if ($dashboard->isClosed()) {
$item->setDisabled(true);
}
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$dashboard,
PhabricatorPolicyCapability::CAN_EDIT);
$href_view = $this->getApplicationURI("manage/{$id}/");
$item->addAction(
id(new PHUIListItemView())
->setName(pht('Manage'))
->setIcon('fa-th')
->setHref($href_view));
$href_edit = $this->getApplicationURI("edit/{$id}/");
$item->addAction(
id(new PHUIListItemView())
->setName(pht('Edit'))
->setIcon('fa-pencil')
->setHref($href_edit)
->setDisabled(!$can_edit));
$list->addItem($item); $list->addItem($item);
} }

View file

@ -14,8 +14,12 @@ final class PhabricatorDashboard extends PhabricatorDashboardDAO
protected $name; protected $name;
protected $viewPolicy; protected $viewPolicy;
protected $editPolicy; protected $editPolicy;
protected $status;
protected $layoutConfig = array(); protected $layoutConfig = array();
const STATUS_ACTIVE = 'active';
const STATUS_ARCHIVED = 'archived';
private $panelPHIDs = self::ATTACHABLE; private $panelPHIDs = self::ATTACHABLE;
private $panels = self::ATTACHABLE; private $panels = self::ATTACHABLE;
private $edgeProjectPHIDs = self::ATTACHABLE; private $edgeProjectPHIDs = self::ATTACHABLE;
@ -26,10 +30,18 @@ final class PhabricatorDashboard extends PhabricatorDashboardDAO
->setName('') ->setName('')
->setViewPolicy(PhabricatorPolicies::POLICY_USER) ->setViewPolicy(PhabricatorPolicies::POLICY_USER)
->setEditPolicy($actor->getPHID()) ->setEditPolicy($actor->getPHID())
->setStatus(self::STATUS_ACTIVE)
->attachPanels(array()) ->attachPanels(array())
->attachPanelPHIDs(array()); ->attachPanelPHIDs(array());
} }
public static function getStatusNameMap() {
return array(
self::STATUS_ACTIVE => pht('Active'),
self::STATUS_ARCHIVED => pht('Archived'),
);
}
public static function copyDashboard( public static function copyDashboard(
PhabricatorDashboard $dst, PhabricatorDashboard $dst,
PhabricatorDashboard $src) { PhabricatorDashboard $src) {
@ -48,6 +60,7 @@ final class PhabricatorDashboard extends PhabricatorDashboardDAO
), ),
self::CONFIG_COLUMN_SCHEMA => array( self::CONFIG_COLUMN_SCHEMA => array(
'name' => 'text255', 'name' => 'text255',
'status' => 'text32',
), ),
) + parent::getConfiguration(); ) + parent::getConfiguration();
} }
@ -96,6 +109,10 @@ final class PhabricatorDashboard extends PhabricatorDashboardDAO
return $this->assertAttached($this->panels); return $this->assertAttached($this->panels);
} }
public function isClosed() {
return ($this->getStatus() == self::STATUS_ARCHIVED);
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */ /* -( PhabricatorApplicationTransactionInterface )------------------------- */

View file

@ -4,6 +4,7 @@ final class PhabricatorDashboardTransaction
extends PhabricatorApplicationTransaction { extends PhabricatorApplicationTransaction {
const TYPE_NAME = 'dashboard:name'; const TYPE_NAME = 'dashboard:name';
const TYPE_STATUS = 'dashboard:status';
const TYPE_LAYOUT_MODE = 'dashboard:layoutmode'; const TYPE_LAYOUT_MODE = 'dashboard:layoutmode';
public function getApplicationName() { public function getApplicationName() {
@ -37,6 +38,18 @@ final class PhabricatorDashboardTransaction
$old, $old,
$new); $new);
} }
break;
case self::TYPE_STATUS:
if ($new == PhabricatorDashboard::STATUS_ACTIVE) {
return pht(
'%s activated this dashboard',
$author_link);
} else {
return pht(
'%s archived this dashboard',
$author_link);
}
break;
} }
return parent::getTitle(); return parent::getTitle();
@ -68,6 +81,20 @@ final class PhabricatorDashboardTransaction
$old, $old,
$new); $new);
} }
break;
case self::TYPE_STATUS:
if ($new == PhabricatorDashboard::STATUS_ACTIVE) {
return pht(
'%s activated dashboard %s.',
$author_link,
$object_link);
} else {
return pht(
'%s archived dashboard %s.',
$author_link,
$object_link);
}
break;
} }
return parent::getTitleForFeed(); return parent::getTitleForFeed();
@ -83,11 +110,39 @@ final class PhabricatorDashboardTransaction
return PhabricatorTransactions::COLOR_GREEN; return PhabricatorTransactions::COLOR_GREEN;
} }
break; break;
case self::TYPE_STATUS:
if ($new == PhabricatorDashboard::STATUS_ACTIVE) {
return PhabricatorTransactions::COLOR_GREEN;
} else {
return PhabricatorTransactions::COLOR_INDIGO;
}
break;
} }
return parent::getColor(); return parent::getColor();
} }
public function getIcon() {
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_NAME:
return 'fa-pencil';
break;
case self::TYPE_STATUS:
if ($new == PhabricatorDashboard::STATUS_ACTIVE) {
return 'fa-check';
} else {
return 'fa-ban';
}
break;
case self::TYPE_LAYOUT_MODE:
return 'fa-columns';
break;
}
return parent::getIcon();
}
public function shouldHide() { public function shouldHide() {
$old = $this->getOldValue(); $old = $this->getOldValue();
$new = $this->getNewValue(); $new = $this->getNewValue();