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:
parent
d0c09ef867
commit
18757e43de
7 changed files with 113 additions and 6 deletions
|
@ -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',
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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'));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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',
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue