Page MenuHomePhabricator

D9501.id22758.diff
No OneTemporary

D9501.id22758.diff

diff --git a/src/applications/dashboard/application/PhabricatorApplicationDashboard.php b/src/applications/dashboard/application/PhabricatorApplicationDashboard.php
--- a/src/applications/dashboard/application/PhabricatorApplicationDashboard.php
+++ b/src/applications/dashboard/application/PhabricatorApplicationDashboard.php
@@ -34,7 +34,7 @@
'panel/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?'
=> 'PhabricatorDashboardPanelListController',
- 'create/' => 'PhabricatorDashboardPanelCreateController',
+ 'create/' => 'PhabricatorDashboardPanelEditController',
'edit/(?:(?P<id>\d+)/)?' => 'PhabricatorDashboardPanelEditController',
'render/(?P<id>\d+)/' => 'PhabricatorDashboardPanelRenderController',
),
diff --git a/src/applications/dashboard/controller/PhabricatorDashboardAddPanelController.php b/src/applications/dashboard/controller/PhabricatorDashboardAddPanelController.php
--- a/src/applications/dashboard/controller/PhabricatorDashboardAddPanelController.php
+++ b/src/applications/dashboard/controller/PhabricatorDashboardAddPanelController.php
@@ -26,82 +26,74 @@
return new Aphront404Response();
}
- $redirect_uri = $this->getApplicationURI(
- 'manage/'.$dashboard->getID().'/');
- $layout_config = $dashboard->getLayoutConfigObject();
+ $redirect_uri = $this->getApplicationURI('manage/'.$dashboard->getID().'/');
$v_panel = $request->getStr('panel');
$e_panel = true;
$errors = array();
if ($request->isFormPost()) {
if (strlen($v_panel)) {
- $panel = id(new PhabricatorObjectQuery())
+ $panel = id(new PhabricatorDashboardPanelQuery())
->setViewer($viewer)
- ->withNames(array($v_panel))
- ->withTypes(array(PhabricatorDashboardPHIDTypePanel::TYPECONST))
+ ->withIDs(array($v_panel))
->executeOne();
if (!$panel) {
$errors[] = pht('No such panel!');
$e_panel = pht('Invalid');
}
} else {
- $errors[] = pht('Name a panel to add.');
+ $errors[] = pht('Select a panel to add.');
$e_panel = pht('Required');
}
if (!$errors) {
- $xactions = array();
- $xactions[] = id(new PhabricatorDashboardTransaction())
- ->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
- ->setMetadataValue(
- 'edge:type',
- PhabricatorEdgeConfig::TYPE_DASHBOARD_HAS_PANEL)
- ->setNewValue(
- array(
- '+' => array(
- $panel->getPHID() => $panel->getPHID(),
- ),
- ));
-
- $layout_config->setPanelLocation(
- $request->getInt('column', 0),
- $panel->getPHID());
- $dashboard->setLayoutConfigFromObject($layout_config);
-
- $editor = id(new PhabricatorDashboardTransactionEditor())
- ->setActor($viewer)
- ->setContentSourceFromRequest($request)
- ->setContinueOnMissingFields(true)
- ->setContinueOnNoEffect(true)
- ->applyTransactions($dashboard, $xactions);
+ PhabricatorDashboardTransactionEditor::addPanelToDashboard(
+ $viewer,
+ PhabricatorContentSource::newFromRequest($request),
+ $panel,
+ $dashboard,
+ $request->getInt('column', 0));
return id(new AphrontRedirectResponse())->setURI($redirect_uri);
}
}
+ $panels = id(new PhabricatorDashboardPanelQuery())
+ ->setViewer($viewer)
+ ->execute();
+
+ if (!$panels) {
+ return $this->newDialog()
+ ->setTitle(pht('No Panels Exist Yet'))
+ ->appendParagraph(
+ pht(
+ 'You have not created any dashboard panels yet, so you can not '.
+ 'add an existing panel.'))
+ ->appendParagraph(
+ pht('Instead, add a new panel.'))
+ ->addCancelButton($redirect_uri);
+ }
+
+ $panel_options = array();
+ foreach ($panels as $panel) {
+ $panel_options[$panel->getID()] = pht(
+ '%s %s',
+ $panel->getMonogram(),
+ $panel->getName());
+ }
+
$form = id(new AphrontFormView())
->setUser($viewer)
- ->addHiddenInput('src', $request->getStr('src', 'edit'))
+ ->addHiddenInput('column', $request->getInt('column'))
->appendRemarkupInstructions(
- pht('Enter a panel monogram like `W123`.'))
+ pht('Choose a panel to add to this dashboard:'))
->appendChild(
- id(new AphrontFormTextControl())
+ id(new AphrontFormSelectControl())
->setName('panel')
->setLabel(pht('Panel'))
->setValue($v_panel)
- ->setError($e_panel));
-
- if ($layout_config->isMultiColumnLayout()) {
- $form
- ->appendRemarkupInstructions(
- pht('Choose which column the panel should reside in.'))
- ->appendChild(
- id(new AphrontFormSelectControl())
- ->setName('column')
- ->setLabel(pht('Column'))
- ->setOptions($layout_config->getColumnSelectOptions())
- ->setValue($request->getInt('column')));
- }
+ ->setError($e_panel)
+ ->setOptions($panel_options));
return $this->newDialog()
->setTitle(pht('Add Panel'))
diff --git a/src/applications/dashboard/controller/PhabricatorDashboardPanelCreateController.php b/src/applications/dashboard/controller/PhabricatorDashboardPanelCreateController.php
--- a/src/applications/dashboard/controller/PhabricatorDashboardPanelCreateController.php
+++ b/src/applications/dashboard/controller/PhabricatorDashboardPanelCreateController.php
@@ -7,6 +7,24 @@
$request = $this->getRequest();
$viewer = $request->getUser();
+ // If the user is trying to create this panel directly on a dashboard,
+ // make sure they have permission to see and edit it.
+ $dashboard_id = $request->getInt('dashboardID');
+ if ($dashboard_id) {
+ $dashboard = id(new PhabricatorDashboardQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($dashboard_id))
+ ->requireCapabilities(
+ array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
+ ))
+ ->executeOne();
+ if (!$dashboard) {
+ return new Aphront404Response();
+ }
+ }
+
$types = PhabricatorDashboardPanelType::getAllPanelTypes();
$v_type = null;
@@ -18,8 +36,13 @@
}
if (!$errors) {
- return id(new AphrontRedirectResponse())->setURI(
- $this->getApplicationURI('panel/edit/?type='.$v_type));
+ $next_uri = $this->getApplicationURI('panel/edit/');
+ $next_uri = id(new PhutilURI($next_uri))
+ ->setQueryParam('type', $v_type)
+ ->setQueryParam('dashboardID', $dashboard_id)
+ ->setQueryParam('column', $request->getInt('column'));
+
+ return id(new AphrontRedirectResponse())->setURI($next_uri);
}
}
@@ -42,11 +65,27 @@
$form = id(new AphrontFormView())
->setUser($viewer)
- ->appendChild($panel_types)
- ->appendChild(
+ ->appendRemarkupInstructions(
+ pht(
+ 'Choose the type of dashboard panel to create:'))
+ ->appendChild($panel_types);
+
+ if ($request->isAjax()) {
+ return $this->newDialog()
+ ->setTitle(pht('Add New Panel'))
+ ->setWidth(AphrontDialogView::WIDTH_FORM)
+ ->setErrors($errors)
+ ->appendChild($form->buildLayoutView())
+ ->addCancelbutton($cancel_uri)
+ ->addSubmitButton(pht('Continue'));
+ } else {
+ $form->appendChild(
id(new AphrontFormSubmitControl())
->setValue(pht('Continue'))
->addCancelButton($cancel_uri));
+ }
+
+ $title = pht('Create Dashboard Panel');
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(
@@ -54,8 +93,6 @@
$this->getApplicationURI('panel/'));
$crumbs->addTextCrumb(pht('New Panel'));
- $title = pht('Create Dashboard Panel');
-
$box = id(new PHUIObjectBoxView())
->setHeaderText($title)
->setFormErrors($errors)
diff --git a/src/applications/dashboard/controller/PhabricatorDashboardPanelEditController.php b/src/applications/dashboard/controller/PhabricatorDashboardPanelEditController.php
--- a/src/applications/dashboard/controller/PhabricatorDashboardPanelEditController.php
+++ b/src/applications/dashboard/controller/PhabricatorDashboardPanelEditController.php
@@ -13,6 +13,29 @@
$request = $this->getRequest();
$viewer = $request->getUser();
+ // If the user is trying to create a panel directly on a dashboard, make
+ // sure they have permission to see and edit the dashboard.
+
+ $dashboard_id = $request->getInt('dashboardID');
+ $dashboard = null;
+ if ($dashboard_id) {
+ $dashboard = id(new PhabricatorDashboardQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($dashboard_id))
+ ->requireCapabilities(
+ array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
+ ))
+ ->executeOne();
+ if (!$dashboard) {
+ return new Aphront404Response();
+ }
+
+ $manage_uri = $this->getApplicationURI(
+ 'dashboard/manage/'.$dashboard_id.'/');
+ }
+
if ($this->id) {
$is_create = false;
@@ -33,11 +56,10 @@
$is_create = true;
$panel = PhabricatorDashboardPanel::initializeNewPanel($viewer);
-
$types = PhabricatorDashboardPanelType::getAllPanelTypes();
$type = $request->getStr('type');
if (empty($types[$type])) {
- return new Aphront404Response();
+ return $this->processPanelTypeRequest($request);
}
$panel->setPanelType($type);
@@ -47,12 +69,20 @@
$title = pht('New Panel');
$header = pht('Create New Panel');
$button = pht('Create Panel');
- $cancel_uri = $this->getApplicationURI('panel/');
+ if ($dashboard) {
+ $cancel_uri = $manage_uri;
+ } else {
+ $cancel_uri = $this->getApplicationURI('panel/');
+ }
} else {
$title = pht('Edit %s', $panel->getMonogram());
$header = pht('Edit %s %s', $panel->getMonogram(), $panel->getName());
$button = pht('Save Panel');
- $cancel_uri = $this->getPanelRedirectURI($panel);
+ if ($dashboard) {
+ $cancel_uri = $manage_uri;
+ } else {
+ $cancel_uri = '/'.$panel->getMonogram();
+ }
}
$v_name = $panel->getName();
@@ -67,7 +97,10 @@
$validation_exception = null;
- if ($request->isFormPost()) {
+ // NOTE: We require 'edit' to distinguish between the "Choose a Type"
+ // and "Create a Panel" dialogs.
+
+ if ($request->isFormPost() && $request->getBool('edit')) {
$v_name = $request->getStr('name');
$v_view_policy = $request->getStr('viewPolicy');
$v_edit_policy = $request->getStr('editPolicy');
@@ -102,8 +135,23 @@
->setContentSourceFromRequest($request)
->applyTransactions($panel, $xactions);
- return id(new AphrontRedirectResponse())
- ->setURI($this->getPanelRedirectURI($panel));
+ // If we're creating a panel directly on a dashboard, add it now.
+ if ($dashboard) {
+ PhabricatorDashboardTransactionEditor::addPanelToDashboard(
+ $viewer,
+ PhabricatorContentSource::newFromRequest($request),
+ $panel,
+ $dashboard,
+ $request->getInt('column', 0));
+ }
+
+ if ($dashboard) {
+ $done_uri = $manage_uri;
+ } else {
+ $done_uri = '/'.$panel->getMonogram();
+ }
+
+ return id(new AphrontRedirectResponse())->setURI($done_uri);
} catch (PhabricatorApplicationTransactionValidationException $ex) {
$validation_exception = $ex;
@@ -121,7 +169,9 @@
$form = id(new AphrontFormView())
->setUser($viewer)
+ ->addHiddenInput('edit', true)
->addHiddenInput('dashboardID', $request->getInt('dashboardID'))
+ ->addHiddenInput('column', $request->getInt('column'))
->appendChild(
id(new AphrontFormTextControl())
->setLabel(pht('Name'))
@@ -189,16 +239,83 @@
));
}
- private function getPanelRedirectURI(PhabricatorDashboardPanel $panel) {
- $request = $this->getRequest();
- $dashboard_id = $request->getInt('dashboardID');
- if ($dashboard_id) {
- $uri = $this->getApplicationURI('manage/'.$dashboard_id.'/');
+ private function processPanelTypeRequest(AphrontRequest $request) {
+ $viewer = $request->getUser();
+
+ $types = PhabricatorDashboardPanelType::getAllPanelTypes();
+
+ $v_type = null;
+ $errors = array();
+ if ($request->isFormPost()) {
+ $v_type = $request->getStr('type');
+ if (!isset($types[$v_type])) {
+ $errors[] = pht('You must select a type of panel to create.');
+ }
+ }
+
+ $cancel_uri = $this->getApplicationURI('panel/');
+
+ if (!$v_type) {
+ $v_type = key($types);
+ }
+
+ $panel_types = id(new AphrontFormRadioButtonControl())
+ ->setName('type')
+ ->setValue($v_type);
+
+ foreach ($types as $key => $type) {
+ $panel_types->addButton(
+ $key,
+ $type->getPanelTypeName(),
+ $type->getPanelTypeDescription());
+ }
+
+ $form = id(new AphrontFormView())
+ ->setUser($viewer)
+ ->addHiddenInput('dashboardID', $request->getInt('dashboardID'))
+ ->addHiddenInput('column', $request->getInt('column'))
+ ->appendRemarkupInstructions(
+ pht(
+ 'Choose the type of dashboard panel to create:'))
+ ->appendChild($panel_types);
+
+ if ($request->isAjax()) {
+ return $this->newDialog()
+ ->setTitle(pht('Add New Panel'))
+ ->setWidth(AphrontDialogView::WIDTH_FORM)
+ ->setErrors($errors)
+ ->appendChild($form->buildLayoutView())
+ ->addCancelbutton($cancel_uri)
+ ->addSubmitButton(pht('Continue'));
} else {
- $uri = '/'.$panel->getMonogram();
+ $form->appendChild(
+ id(new AphrontFormSubmitControl())
+ ->setValue(pht('Continue'))
+ ->addCancelButton($cancel_uri));
}
- return $uri;
+ $title = pht('Create Dashboard Panel');
+
+ $crumbs = $this->buildApplicationCrumbs();
+ $crumbs->addTextCrumb(
+ pht('Panels'),
+ $this->getApplicationURI('panel/'));
+ $crumbs->addTextCrumb(pht('New Panel'));
+
+ $box = id(new PHUIObjectBoxView())
+ ->setHeaderText($title)
+ ->setFormErrors($errors)
+ ->setForm($form);
+
+ return $this->buildApplicationPage(
+ array(
+ $crumbs,
+ $box,
+ ),
+ array(
+ 'title' => $title,
+ 'device' => true,
+ ));
}
}
diff --git a/src/applications/dashboard/controller/PhabricatorDashboardPanelViewController.php b/src/applications/dashboard/controller/PhabricatorDashboardPanelViewController.php
--- a/src/applications/dashboard/controller/PhabricatorDashboardPanelViewController.php
+++ b/src/applications/dashboard/controller/PhabricatorDashboardPanelViewController.php
@@ -136,9 +136,14 @@
PhabricatorEdgeConfig::TYPE_PANEL_HAS_DASHBOARD);
$this->loadHandles($dashboard_phids);
+ $does_not_appear = pht(
+ 'This panel does not appear on any dashboards.');
+
$properties->addProperty(
pht('Appears On'),
- $this->renderHandlesForPHIDs($dashboard_phids));
+ $dashboard_phids
+ ? $this->renderHandlesForPHIDs($dashboard_phids)
+ : phutil_tag('em', array(), $does_not_appear));
return $properties;
}
diff --git a/src/applications/dashboard/editor/PhabricatorDashboardTransactionEditor.php b/src/applications/dashboard/editor/PhabricatorDashboardTransactionEditor.php
--- a/src/applications/dashboard/editor/PhabricatorDashboardTransactionEditor.php
+++ b/src/applications/dashboard/editor/PhabricatorDashboardTransactionEditor.php
@@ -3,6 +3,38 @@
final class PhabricatorDashboardTransactionEditor
extends PhabricatorApplicationTransactionEditor {
+ public static function addPanelToDashboard(
+ PhabricatorUser $actor,
+ PhabricatorContentSource $content_source,
+ PhabricatorDashboardPanel $panel,
+ PhabricatorDashboard $dashboard,
+ $column) {
+
+ $xactions = array();
+ $xactions[] = id(new PhabricatorDashboardTransaction())
+ ->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
+ ->setMetadataValue(
+ 'edge:type',
+ PhabricatorEdgeConfig::TYPE_DASHBOARD_HAS_PANEL)
+ ->setNewValue(
+ array(
+ '+' => array(
+ $panel->getPHID() => $panel->getPHID(),
+ ),
+ ));
+
+ $layout_config = $dashboard->getLayoutConfigObject();
+ $layout_config->setPanelLocation($column, $panel->getPHID());
+ $dashboard->setLayoutConfigFromObject($layout_config);
+
+ $editor = id(new PhabricatorDashboardTransactionEditor())
+ ->setActor($actor)
+ ->setContentSource($content_source)
+ ->setContinueOnMissingFields(true)
+ ->setContinueOnNoEffect(true)
+ ->applyTransactions($dashboard, $xactions);
+ }
+
public function getTransactionTypes() {
$types = parent::getTransactionTypes();
diff --git a/src/applications/dashboard/engine/PhabricatorDashboardRenderingEngine.php b/src/applications/dashboard/engine/PhabricatorDashboardRenderingEngine.php
--- a/src/applications/dashboard/engine/PhabricatorDashboardRenderingEngine.php
+++ b/src/applications/dashboard/engine/PhabricatorDashboardRenderingEngine.php
@@ -86,45 +86,57 @@
}
private function renderAddPanelPlaceHolder($column) {
- $uri = $this->getAddPanelURI($column);
-
$dashboard = $this->dashboard;
$panels = $dashboard->getPanels();
- $layout_config = $dashboard->getLayoutConfigObject();
- if ($layout_config->isMultiColumnLayout() && count($panels)) {
- $text = pht('Drag a panel here or click to add a panel.');
- } else {
- $text = pht('Click to add a panel.');
- }
+
return javelin_tag(
- 'a',
+ 'span',
array(
'sigil' => 'workflow',
'class' => 'drag-ghost dashboard-panel-placeholder',
- 'href' => (string) $uri),
- $text);
+ ),
+ pht('This column does not have any panels yet.'));
}
private function renderAddPanelUI($column) {
- $uri = $this->getAddPanelURI($column);
+ $dashboard_id = $this->dashboard->getID();
+
+ $create_uri = id(new PhutilURI('/dashboard/panel/create/'))
+ ->setQueryParam('dashboardID', $dashboard_id)
+ ->setQueryParam('column', $column);
- return id(new PHUIButtonView())
+ $add_uri = id(new PhutilURI('/dashboard/addpanel/'.$dashboard_id.'/'))
+ ->setQueryParam('column', $column);
+
+ $create_button = id(new PHUIButtonView())
->setTag('a')
- ->setHref((string) $uri)
+ ->setHref($create_uri)
->setWorkflow(true)
->setColor(PHUIButtonView::GREY)
->setIcon(id(new PHUIIconView())
->setIconFont('fa-plus'))
- ->setText(pht('Add Panel'))
- ->addClass(PHUI::MARGIN_LARGE);
- }
+ ->setText(pht('Add New Panel'))
+ ->addClass(PHUI::MARGIN_MEDIUM);
- private function getAddPanelURI($column) {
- $dashboard = $this->dashboard;
- $uri = id(new PhutilURI('/dashboard/addpanel/'.$dashboard->getID().'/'))
- ->setQueryParam('column', $column)
- ->setQueryParam('src', 'arrange');
- return $uri;
+ $add_button = id(new PHUIButtonView())
+ ->setTag('a')
+ ->setHref($add_uri)
+ ->setWorkflow(true)
+ ->setColor(PHUIButtonView::GREY)
+ ->setIcon(id(new PHUIIconView())
+ ->setIconFont('fa-folder-open'))
+ ->setText(pht('Add Existing Panel'))
+ ->addClass(PHUI::MARGIN_MEDIUM);
+
+ return phutil_tag(
+ 'div',
+ array(
+ 'style' => 'text-align: center;',
+ ),
+ array(
+ $create_button,
+ $add_button,
+ ));
}
}
diff --git a/webroot/rsrc/css/application/dashboard/dashboard.css b/webroot/rsrc/css/application/dashboard/dashboard.css
--- a/webroot/rsrc/css/application/dashboard/dashboard.css
+++ b/webroot/rsrc/css/application/dashboard/dashboard.css
@@ -50,18 +50,12 @@
.aphront-multi-column-fluid
.aphront-multi-column-column.dashboard-column-empty
.dashboard-panel-placeholder {
- color: {$greytext};
display: block;
padding: 24px;
margin: 16px 16px 0px 16px;
-}
-
-.aphront-multi-column-fluid
-.aphront-multi-column-column.dashboard-column-empty
-.dashboard-panel-placeholder:hover {
text-decoration: none;
border: 1px {$greyborder} dashed;
- color: {$darkgreytext};
+ color: {$greytext};
}
.aphront-multi-column-fluid

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 16, 4:29 AM (2 d, 17 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6737807
Default Alt Text
D9501.id22758.diff (20 KB)

Event Timeline