mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 23:02:42 +01:00
Basic "Install Dashboard" workflow
Summary: Ref T12264. This allows users to install a dashboard they are viewing to their personal home menu or as a global home menu item. Has some basic ability to be extended later for maybe projects. Test Plan: Build a dashboard, click "Install Dashboard". - As user only get personal option - As HomeApp edit person, see both options - Try installation as either, with and without label set - Fake "global" form as user, get error - Don't set anything, get error Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Maniphest Tasks: T12264 Differential Revision: https://secure.phabricator.com/D17492
This commit is contained in:
parent
251ee9b660
commit
a72d18765f
8 changed files with 169 additions and 10 deletions
|
@ -9,7 +9,7 @@ return array(
|
||||||
'names' => array(
|
'names' => array(
|
||||||
'conpherence.pkg.css' => '32f2c040',
|
'conpherence.pkg.css' => '32f2c040',
|
||||||
'conpherence.pkg.js' => '6249a1cf',
|
'conpherence.pkg.js' => '6249a1cf',
|
||||||
'core.pkg.css' => '35645dec',
|
'core.pkg.css' => 'c0c87dac',
|
||||||
'core.pkg.js' => '1fa7c0c5',
|
'core.pkg.js' => '1fa7c0c5',
|
||||||
'darkconsole.pkg.js' => 'e7393ebb',
|
'darkconsole.pkg.js' => 'e7393ebb',
|
||||||
'differential.pkg.css' => '90b30783',
|
'differential.pkg.css' => '90b30783',
|
||||||
|
@ -21,7 +21,7 @@ return array(
|
||||||
'maniphest.pkg.js' => '5ab2753f',
|
'maniphest.pkg.js' => '5ab2753f',
|
||||||
'rsrc/css/aphront/aphront-bars.css' => '231ac33c',
|
'rsrc/css/aphront/aphront-bars.css' => '231ac33c',
|
||||||
'rsrc/css/aphront/dark-console.css' => 'f54bf286',
|
'rsrc/css/aphront/dark-console.css' => 'f54bf286',
|
||||||
'rsrc/css/aphront/dialog-view.css' => '5e5aa60b',
|
'rsrc/css/aphront/dialog-view.css' => '685c7e2d',
|
||||||
'rsrc/css/aphront/list-filter-view.css' => '5d6f0526',
|
'rsrc/css/aphront/list-filter-view.css' => '5d6f0526',
|
||||||
'rsrc/css/aphront/multi-column.css' => '84cc6640',
|
'rsrc/css/aphront/multi-column.css' => '84cc6640',
|
||||||
'rsrc/css/aphront/notification.css' => '3f6c89c9',
|
'rsrc/css/aphront/notification.css' => '3f6c89c9',
|
||||||
|
@ -146,7 +146,7 @@ return array(
|
||||||
'rsrc/css/phui/phui-document.css' => 'c32e8dec',
|
'rsrc/css/phui/phui-document.css' => 'c32e8dec',
|
||||||
'rsrc/css/phui/phui-feed-story.css' => '44a9c8e9',
|
'rsrc/css/phui/phui-feed-story.css' => '44a9c8e9',
|
||||||
'rsrc/css/phui/phui-fontkit.css' => 'b78a0059',
|
'rsrc/css/phui/phui-fontkit.css' => 'b78a0059',
|
||||||
'rsrc/css/phui/phui-form-view.css' => 'adca31ce',
|
'rsrc/css/phui/phui-form-view.css' => 'cf198e10',
|
||||||
'rsrc/css/phui/phui-form.css' => 'b62c01d8',
|
'rsrc/css/phui/phui-form.css' => 'b62c01d8',
|
||||||
'rsrc/css/phui/phui-head-thing.css' => 'fd311e5f',
|
'rsrc/css/phui/phui-head-thing.css' => 'fd311e5f',
|
||||||
'rsrc/css/phui/phui-header-view.css' => 'fef6a54e',
|
'rsrc/css/phui/phui-header-view.css' => 'fef6a54e',
|
||||||
|
@ -548,7 +548,7 @@ return array(
|
||||||
'almanac-css' => 'dbb9b3af',
|
'almanac-css' => 'dbb9b3af',
|
||||||
'aphront-bars' => '231ac33c',
|
'aphront-bars' => '231ac33c',
|
||||||
'aphront-dark-console-css' => 'f54bf286',
|
'aphront-dark-console-css' => 'f54bf286',
|
||||||
'aphront-dialog-view-css' => '5e5aa60b',
|
'aphront-dialog-view-css' => '685c7e2d',
|
||||||
'aphront-list-filter-view-css' => '5d6f0526',
|
'aphront-list-filter-view-css' => '5d6f0526',
|
||||||
'aphront-multi-column-view-css' => '84cc6640',
|
'aphront-multi-column-view-css' => '84cc6640',
|
||||||
'aphront-panel-view-css' => '8427b78d',
|
'aphront-panel-view-css' => '8427b78d',
|
||||||
|
@ -859,7 +859,7 @@ return array(
|
||||||
'phui-font-icon-base-css' => '870a7360',
|
'phui-font-icon-base-css' => '870a7360',
|
||||||
'phui-fontkit-css' => 'b78a0059',
|
'phui-fontkit-css' => 'b78a0059',
|
||||||
'phui-form-css' => 'b62c01d8',
|
'phui-form-css' => 'b62c01d8',
|
||||||
'phui-form-view-css' => 'adca31ce',
|
'phui-form-view-css' => 'cf198e10',
|
||||||
'phui-head-thing-view-css' => 'fd311e5f',
|
'phui-head-thing-view-css' => 'fd311e5f',
|
||||||
'phui-header-view-css' => 'fef6a54e',
|
'phui-header-view-css' => 'fef6a54e',
|
||||||
'phui-hovercard' => '1bd28176',
|
'phui-hovercard' => '1bd28176',
|
||||||
|
|
|
@ -2496,6 +2496,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorDashboardEditController' => 'applications/dashboard/controller/PhabricatorDashboardEditController.php',
|
'PhabricatorDashboardEditController' => 'applications/dashboard/controller/PhabricatorDashboardEditController.php',
|
||||||
'PhabricatorDashboardIconSet' => 'applications/dashboard/icon/PhabricatorDashboardIconSet.php',
|
'PhabricatorDashboardIconSet' => 'applications/dashboard/icon/PhabricatorDashboardIconSet.php',
|
||||||
'PhabricatorDashboardInstall' => 'applications/dashboard/storage/PhabricatorDashboardInstall.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',
|
||||||
'PhabricatorDashboardManageController' => 'applications/dashboard/controller/PhabricatorDashboardManageController.php',
|
'PhabricatorDashboardManageController' => 'applications/dashboard/controller/PhabricatorDashboardManageController.php',
|
||||||
|
@ -7562,6 +7563,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorDashboardEditController' => 'PhabricatorDashboardController',
|
'PhabricatorDashboardEditController' => 'PhabricatorDashboardController',
|
||||||
'PhabricatorDashboardIconSet' => 'PhabricatorIconSet',
|
'PhabricatorDashboardIconSet' => 'PhabricatorIconSet',
|
||||||
'PhabricatorDashboardInstall' => 'PhabricatorDashboardDAO',
|
'PhabricatorDashboardInstall' => 'PhabricatorDashboardDAO',
|
||||||
|
'PhabricatorDashboardInstallController' => 'PhabricatorDashboardController',
|
||||||
'PhabricatorDashboardLayoutConfig' => 'Phobject',
|
'PhabricatorDashboardLayoutConfig' => 'Phobject',
|
||||||
'PhabricatorDashboardListController' => 'PhabricatorDashboardController',
|
'PhabricatorDashboardListController' => 'PhabricatorDashboardController',
|
||||||
'PhabricatorDashboardManageController' => 'PhabricatorDashboardProfileController',
|
'PhabricatorDashboardManageController' => 'PhabricatorDashboardProfileController',
|
||||||
|
|
|
@ -30,6 +30,7 @@ final class PhabricatorDashboardApplication 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',
|
||||||
'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+)/'
|
||||||
|
|
|
@ -51,6 +51,14 @@ final class PhabricatorDashboardArrangeController
|
||||||
->addClass('dashboard-preview-box')
|
->addClass('dashboard-preview-box')
|
||||||
->appendChild($rendered_dashboard);
|
->appendChild($rendered_dashboard);
|
||||||
|
|
||||||
|
$install_button = id(new PHUIButtonView())
|
||||||
|
->setTag('a')
|
||||||
|
->setText('Install Dashboard')
|
||||||
|
->setIcon('fa-plus')
|
||||||
|
->setWorkflow(true)
|
||||||
|
->setHref($this->getApplicationURI("/install/{$id}/"));
|
||||||
|
$header->addActionLink($install_button);
|
||||||
|
|
||||||
$view = id(new PHUITwoColumnView())
|
$view = id(new PHUITwoColumnView())
|
||||||
->setHeader($header)
|
->setHeader($header)
|
||||||
->setFooter(array(
|
->setFooter(array(
|
||||||
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorDashboardInstallController
|
||||||
|
extends PhabricatorDashboardController {
|
||||||
|
|
||||||
|
public function handleRequest(AphrontRequest $request) {
|
||||||
|
$viewer = $request->getViewer();
|
||||||
|
$id = $request->getURIData('id');
|
||||||
|
|
||||||
|
$dashboard = id(new PhabricatorDashboardQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withIDs(array($id))
|
||||||
|
->executeOne();
|
||||||
|
if (!$dashboard) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
$cancel_uri = $this->getApplicationURI(
|
||||||
|
'view/'.$dashboard->getID().'/');
|
||||||
|
|
||||||
|
$home_app = new PhabricatorHomeApplication();
|
||||||
|
|
||||||
|
$options = array();
|
||||||
|
$options['home'] = array(
|
||||||
|
'personal' =>
|
||||||
|
array(
|
||||||
|
'capability' => PhabricatorPolicyCapability::CAN_VIEW,
|
||||||
|
'application' => $home_app,
|
||||||
|
'name' => pht('Personal Dashboard'),
|
||||||
|
'value' => 'personal',
|
||||||
|
'description' => pht('Places this dashboard as a menu item on home '.
|
||||||
|
'as a personal menu item. It will only be on your personal '.
|
||||||
|
'home.'),
|
||||||
|
),
|
||||||
|
'global' =>
|
||||||
|
array(
|
||||||
|
'capability' => PhabricatorPolicyCapability::CAN_EDIT,
|
||||||
|
'application' => $home_app,
|
||||||
|
'name' => pht('Global Dashboard'),
|
||||||
|
'value' => 'global',
|
||||||
|
'description' => pht('Places this dashboard as a menu item on home '.
|
||||||
|
'as a global menu item. It will be available to all users.'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
$errors = array();
|
||||||
|
$v_name = null;
|
||||||
|
if ($request->isFormPost()) {
|
||||||
|
$menuitem = new PhabricatorDashboardProfileMenuItem();
|
||||||
|
$dashboard_phid = $dashboard->getPHID();
|
||||||
|
$home = new PhabricatorHomeApplication();
|
||||||
|
$v_name = $request->getStr('name');
|
||||||
|
$v_home = $request->getStr('home');
|
||||||
|
|
||||||
|
if ($v_home) {
|
||||||
|
$application = $options['home'][$v_home]['application'];
|
||||||
|
$capability = $options['home'][$v_home]['capability'];
|
||||||
|
|
||||||
|
$can_edit_home = PhabricatorPolicyFilter::hasCapability(
|
||||||
|
$viewer,
|
||||||
|
$application,
|
||||||
|
$capability);
|
||||||
|
|
||||||
|
if (!$can_edit_home) {
|
||||||
|
$errors[] = pht(
|
||||||
|
'You do not have permission to install a dashboard on home.');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$errors[] = pht(
|
||||||
|
'You must select a destination to install this dashboard.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$v_phid = $viewer->getPHID();
|
||||||
|
if ($v_home == 'global') {
|
||||||
|
$v_phid = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$errors) {
|
||||||
|
$install = PhabricatorProfileMenuItemConfiguration::initializeNewItem(
|
||||||
|
$home,
|
||||||
|
$menuitem,
|
||||||
|
$v_phid);
|
||||||
|
|
||||||
|
$install->setMenuItemProperty('dashboardPHID', $dashboard_phid);
|
||||||
|
$install->setMenuItemProperty('name', $v_name);
|
||||||
|
$install->setMenuItemOrder(1);
|
||||||
|
|
||||||
|
$xactions = array();
|
||||||
|
|
||||||
|
$editor = id(new PhabricatorProfileMenuEditor())
|
||||||
|
->setActor($viewer)
|
||||||
|
->setContinueOnNoEffect(true)
|
||||||
|
->setContinueOnMissingFields(true)
|
||||||
|
->setContentSourceFromRequest($request);
|
||||||
|
|
||||||
|
$editor->applyTransactions($install, $xactions);
|
||||||
|
|
||||||
|
$view_uri = '/home/menu/view/'.$install->getID().'/';
|
||||||
|
|
||||||
|
return id(new AphrontRedirectResponse())->setURI($view_uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$form = id(new AphrontFormView())
|
||||||
|
->setUser($viewer)
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormTextControl())
|
||||||
|
->setLabel(pht('Menu Label'))
|
||||||
|
->setName('name')
|
||||||
|
->setValue($v_name));
|
||||||
|
|
||||||
|
$radio = id(new AphrontFormRadioButtonControl())
|
||||||
|
->setLabel(pht('Home Menu'))
|
||||||
|
->setName('home');
|
||||||
|
|
||||||
|
foreach ($options['home'] as $type => $option) {
|
||||||
|
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||||
|
$viewer,
|
||||||
|
$option['application'],
|
||||||
|
$option['capability']);
|
||||||
|
if ($can_edit) {
|
||||||
|
$radio->addButton(
|
||||||
|
$option['value'],
|
||||||
|
$option['name'],
|
||||||
|
$option['description']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$form->appendChild($radio);
|
||||||
|
|
||||||
|
return $this->newDialog()
|
||||||
|
->setTitle(pht('Install Dashboard'))
|
||||||
|
->setErrors($errors)
|
||||||
|
->setWidth(AphrontDialogView::WIDTH_FORM)
|
||||||
|
->appendChild($form->buildLayoutView())
|
||||||
|
->addCancelButton($cancel_uri)
|
||||||
|
->addSubmitButton(pht('Install Dashboard'));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -43,6 +43,14 @@ final class PhabricatorDashboardViewController
|
||||||
$navigation = $this->buildSideNavView('view');
|
$navigation = $this->buildSideNavView('view');
|
||||||
$header = $this->buildHeaderView();
|
$header = $this->buildHeaderView();
|
||||||
|
|
||||||
|
$install_button = id(new PHUIButtonView())
|
||||||
|
->setTag('a')
|
||||||
|
->setText('Install Dashboard')
|
||||||
|
->setIcon('fa-plus')
|
||||||
|
->setWorkflow(true)
|
||||||
|
->setHref($this->getApplicationURI("/install/{$id}/"));
|
||||||
|
$header->addActionLink($install_button);
|
||||||
|
|
||||||
$view = id(new PHUITwoColumnView())
|
$view = id(new PHUITwoColumnView())
|
||||||
->setHeader($header)
|
->setHeader($header)
|
||||||
->setFooter(array(
|
->setFooter(array(
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.aphront-dialog-view {
|
.aphront-dialog-view {
|
||||||
width: 540px;
|
width: 560px;
|
||||||
margin: 32px auto 16px;
|
margin: 32px auto 16px;
|
||||||
border: 1px solid {$lightblueborder};
|
border: 1px solid {$lightblueborder};
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.aphront-dialog-view-width-form {
|
.aphront-dialog-view-width-form {
|
||||||
width: 600px;
|
width: 640px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.aphront-dialog-view-width-full {
|
.aphront-dialog-view-width-full {
|
||||||
|
|
|
@ -208,14 +208,13 @@
|
||||||
|
|
||||||
table.aphront-form-control-radio-layout,
|
table.aphront-form-control-radio-layout,
|
||||||
table.aphront-form-control-checkbox-layout {
|
table.aphront-form-control-checkbox-layout {
|
||||||
margin-top: 3px;
|
margin-top: 4px !important;
|
||||||
font-size: {$normalfontsize};
|
font-size: {$normalfontsize};
|
||||||
}
|
}
|
||||||
|
|
||||||
table.aphront-form-control-radio-layout th {
|
table.aphront-form-control-radio-layout th {
|
||||||
padding-top: 3px;
|
|
||||||
padding-left: 8px;
|
padding-left: 8px;
|
||||||
padding-bottom: 4px;
|
padding-bottom: 8px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: {$darkgreytext};
|
color: {$darkgreytext};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue