diff --git a/resources/celerity/map.php b/resources/celerity/map.php index dcaaf112b3..a1143b0eb1 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -7,7 +7,7 @@ return array( 'names' => array( - 'core.pkg.css' => '3a40ccda', + 'core.pkg.css' => 'db38c2c9', 'core.pkg.js' => '8335fe3f', 'darkconsole.pkg.js' => 'ca8671ce', 'differential.pkg.css' => '4a93db37', @@ -38,7 +38,7 @@ return array( 'rsrc/css/application/auth/auth.css' => '1e655982', 'rsrc/css/application/base/main-menu-view.css' => '72d1d2ef', '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/chatlog/chatlog.css' => '852140ff', 'rsrc/css/application/config/config-options.css' => '7fedf08b', @@ -687,7 +687,7 @@ return array( 'people-profile-css' => 'ba7b2762', 'phabricator-action-header-view-css' => 'f11f18b5', 'phabricator-action-list-view-css' => 'dcbfc854', - 'phabricator-application-launch-view-css' => '81bebcff', + 'phabricator-application-launch-view-css' => '8b7e271d', 'phabricator-busy' => '6453c869', 'phabricator-chatlog-css' => '852140ff', 'phabricator-content-source-view-css' => '4b8b05d4', diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 85a8c6e13e..77cd6aad34 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1475,6 +1475,7 @@ phutil_register_library_map(array( 'PhabricatorDashboard' => 'applications/dashboard/storage/PhabricatorDashboard.php', 'PhabricatorDashboardAddPanelController' => 'applications/dashboard/controller/PhabricatorDashboardAddPanelController.php', 'PhabricatorDashboardController' => 'applications/dashboard/controller/PhabricatorDashboardController.php', + 'PhabricatorDashboardCopyController' => 'applications/dashboard/controller/PhabricatorDashboardCopyController.php', 'PhabricatorDashboardDAO' => 'applications/dashboard/storage/PhabricatorDashboardDAO.php', 'PhabricatorDashboardEditController' => 'applications/dashboard/controller/PhabricatorDashboardEditController.php', 'PhabricatorDashboardHistoryController' => 'applications/dashboard/controller/PhabricatorDashboardHistoryController.php', @@ -3914,7 +3915,7 @@ phutil_register_library_map(array( 'PhabricatorApplicationHelp' => 'PhabricatorApplication', 'PhabricatorApplicationHerald' => 'PhabricatorApplication', 'PhabricatorApplicationHome' => 'PhabricatorApplication', - 'PhabricatorApplicationLaunchView' => 'AphrontView', + 'PhabricatorApplicationLaunchView' => 'AphrontTagView', 'PhabricatorApplicationLegalpad' => 'PhabricatorApplication', 'PhabricatorApplicationMacro' => 'PhabricatorApplication', 'PhabricatorApplicationMailingLists' => 'PhabricatorApplication', @@ -4291,6 +4292,7 @@ phutil_register_library_map(array( ), 'PhabricatorDashboardAddPanelController' => 'PhabricatorDashboardController', 'PhabricatorDashboardController' => 'PhabricatorController', + 'PhabricatorDashboardCopyController' => 'PhabricatorDashboardController', 'PhabricatorDashboardDAO' => 'PhabricatorLiskDAO', 'PhabricatorDashboardEditController' => 'PhabricatorDashboardController', 'PhabricatorDashboardHistoryController' => 'PhabricatorDashboardController', diff --git a/src/applications/dashboard/application/PhabricatorApplicationDashboard.php b/src/applications/dashboard/application/PhabricatorApplicationDashboard.php index 220a492714..c47c317cf0 100644 --- a/src/applications/dashboard/application/PhabricatorApplicationDashboard.php +++ b/src/applications/dashboard/application/PhabricatorApplicationDashboard.php @@ -24,6 +24,7 @@ final class PhabricatorApplicationDashboard extends PhabricatorApplication { 'manage/(?P\d+)/' => 'PhabricatorDashboardManageController', 'history/(?P\d+)/' => 'PhabricatorDashboardHistoryController', 'create/' => 'PhabricatorDashboardEditController', + 'copy/(?:(?P\d+)/)?' => 'PhabricatorDashboardCopyController', 'edit/(?:(?P\d+)/)?' => 'PhabricatorDashboardEditController', 'install/(?P\d+)/' => 'PhabricatorDashboardInstallController', 'uninstall/(?P\d+)/' => 'PhabricatorDashboardUninstallController', diff --git a/src/applications/dashboard/controller/PhabricatorDashboardCopyController.php b/src/applications/dashboard/controller/PhabricatorDashboardCopyController.php new file mode 100644 index 0000000000..4641158a58 --- /dev/null +++ b/src/applications/dashboard/controller/PhabricatorDashboardCopyController.php @@ -0,0 +1,68 @@ +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')); + } + +} diff --git a/src/applications/dashboard/controller/PhabricatorDashboardManageController.php b/src/applications/dashboard/controller/PhabricatorDashboardManageController.php index 077b428fa5..7eb1238780 100644 --- a/src/applications/dashboard/controller/PhabricatorDashboardManageController.php +++ b/src/applications/dashboard/controller/PhabricatorDashboardManageController.php @@ -28,6 +28,11 @@ final class PhabricatorDashboardManageController return new Aphront404Response(); } + $can_edit = PhabricatorPolicyFilter::hasCapability( + $viewer, + $dashboard, + PhabricatorPolicyCapability::CAN_EDIT); + $title = $dashboard->getName(); $crumbs = $this->buildApplicationCrumbs(); @@ -45,10 +50,21 @@ final class PhabricatorDashboardManageController ->setHeader($header) ->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()) ->setViewer($viewer) ->setDashboard($dashboard) - ->setArrangeMode(true) + ->setArrangeMode($can_edit) ->renderDashboard(); return $this->buildApplicationPage( @@ -93,6 +109,13 @@ final class PhabricatorDashboardManageController ->setDisabled(!$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()) ->loadOneWhere( 'objectPHID = %s AND applicationClass = %s', diff --git a/src/applications/dashboard/storage/PhabricatorDashboard.php b/src/applications/dashboard/storage/PhabricatorDashboard.php index 48413168ab..ef4955df20 100644 --- a/src/applications/dashboard/storage/PhabricatorDashboard.php +++ b/src/applications/dashboard/storage/PhabricatorDashboard.php @@ -23,6 +23,16 @@ final class PhabricatorDashboard extends PhabricatorDashboardDAO ->attachPanelPHIDs(array()); } + public static function copyDashboard( + PhabricatorDashboard $dst, + PhabricatorDashboard $src) { + + $dst->name = $src->name; + $dst->layoutConfig = $src->layoutConfig; + + return $dst; + } + public function getConfiguration() { return array( self::CONFIG_AUX_PHID => true, diff --git a/src/applications/dashboard/storage/PhabricatorDashboardPanel.php b/src/applications/dashboard/storage/PhabricatorDashboardPanel.php index 530277295c..b5625117e9 100644 --- a/src/applications/dashboard/storage/PhabricatorDashboardPanel.php +++ b/src/applications/dashboard/storage/PhabricatorDashboardPanel.php @@ -24,7 +24,10 @@ final class PhabricatorDashboardPanel ->setEditPolicy($actor->getPHID()); } - public static function copyPanel($dst, $src) { + public static function copyPanel( + PhabricatorDashboardPanel $dst, + PhabricatorDashboardPanel $src) { + $dst->name = $src->name; $dst->panelType = $src->panelType; $dst->properties = $src->properties;