1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-01-14 16:51:08 +01:00

Dashboards - add ability to install dashboard as home

Summary:
See title. Adds PhabricatorDashboardInstall data object which scopes installs to objectPHID + applicationClass. This is because we already have a collision for user home pages and user profiles. Assume only one dashboard per objectPHID + applicationClass though at the database level.

Fixes T5076.

Test Plan: From dashboard view, installed a dashboard - success! Went back to dashboard view and uninstalled it!

Reviewers: chad, epriestley

Reviewed By: epriestley

Subscribers: epriestley, Korvin

Maniphest Tasks: T5076

Differential Revision: https://secure.phabricator.com/D9206
This commit is contained in:
Bob Trahan 2014-05-19 16:09:31 -07:00
parent d9058d7f3f
commit 5f33aa5b4f
8 changed files with 380 additions and 15 deletions

View file

@ -0,0 +1,10 @@
CREATE TABLE {$NAMESPACE}_dashboard.dashboard_install (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
installerPHID VARCHAR(64) NOT NULL COLLATE utf8_bin,
objectPHID VARCHAR(64) NOT NULL COLLATE utf8_bin,
applicationClass VARCHAR(64) NOT NULL COLLATE utf8_bin,
dashboardPHID VARCHAR(64) NOT NULL COLLATE utf8_bin,
dateCreated INT UNSIGNED NOT NULL,
dateModified INT UNSIGNED NOT NULL,
UNIQUE KEY (objectPHID, applicationClass)
) ENGINE=InnoDB, COLLATE utf8_general_ci;

View file

@ -1463,6 +1463,8 @@ phutil_register_library_map(array(
'PhabricatorDashboardController' => 'applications/dashboard/controller/PhabricatorDashboardController.php', 'PhabricatorDashboardController' => 'applications/dashboard/controller/PhabricatorDashboardController.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',
'PhabricatorDashboardInstall' => 'applications/dashboard/storage/PhabricatorDashboardInstall.php',
'PhabricatorDashboardInstallController' => 'applications/dashboard/controller/PhabricatorDashboardInstallController.php',
'PhabricatorDashboardLayoutConfig' => 'applications/dashboard/layoutconfig/PhabricatorDashboardLayoutConfig.php', 'PhabricatorDashboardLayoutConfig' => 'applications/dashboard/layoutconfig/PhabricatorDashboardLayoutConfig.php',
'PhabricatorDashboardListController' => 'applications/dashboard/controller/PhabricatorDashboardListController.php', 'PhabricatorDashboardListController' => 'applications/dashboard/controller/PhabricatorDashboardListController.php',
'PhabricatorDashboardMovePanelController' => 'applications/dashboard/controller/PhabricatorDashboardMovePanelController.php', 'PhabricatorDashboardMovePanelController' => 'applications/dashboard/controller/PhabricatorDashboardMovePanelController.php',
@ -1493,6 +1495,7 @@ phutil_register_library_map(array(
'PhabricatorDashboardTransaction' => 'applications/dashboard/storage/PhabricatorDashboardTransaction.php', 'PhabricatorDashboardTransaction' => 'applications/dashboard/storage/PhabricatorDashboardTransaction.php',
'PhabricatorDashboardTransactionEditor' => 'applications/dashboard/editor/PhabricatorDashboardTransactionEditor.php', 'PhabricatorDashboardTransactionEditor' => 'applications/dashboard/editor/PhabricatorDashboardTransactionEditor.php',
'PhabricatorDashboardTransactionQuery' => 'applications/dashboard/query/PhabricatorDashboardTransactionQuery.php', 'PhabricatorDashboardTransactionQuery' => 'applications/dashboard/query/PhabricatorDashboardTransactionQuery.php',
'PhabricatorDashboardUninstallController' => 'applications/dashboard/controller/PhabricatorDashboardUninstallController.php',
'PhabricatorDashboardViewController' => 'applications/dashboard/controller/PhabricatorDashboardViewController.php', 'PhabricatorDashboardViewController' => 'applications/dashboard/controller/PhabricatorDashboardViewController.php',
'PhabricatorDataNotAttachedException' => 'infrastructure/storage/lisk/PhabricatorDataNotAttachedException.php', 'PhabricatorDataNotAttachedException' => 'infrastructure/storage/lisk/PhabricatorDataNotAttachedException.php',
'PhabricatorDebugController' => 'applications/system/controller/PhabricatorDebugController.php', 'PhabricatorDebugController' => 'applications/system/controller/PhabricatorDebugController.php',
@ -4247,6 +4250,8 @@ phutil_register_library_map(array(
'PhabricatorDashboardController' => 'PhabricatorController', 'PhabricatorDashboardController' => 'PhabricatorController',
'PhabricatorDashboardDAO' => 'PhabricatorLiskDAO', 'PhabricatorDashboardDAO' => 'PhabricatorLiskDAO',
'PhabricatorDashboardEditController' => 'PhabricatorDashboardController', 'PhabricatorDashboardEditController' => 'PhabricatorDashboardController',
'PhabricatorDashboardInstall' => 'PhabricatorDashboardDAO',
'PhabricatorDashboardInstallController' => 'PhabricatorDashboardController',
'PhabricatorDashboardListController' => 'PhabricatorDashboardController', 'PhabricatorDashboardListController' => 'PhabricatorDashboardController',
'PhabricatorDashboardMovePanelController' => 'PhabricatorDashboardController', 'PhabricatorDashboardMovePanelController' => 'PhabricatorDashboardController',
'PhabricatorDashboardPHIDTypeDashboard' => 'PhabricatorPHIDType', 'PhabricatorDashboardPHIDTypeDashboard' => 'PhabricatorPHIDType',
@ -4285,6 +4290,7 @@ phutil_register_library_map(array(
'PhabricatorDashboardTransaction' => 'PhabricatorApplicationTransaction', 'PhabricatorDashboardTransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorDashboardTransactionEditor' => 'PhabricatorApplicationTransactionEditor', 'PhabricatorDashboardTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorDashboardTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhabricatorDashboardTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorDashboardUninstallController' => 'PhabricatorDashboardController',
'PhabricatorDashboardViewController' => 'PhabricatorDashboardController', 'PhabricatorDashboardViewController' => 'PhabricatorDashboardController',
'PhabricatorDataNotAttachedException' => 'Exception', 'PhabricatorDataNotAttachedException' => 'Exception',
'PhabricatorDebugController' => 'PhabricatorController', 'PhabricatorDebugController' => 'PhabricatorController',

View file

@ -24,6 +24,8 @@ final class PhabricatorApplicationDashboard extends PhabricatorApplication {
'arrange/(?P<id>\d+)/' => 'PhabricatorDashboardArrangeController', 'arrange/(?P<id>\d+)/' => 'PhabricatorDashboardArrangeController',
'create/' => 'PhabricatorDashboardEditController', 'create/' => 'PhabricatorDashboardEditController',
'edit/(?:(?P<id>\d+)/)?' => 'PhabricatorDashboardEditController', 'edit/(?:(?P<id>\d+)/)?' => 'PhabricatorDashboardEditController',
'install/(?P<id>\d+)/' => 'PhabricatorDashboardInstallController',
'uninstall/(?P<id>\d+)/' => 'PhabricatorDashboardUninstallController',
'addpanel/(?P<id>\d+)/' => 'PhabricatorDashboardAddPanelController', 'addpanel/(?P<id>\d+)/' => 'PhabricatorDashboardAddPanelController',
'movepanel/(?P<id>\d+)/' => 'PhabricatorDashboardMovePanelController', 'movepanel/(?P<id>\d+)/' => 'PhabricatorDashboardMovePanelController',
'removepanel/(?P<id>\d+)/' 'removepanel/(?P<id>\d+)/'

View file

@ -0,0 +1,139 @@
<?php
final class PhabricatorDashboardInstallController
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))
->executeOne();
if (!$dashboard) {
return new Aphront404Response();
}
$dashboard_phid = $dashboard->getPHID();
$object_phid = $request->getStr('objectPHID', $viewer->getPHID());
$object = id(new PhabricatorObjectQuery())
->setViewer($viewer)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->withPHIDs(array($object_phid))
->executeOne();
if (!$object) {
return new Aphront404Response();
}
$installer_phid = $viewer->getPHID();
$application_class = $request->getStr(
'applicationClass',
'PhabricatorApplicationHome');
$handles = $this->loadHandles(array(
$object_phid,
$installer_phid));
if ($request->isFormPost()) {
$dashboard_install = id(new PhabricatorDashboardInstall())
->loadOneWhere(
'objectPHID = %s AND applicationClass = %s',
$object_phid,
$application_class);
if (!$dashboard_install) {
$dashboard_install = id(new PhabricatorDashboardInstall())
->setObjectPHID($object_phid)
->setApplicationClass($application_class);
}
$dashboard_install
->setInstallerPHID($installer_phid)
->setDashboardPHID($dashboard_phid)
->save();
return id(new AphrontRedirectResponse())
->setURI($this->getRedirectURI($application_class, $object_phid));
}
$body = $this->getBodyContent(
$application_class,
$object_phid,
$installer_phid);
$form = id(new AphrontFormView())
->setUser($viewer)
->appendChild($body);
return $this->newDialog()
->setTitle(pht('Install Dashboard'))
->appendChild($form->buildLayoutView())
->addCancelButton($this->getCancelURI(
$application_class, $object_phid))
->addSubmitButton(pht('Install Dashboard'));
}
private function getBodyContent(
$application_class,
$object_phid,
$installer_phid) {
$body = array();
switch ($application_class) {
case 'PhabricatorApplicationHome':
if ($installer_phid == $object_phid) {
$body[] = phutil_tag(
'p',
array(),
pht(
'Are you sure you want to install this dashboard as your '.
'home page?'));
$body[] = phutil_tag(
'p',
array(),
pht(
'You will be re-directed to your spiffy new home page if you '.
'choose to install this dashboard.'));
} else {
$body[] = phutil_tag(
'p',
array(),
pht(
'Are you sure you want to install this dashboard as the home '.
'page for %s?',
$this->getHandle($object_phid)->getName()));
}
break;
}
return $body;
}
private function getCancelURI($application_class, $object_phid) {
$uri = null;
switch ($application_class) {
case 'PhabricatorApplicationHome':
$uri = '/dashboard/view/'.$this->id.'/';
break;
}
return $uri;
}
private function getRedirectURI($application_class, $object_phid) {
$uri = null;
switch ($application_class) {
case 'PhabricatorApplicationHome':
$uri = '/';
break;
}
return $uri;
}
}

View file

@ -0,0 +1,136 @@
<?php
final class PhabricatorDashboardUninstallController
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))
->executeOne();
if (!$dashboard) {
return new Aphront404Response();
}
$dashboard_phid = $dashboard->getPHID();
$object_phid = $request->getStr('objectPHID', $viewer->getPHID());
$object = id(new PhabricatorObjectQuery())
->setViewer($viewer)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->withPHIDs(array($object_phid))
->executeOne();
if (!$object) {
return new Aphront404Response();
}
$application_class = $request->getStr(
'applicationClass',
'PhabricatorApplicationHome');
$dashboard_install = id(new PhabricatorDashboardInstall())
->loadOneWhere(
'objectPHID = %s AND applicationClass = %s',
$object_phid,
$application_class);
if (!$dashboard_install) {
return new Aphront404Response();
}
if ($dashboard_install->getDashboardPHID() != $dashboard_phid) {
return new Aphront404Response();
}
$installer_phid = $viewer->getPHID();
$handles = $this->loadHandles(array($object_phid, $installer_phid));
if ($request->isFormPost()) {
$dashboard_install->delete();
return id(new AphrontRedirectResponse())
->setURI($this->getRedirectURI($application_class, $object_phid));
}
$body = $this->getBodyContent(
$application_class,
$object_phid,
$installer_phid);
$form = id(new AphrontFormView())
->setUser($viewer)
->appendChild($body);
return $this->newDialog()
->setTitle(pht('Uninstall Dashboard'))
->appendChild($form->buildLayoutView())
->addCancelButton($this->getCancelURI(
$application_class, $object_phid))
->addSubmitButton(pht('Uninstall Dashboard'));
}
private function getBodyContent(
$application_class,
$object_phid,
$installer_phid) {
$body = array();
switch ($application_class) {
case 'PhabricatorApplicationHome':
if ($installer_phid == $object_phid) {
$body[] = phutil_tag(
'p',
array(),
pht(
'Are you sure you want to uninstall this dashboard as your '.
'home page?'));
$body[] = phutil_tag(
'p',
array(),
pht(
'You will be re-directed to your bland, default home page if '.
'you choose to uninstall this dashboard.'));
} else {
$body[] = phutil_tag(
'p',
array(),
pht(
'Are you sure you want to uninstall this dashboard as the home '.
'page for %s?',
$this->getHandle($object_phid)->getName()));
}
break;
}
return $body;
}
private function getCancelURI($application_class, $object_phid) {
$uri = null;
switch ($application_class) {
case 'PhabricatorApplicationHome':
$uri = '/dashboard/view/'.$this->id.'/';
break;
}
return $uri;
}
private function getRedirectURI($application_class, $object_phid) {
$uri = null;
switch ($application_class) {
case 'PhabricatorApplicationHome':
$uri = '/';
break;
}
return $uri;
}
}

View file

@ -92,6 +92,26 @@ final class PhabricatorDashboardViewController
->setDisabled(!$can_edit) ->setDisabled(!$can_edit)
->setWorkflow(!$can_edit)); ->setWorkflow(!$can_edit));
$installed_dashboard = id(new PhabricatorDashboardInstall())
->loadOneWhere(
'objectPHID = %s AND applicationClass = %s',
$viewer->getPHID(),
'PhabricatorApplicationHome');
if ($installed_dashboard &&
$installed_dashboard->getDashboardPHID() == $dashboard->getPHID()) {
$title_install = pht('Uninstall Dashboard');
$href_install = "uninstall/{$id}/";
} else {
$title_install = pht('Install Dashboard');
$href_install = "install/{$id}/";
}
$actions->addAction(
id(new PhabricatorActionView())
->setName($title_install)
->setIcon('fa-wrench')
->setHref($this->getApplicationURI($href_install))
->setWorkflow(true));
$actions->addAction( $actions->addAction(
id(new PhabricatorActionView()) id(new PhabricatorActionView())
->setName(pht('Add Panel')) ->setName(pht('Add Panel'))

View file

@ -0,0 +1,38 @@
<?php
/**
* An install of a dashboard. Examples might be
* - the home page for a user
* - the profile page for a user
* - the profile page for a project
*/
final class PhabricatorDashboardInstall
extends PhabricatorDashboardDAO {
protected $installerPHID;
protected $objectPHID;
protected $applicationClass;
protected $dashboardPHID;
public static function getDashboard(
PhabricatorUser $viewer,
$object_phid,
$application_class) {
$dashboard = null;
$dashboard_install = id(new PhabricatorDashboardInstall())
->loadOneWhere(
'objectPHID = %s AND applicationClass = %s',
$object_phid,
$application_class);
if ($dashboard_install) {
$dashboard = id(new PhabricatorDashboardQuery())
->setViewer($viewer)
->withPHIDs(array($dashboard_install->getDashboardPHID()))
->needPanels(true)
->executeOne();
}
return $dashboard;
}
}

View file

@ -20,15 +20,36 @@ final class PhabricatorHomeMainController
if ($this->filter == 'jump') { if ($this->filter == 'jump') {
return $this->buildJumpResponse(); return $this->buildJumpResponse();
} }
$nav = $this->buildNav(); $nav = $this->buildNav();
$project_query = new PhabricatorProjectQuery(); $dashboard = PhabricatorDashboardInstall::getDashboard(
$project_query->setViewer($user); $user,
$project_query->withMemberPHIDs(array($user->getPHID())); $user->getPHID(),
$projects = $project_query->execute(); get_class($this->getCurrentApplication()));
if ($dashboard) {
$rendered_dashboard = id(new PhabricatorDashboardRenderingEngine())
->setViewer($user)
->setDashboard($dashboard)
->renderDashboard();
$nav->appendChild($rendered_dashboard);
} else {
$project_query = new PhabricatorProjectQuery();
$project_query->setViewer($user);
$project_query->withMemberPHIDs(array($user->getPHID()));
$projects = $project_query->execute();
return $this->buildMainResponse($nav, $projects); $nav = $this->buildMainResponse($nav, $projects);
}
$nav->appendChild(id(new PhabricatorGlobalUploadTargetView())
->setUser($user));
return $this->buildApplicationPage(
$nav,
array(
'title' => 'Phabricator',
'device' => true,
));
} }
private function buildMainResponse($nav, array $projects) { private function buildMainResponse($nav, array $projects) {
@ -91,17 +112,10 @@ final class PhabricatorHomeMainController
$this->minipanels, $this->minipanels,
); );
$user = $this->getRequest()->getUser();
$nav->appendChild($content); $nav->appendChild($content);
$nav->appendChild(id(new PhabricatorGlobalUploadTargetView())
->setUser($user));
return $this->buildApplicationPage( return $nav;
$nav,
array(
'title' => 'Phabricator',
'device' => true,
));
} }
private function buildJumpResponse() { private function buildJumpResponse() {