From c22d6c7beb08c48927c8929933ef70e4100c15fc Mon Sep 17 00:00:00 2001 From: Chad Little Date: Thu, 23 Jul 2015 14:22:56 -0700 Subject: [PATCH] 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 --- .../sql/autopatches/20150722.dashboard.1.sql | 2 + .../sql/autopatches/20150722.dashboard.2.sql | 2 + .../PhabricatorDashboardEditController.php | 14 ++++- .../PhabricatorDashboardManageController.php | 15 ++++- .../PhabricatorDashboardTransactionEditor.php | 11 ++++ .../query/PhabricatorDashboardQuery.php | 13 +++++ .../PhabricatorDashboardSearchEngine.php | 44 ++++++++++++++- .../storage/PhabricatorDashboard.php | 17 ++++++ .../PhabricatorDashboardTransaction.php | 55 +++++++++++++++++++ 9 files changed, 169 insertions(+), 4 deletions(-) create mode 100644 resources/sql/autopatches/20150722.dashboard.1.sql create mode 100644 resources/sql/autopatches/20150722.dashboard.2.sql diff --git a/resources/sql/autopatches/20150722.dashboard.1.sql b/resources/sql/autopatches/20150722.dashboard.1.sql new file mode 100644 index 0000000000..1cd135e48c --- /dev/null +++ b/resources/sql/autopatches/20150722.dashboard.1.sql @@ -0,0 +1,2 @@ +ALTER TABLE {$NAMESPACE}_dashboard.dashboard + ADD status VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20150722.dashboard.2.sql b/resources/sql/autopatches/20150722.dashboard.2.sql new file mode 100644 index 0000000000..21a9a2ab88 --- /dev/null +++ b/resources/sql/autopatches/20150722.dashboard.2.sql @@ -0,0 +1,2 @@ +UPDATE {$NAMESPACE}_dashboard.dashboard + SET status = 'open'; diff --git a/src/applications/dashboard/controller/PhabricatorDashboardEditController.php b/src/applications/dashboard/controller/PhabricatorDashboardEditController.php index 16fdac5577..01ab487b6e 100644 --- a/src/applications/dashboard/controller/PhabricatorDashboardEditController.php +++ b/src/applications/dashboard/controller/PhabricatorDashboardEditController.php @@ -67,6 +67,7 @@ final class PhabricatorDashboardEditController } $v_name = $dashboard->getName(); + $v_stat = $dashboard->getStatus(); $v_layout_mode = $dashboard->getLayoutConfigObject()->getLayoutMode(); $e_name = true; @@ -77,11 +78,13 @@ final class PhabricatorDashboardEditController $v_view_policy = $request->getStr('viewPolicy'); $v_edit_policy = $request->getStr('editPolicy'); $v_projects = $request->getArr('projects'); + $v_stat = $request->getStr('status'); $xactions = array(); $type_name = PhabricatorDashboardTransaction::TYPE_NAME; $type_layout_mode = PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE; + $type_stat = PhabricatorDashboardTransaction::TYPE_STATUS; $type_view_policy = PhabricatorTransactions::TYPE_VIEW_POLICY; $type_edit_policy = PhabricatorTransactions::TYPE_EDIT_POLICY; @@ -97,6 +100,9 @@ final class PhabricatorDashboardEditController $xactions[] = id(new PhabricatorDashboardTransaction()) ->setTransactionType($type_edit_policy) ->setNewValue($v_edit_policy); + $xactions[] = id(new PhabricatorDashboardTransaction()) + ->setTransactionType($type_stat) + ->setNewValue($v_stat); $proj_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST; $xactions[] = id(new PhabricatorDashboardTransaction()) @@ -157,7 +163,13 @@ final class PhabricatorDashboardEditController ->setLabel(pht('Layout Mode')) ->setName('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( id(new AphrontFormTokenizerControl()) diff --git a/src/applications/dashboard/controller/PhabricatorDashboardManageController.php b/src/applications/dashboard/controller/PhabricatorDashboardManageController.php index 58e9c1c20a..1719687b0d 100644 --- a/src/applications/dashboard/controller/PhabricatorDashboardManageController.php +++ b/src/applications/dashboard/controller/PhabricatorDashboardManageController.php @@ -81,10 +81,23 @@ final class PhabricatorDashboardManageController private function buildHeaderView(PhabricatorDashboard $dashboard) { $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()) ->setUser($viewer) ->setHeader($dashboard->getName()) - ->setPolicyObject($dashboard); + ->setPolicyObject($dashboard) + ->setStatus($status_icon, $status_color, $status_name); } private function buildActionView(PhabricatorDashboard $dashboard) { diff --git a/src/applications/dashboard/editor/PhabricatorDashboardTransactionEditor.php b/src/applications/dashboard/editor/PhabricatorDashboardTransactionEditor.php index 4b1b6533d6..6cb7810d0b 100644 --- a/src/applications/dashboard/editor/PhabricatorDashboardTransactionEditor.php +++ b/src/applications/dashboard/editor/PhabricatorDashboardTransactionEditor.php @@ -51,6 +51,7 @@ final class PhabricatorDashboardTransactionEditor $types[] = PhabricatorTransactions::TYPE_EDGE; $types[] = PhabricatorDashboardTransaction::TYPE_NAME; + $types[] = PhabricatorDashboardTransaction::TYPE_STATUS; $types[] = PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE; return $types; @@ -65,6 +66,11 @@ final class PhabricatorDashboardTransactionEditor return null; } return $object->getName(); + case PhabricatorDashboardTransaction::TYPE_STATUS: + if ($this->getIsNewObject()) { + return null; + } + return $object->getStatus(); case PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE: if ($this->getIsNewObject()) { return null; @@ -81,6 +87,7 @@ final class PhabricatorDashboardTransactionEditor PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PhabricatorDashboardTransaction::TYPE_NAME: + case PhabricatorDashboardTransaction::TYPE_STATUS: case PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE: return $xaction->getNewValue(); } @@ -94,6 +101,9 @@ final class PhabricatorDashboardTransactionEditor case PhabricatorDashboardTransaction::TYPE_NAME: $object->setName($xaction->getNewValue()); return; + case PhabricatorDashboardTransaction::TYPE_STATUS: + $object->setStatus($xaction->getNewValue()); + return; case PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE: $old_layout = $object->getLayoutConfigObject(); $new_layout = clone $old_layout; @@ -120,6 +130,7 @@ final class PhabricatorDashboardTransactionEditor switch ($xaction->getTransactionType()) { case PhabricatorDashboardTransaction::TYPE_NAME: + case PhabricatorDashboardTransaction::TYPE_STATUS: case PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE: return; } diff --git a/src/applications/dashboard/query/PhabricatorDashboardQuery.php b/src/applications/dashboard/query/PhabricatorDashboardQuery.php index f1fe0047db..55cd447c7a 100644 --- a/src/applications/dashboard/query/PhabricatorDashboardQuery.php +++ b/src/applications/dashboard/query/PhabricatorDashboardQuery.php @@ -5,6 +5,7 @@ final class PhabricatorDashboardQuery private $ids; private $phids; + private $statuses; private $needPanels; private $needProjects; @@ -19,6 +20,11 @@ final class PhabricatorDashboardQuery return $this; } + public function withStatuses(array $statuses) { + $this->statuses = $statuses; + return $this; + } + public function needPanels($need_panels) { $this->needPanels = $need_panels; return $this; @@ -108,6 +114,13 @@ final class PhabricatorDashboardQuery $this->phids); } + if ($this->statuses !== null) { + $where[] = qsprintf( + $conn, + 'status IN (%Ls)', + $this->statuses); + } + return $where; } diff --git a/src/applications/dashboard/query/PhabricatorDashboardSearchEngine.php b/src/applications/dashboard/query/PhabricatorDashboardSearchEngine.php index 6aa0b43c8d..b7125e17e5 100644 --- a/src/applications/dashboard/query/PhabricatorDashboardSearchEngine.php +++ b/src/applications/dashboard/query/PhabricatorDashboardSearchEngine.php @@ -17,7 +17,12 @@ final class PhabricatorDashboardSearchEngine } protected function buildCustomSearchFields() { - return array(); + return array( + id(new PhabricatorSearchCheckboxesField()) + ->setKey('statuses') + ->setLabel(pht('Status')) + ->setOptions(PhabricatorDashboard::getStatusNameMap()), + ); } protected function getURI($path) { @@ -26,18 +31,24 @@ final class PhabricatorDashboardSearchEngine protected function getBuiltinQueryNames() { return array( + 'open' => pht('Active Dashboards'), 'all' => pht('All Dashboards'), ); } public function buildSavedQueryFromBuiltin($query_key) { - $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; + case 'open': + return $query->setParameter( + 'statuses', + array( + PhabricatorDashboard::STATUS_ACTIVE, + )); } return parent::buildSavedQueryFromBuiltin($query_key); @@ -45,6 +56,11 @@ final class PhabricatorDashboardSearchEngine protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); + + if ($map['statuses']) { + $query->withStatuses($map['statuses']); + } + return $query; } @@ -124,6 +140,30 @@ final class PhabricatorDashboardSearchEngine ->setSlim(true) ->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); } diff --git a/src/applications/dashboard/storage/PhabricatorDashboard.php b/src/applications/dashboard/storage/PhabricatorDashboard.php index df921b4414..371005b99c 100644 --- a/src/applications/dashboard/storage/PhabricatorDashboard.php +++ b/src/applications/dashboard/storage/PhabricatorDashboard.php @@ -14,8 +14,12 @@ final class PhabricatorDashboard extends PhabricatorDashboardDAO protected $name; protected $viewPolicy; protected $editPolicy; + protected $status; protected $layoutConfig = array(); + const STATUS_ACTIVE = 'active'; + const STATUS_ARCHIVED = 'archived'; + private $panelPHIDs = self::ATTACHABLE; private $panels = self::ATTACHABLE; private $edgeProjectPHIDs = self::ATTACHABLE; @@ -26,10 +30,18 @@ final class PhabricatorDashboard extends PhabricatorDashboardDAO ->setName('') ->setViewPolicy(PhabricatorPolicies::POLICY_USER) ->setEditPolicy($actor->getPHID()) + ->setStatus(self::STATUS_ACTIVE) ->attachPanels(array()) ->attachPanelPHIDs(array()); } + public static function getStatusNameMap() { + return array( + self::STATUS_ACTIVE => pht('Active'), + self::STATUS_ARCHIVED => pht('Archived'), + ); + } + public static function copyDashboard( PhabricatorDashboard $dst, PhabricatorDashboard $src) { @@ -48,6 +60,7 @@ final class PhabricatorDashboard extends PhabricatorDashboardDAO ), self::CONFIG_COLUMN_SCHEMA => array( 'name' => 'text255', + 'status' => 'text32', ), ) + parent::getConfiguration(); } @@ -96,6 +109,10 @@ final class PhabricatorDashboard extends PhabricatorDashboardDAO return $this->assertAttached($this->panels); } + public function isClosed() { + return ($this->getStatus() == self::STATUS_ARCHIVED); + } + /* -( PhabricatorApplicationTransactionInterface )------------------------- */ diff --git a/src/applications/dashboard/storage/PhabricatorDashboardTransaction.php b/src/applications/dashboard/storage/PhabricatorDashboardTransaction.php index a6ecdf9589..70b5963f03 100644 --- a/src/applications/dashboard/storage/PhabricatorDashboardTransaction.php +++ b/src/applications/dashboard/storage/PhabricatorDashboardTransaction.php @@ -4,6 +4,7 @@ final class PhabricatorDashboardTransaction extends PhabricatorApplicationTransaction { const TYPE_NAME = 'dashboard:name'; + const TYPE_STATUS = 'dashboard:status'; const TYPE_LAYOUT_MODE = 'dashboard:layoutmode'; public function getApplicationName() { @@ -37,6 +38,18 @@ final class PhabricatorDashboardTransaction $old, $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(); @@ -68,6 +81,20 @@ final class PhabricatorDashboardTransaction $old, $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(); @@ -83,11 +110,39 @@ final class PhabricatorDashboardTransaction return PhabricatorTransactions::COLOR_GREEN; } break; + case self::TYPE_STATUS: + if ($new == PhabricatorDashboard::STATUS_ACTIVE) { + return PhabricatorTransactions::COLOR_GREEN; + } else { + return PhabricatorTransactions::COLOR_INDIGO; + } + break; } 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() { $old = $this->getOldValue(); $new = $this->getNewValue(); -- 2.51.2