Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14051856
D9501.id22758.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
20 KB
Referenced Files
None
Subscribers
None
D9501.id22758.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D9501: Create dashboard panels inline on dashboards
Attached
Detach File
Event Timeline
Log In to Comment