1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-27 01:02:42 +01:00

Allow entire dashboards to be copied

Summary:
Further improve UX for dealing with policy rules on dashboards:

  - When in the "Manage" view of a dashboard you can not edit:
    - Don't show the panel management controls.
    - Show a notice that the board isn't editable, recommending you make a copy instead.
  - Add a "Copy Dashboard" action to create a copy which you //can// edit.

Test Plan: Copied some dashboards. See screenshots.

Reviewers: chad

Reviewed By: chad

Subscribers: epriestley

Differential Revision: https://secure.phabricator.com/D9508
This commit is contained in:
epriestley 2014-06-12 21:49:19 -07:00
parent d0c09ef867
commit 18757e43de
7 changed files with 113 additions and 6 deletions

View file

@ -7,7 +7,7 @@
return array( return array(
'names' => 'names' =>
array( array(
'core.pkg.css' => '3a40ccda', 'core.pkg.css' => 'db38c2c9',
'core.pkg.js' => '8335fe3f', 'core.pkg.js' => '8335fe3f',
'darkconsole.pkg.js' => 'ca8671ce', 'darkconsole.pkg.js' => 'ca8671ce',
'differential.pkg.css' => '4a93db37', 'differential.pkg.css' => '4a93db37',
@ -38,7 +38,7 @@ return array(
'rsrc/css/application/auth/auth.css' => '1e655982', 'rsrc/css/application/auth/auth.css' => '1e655982',
'rsrc/css/application/base/main-menu-view.css' => '72d1d2ef', 'rsrc/css/application/base/main-menu-view.css' => '72d1d2ef',
'rsrc/css/application/base/notification-menu.css' => 'cbff1b94', 'rsrc/css/application/base/notification-menu.css' => 'cbff1b94',
'rsrc/css/application/base/phabricator-application-launch-view.css' => '81bebcff', 'rsrc/css/application/base/phabricator-application-launch-view.css' => '8b7e271d',
'rsrc/css/application/base/standard-page-view.css' => '517cdfb1', 'rsrc/css/application/base/standard-page-view.css' => '517cdfb1',
'rsrc/css/application/chatlog/chatlog.css' => '852140ff', 'rsrc/css/application/chatlog/chatlog.css' => '852140ff',
'rsrc/css/application/config/config-options.css' => '7fedf08b', 'rsrc/css/application/config/config-options.css' => '7fedf08b',
@ -687,7 +687,7 @@ return array(
'people-profile-css' => 'ba7b2762', 'people-profile-css' => 'ba7b2762',
'phabricator-action-header-view-css' => 'f11f18b5', 'phabricator-action-header-view-css' => 'f11f18b5',
'phabricator-action-list-view-css' => 'dcbfc854', 'phabricator-action-list-view-css' => 'dcbfc854',
'phabricator-application-launch-view-css' => '81bebcff', 'phabricator-application-launch-view-css' => '8b7e271d',
'phabricator-busy' => '6453c869', 'phabricator-busy' => '6453c869',
'phabricator-chatlog-css' => '852140ff', 'phabricator-chatlog-css' => '852140ff',
'phabricator-content-source-view-css' => '4b8b05d4', 'phabricator-content-source-view-css' => '4b8b05d4',

View file

@ -1475,6 +1475,7 @@ phutil_register_library_map(array(
'PhabricatorDashboard' => 'applications/dashboard/storage/PhabricatorDashboard.php', 'PhabricatorDashboard' => 'applications/dashboard/storage/PhabricatorDashboard.php',
'PhabricatorDashboardAddPanelController' => 'applications/dashboard/controller/PhabricatorDashboardAddPanelController.php', 'PhabricatorDashboardAddPanelController' => 'applications/dashboard/controller/PhabricatorDashboardAddPanelController.php',
'PhabricatorDashboardController' => 'applications/dashboard/controller/PhabricatorDashboardController.php', 'PhabricatorDashboardController' => 'applications/dashboard/controller/PhabricatorDashboardController.php',
'PhabricatorDashboardCopyController' => 'applications/dashboard/controller/PhabricatorDashboardCopyController.php',
'PhabricatorDashboardDAO' => 'applications/dashboard/storage/PhabricatorDashboardDAO.php', 'PhabricatorDashboardDAO' => 'applications/dashboard/storage/PhabricatorDashboardDAO.php',
'PhabricatorDashboardEditController' => 'applications/dashboard/controller/PhabricatorDashboardEditController.php', 'PhabricatorDashboardEditController' => 'applications/dashboard/controller/PhabricatorDashboardEditController.php',
'PhabricatorDashboardHistoryController' => 'applications/dashboard/controller/PhabricatorDashboardHistoryController.php', 'PhabricatorDashboardHistoryController' => 'applications/dashboard/controller/PhabricatorDashboardHistoryController.php',
@ -3914,7 +3915,7 @@ phutil_register_library_map(array(
'PhabricatorApplicationHelp' => 'PhabricatorApplication', 'PhabricatorApplicationHelp' => 'PhabricatorApplication',
'PhabricatorApplicationHerald' => 'PhabricatorApplication', 'PhabricatorApplicationHerald' => 'PhabricatorApplication',
'PhabricatorApplicationHome' => 'PhabricatorApplication', 'PhabricatorApplicationHome' => 'PhabricatorApplication',
'PhabricatorApplicationLaunchView' => 'AphrontView', 'PhabricatorApplicationLaunchView' => 'AphrontTagView',
'PhabricatorApplicationLegalpad' => 'PhabricatorApplication', 'PhabricatorApplicationLegalpad' => 'PhabricatorApplication',
'PhabricatorApplicationMacro' => 'PhabricatorApplication', 'PhabricatorApplicationMacro' => 'PhabricatorApplication',
'PhabricatorApplicationMailingLists' => 'PhabricatorApplication', 'PhabricatorApplicationMailingLists' => 'PhabricatorApplication',
@ -4291,6 +4292,7 @@ phutil_register_library_map(array(
), ),
'PhabricatorDashboardAddPanelController' => 'PhabricatorDashboardController', 'PhabricatorDashboardAddPanelController' => 'PhabricatorDashboardController',
'PhabricatorDashboardController' => 'PhabricatorController', 'PhabricatorDashboardController' => 'PhabricatorController',
'PhabricatorDashboardCopyController' => 'PhabricatorDashboardController',
'PhabricatorDashboardDAO' => 'PhabricatorLiskDAO', 'PhabricatorDashboardDAO' => 'PhabricatorLiskDAO',
'PhabricatorDashboardEditController' => 'PhabricatorDashboardController', 'PhabricatorDashboardEditController' => 'PhabricatorDashboardController',
'PhabricatorDashboardHistoryController' => 'PhabricatorDashboardController', 'PhabricatorDashboardHistoryController' => 'PhabricatorDashboardController',

View file

@ -24,6 +24,7 @@ final class PhabricatorApplicationDashboard extends PhabricatorApplication {
'manage/(?P<id>\d+)/' => 'PhabricatorDashboardManageController', 'manage/(?P<id>\d+)/' => 'PhabricatorDashboardManageController',
'history/(?P<id>\d+)/' => 'PhabricatorDashboardHistoryController', 'history/(?P<id>\d+)/' => 'PhabricatorDashboardHistoryController',
'create/' => 'PhabricatorDashboardEditController', 'create/' => 'PhabricatorDashboardEditController',
'copy/(?:(?P<id>\d+)/)?' => 'PhabricatorDashboardCopyController',
'edit/(?:(?P<id>\d+)/)?' => 'PhabricatorDashboardEditController', 'edit/(?:(?P<id>\d+)/)?' => 'PhabricatorDashboardEditController',
'install/(?P<id>\d+)/' => 'PhabricatorDashboardInstallController', 'install/(?P<id>\d+)/' => 'PhabricatorDashboardInstallController',
'uninstall/(?P<id>\d+)/' => 'PhabricatorDashboardUninstallController', 'uninstall/(?P<id>\d+)/' => 'PhabricatorDashboardUninstallController',

View file

@ -0,0 +1,68 @@
<?php
final class PhabricatorDashboardCopyController
extends PhabricatorDashboardController {
private $id;
public function willProcessRequest(array $data) {
$this->id = idx($data, 'id');
}
public function processRequest() {
$request = $this->getRequest();
$viewer = $request->getUser();
$dashboard = id(new PhabricatorDashboardQuery())
->setViewer($viewer)
->withIDs(array($this->id))
->needPanels(true)
->executeOne();
if (!$dashboard) {
return new Aphront404Response();
}
$manage_uri = $this->getApplicationURI('manage/'.$dashboard->getID().'/');
if ($request->isFormPost()) {
$copy = PhabricatorDashboard::initializeNewDashboard($viewer);
$copy = PhabricatorDashboard::copyDashboard($copy, $dashboard);
$copy->setName(pht('Copy of %s', $copy->getName()));
// Set up all the edges for the new dashboard.
$xactions = array();
$xactions[] = id(new PhabricatorDashboardTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
->setMetadataValue(
'edge:type',
PhabricatorEdgeConfig::TYPE_DASHBOARD_HAS_PANEL)
->setNewValue(
array(
'=' => array_fuse($dashboard->getPanelPHIDs()),
));
$editor = id(new PhabricatorDashboardTransactionEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnMissingFields(true)
->setContinueOnNoEffect(true)
->applyTransactions($copy, $xactions);
$manage_uri = $this->getApplicationURI('edit/'.$copy->getID().'/');
return id(new AphrontRedirectResponse())->setURI($manage_uri);
}
return $this->newDialog()
->setTitle(pht('Copy Dashboard'))
->appendParagraph(
pht(
'Create a copy of the dashboard "%s"?',
phutil_tag('strong', array(), $dashboard->getName())))
->addCancelButton($manage_uri)
->addSubmitButton(pht('Create Copy'));
}
}

View file

@ -28,6 +28,11 @@ final class PhabricatorDashboardManageController
return new Aphront404Response(); return new Aphront404Response();
} }
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$dashboard,
PhabricatorPolicyCapability::CAN_EDIT);
$title = $dashboard->getName(); $title = $dashboard->getName();
$crumbs = $this->buildApplicationCrumbs(); $crumbs = $this->buildApplicationCrumbs();
@ -45,10 +50,21 @@ final class PhabricatorDashboardManageController
->setHeader($header) ->setHeader($header)
->addPropertyList($properties); ->addPropertyList($properties);
if (!$can_edit) {
$no_edit = pht(
'You do not have permission to edit this dashboard. If you want to '.
'make changes, make a copy first.');
$box->setErrorView(
id(new AphrontErrorView())
->setSeverity(AphrontErrorView::SEVERITY_NOTICE)
->setErrors(array($no_edit)));
}
$rendered_dashboard = id(new PhabricatorDashboardRenderingEngine()) $rendered_dashboard = id(new PhabricatorDashboardRenderingEngine())
->setViewer($viewer) ->setViewer($viewer)
->setDashboard($dashboard) ->setDashboard($dashboard)
->setArrangeMode(true) ->setArrangeMode($can_edit)
->renderDashboard(); ->renderDashboard();
return $this->buildApplicationPage( return $this->buildApplicationPage(
@ -93,6 +109,13 @@ final class PhabricatorDashboardManageController
->setDisabled(!$can_edit) ->setDisabled(!$can_edit)
->setWorkflow(!$can_edit)); ->setWorkflow(!$can_edit));
$actions->addAction(
id(new PhabricatorActionView())
->setName(pht('Copy Dashboard'))
->setIcon('fa-files-o')
->setHref($this->getApplicationURI("copy/{$id}/"))
->setWorkflow(true));
$installed_dashboard = id(new PhabricatorDashboardInstall()) $installed_dashboard = id(new PhabricatorDashboardInstall())
->loadOneWhere( ->loadOneWhere(
'objectPHID = %s AND applicationClass = %s', 'objectPHID = %s AND applicationClass = %s',

View file

@ -23,6 +23,16 @@ final class PhabricatorDashboard extends PhabricatorDashboardDAO
->attachPanelPHIDs(array()); ->attachPanelPHIDs(array());
} }
public static function copyDashboard(
PhabricatorDashboard $dst,
PhabricatorDashboard $src) {
$dst->name = $src->name;
$dst->layoutConfig = $src->layoutConfig;
return $dst;
}
public function getConfiguration() { public function getConfiguration() {
return array( return array(
self::CONFIG_AUX_PHID => true, self::CONFIG_AUX_PHID => true,

View file

@ -24,7 +24,10 @@ final class PhabricatorDashboardPanel
->setEditPolicy($actor->getPHID()); ->setEditPolicy($actor->getPHID());
} }
public static function copyPanel($dst, $src) { public static function copyPanel(
PhabricatorDashboardPanel $dst,
PhabricatorDashboardPanel $src) {
$dst->name = $src->name; $dst->name = $src->name;
$dst->panelType = $src->panelType; $dst->panelType = $src->panelType;
$dst->properties = $src->properties; $dst->properties = $src->properties;