mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-18 21:02:41 +01:00
Dashboards - add remove functionality
Summary: To get there, upgrade "headerless" to "headerMode". Add a new removepanel controller. Fixes T5084. Test Plan: removed some panels to much success Reviewers: chad, epriestley Reviewed By: epriestley Subscribers: epriestley, Korvin Maniphest Tasks: T5078, T5084 Differential Revision: https://secure.phabricator.com/D9156
This commit is contained in:
parent
9cb4047134
commit
d9058d7f3f
17 changed files with 327 additions and 99 deletions
|
@ -52,7 +52,7 @@ return array(
|
||||||
'rsrc/css/application/conpherence/widget-pane.css' => 'bf275a6c',
|
'rsrc/css/application/conpherence/widget-pane.css' => 'bf275a6c',
|
||||||
'rsrc/css/application/contentsource/content-source-view.css' => '4b8b05d4',
|
'rsrc/css/application/contentsource/content-source-view.css' => '4b8b05d4',
|
||||||
'rsrc/css/application/countdown/timer.css' => '86b7b0a0',
|
'rsrc/css/application/countdown/timer.css' => '86b7b0a0',
|
||||||
'rsrc/css/application/dashboard/dashboard.css' => '2b41640b',
|
'rsrc/css/application/dashboard/dashboard.css' => 'fbf815b5',
|
||||||
'rsrc/css/application/diff/inline-comment-summary.css' => '8cfd34e8',
|
'rsrc/css/application/diff/inline-comment-summary.css' => '8cfd34e8',
|
||||||
'rsrc/css/application/differential/add-comment.css' => 'c478bcaa',
|
'rsrc/css/application/differential/add-comment.css' => 'c478bcaa',
|
||||||
'rsrc/css/application/differential/changeset-view.css' => 'c45747f0',
|
'rsrc/css/application/differential/changeset-view.css' => 'c45747f0',
|
||||||
|
@ -355,7 +355,7 @@ return array(
|
||||||
'rsrc/js/application/conpherence/behavior-pontificate.js' => '53f6f2dd',
|
'rsrc/js/application/conpherence/behavior-pontificate.js' => '53f6f2dd',
|
||||||
'rsrc/js/application/conpherence/behavior-widget-pane.js' => '40b1ff90',
|
'rsrc/js/application/conpherence/behavior-widget-pane.js' => '40b1ff90',
|
||||||
'rsrc/js/application/countdown/timer.js' => '889c96f3',
|
'rsrc/js/application/countdown/timer.js' => '889c96f3',
|
||||||
'rsrc/js/application/dashboard/behavior-dashboard-async-panel.js' => 'f1375ea5',
|
'rsrc/js/application/dashboard/behavior-dashboard-async-panel.js' => '469c0d9e',
|
||||||
'rsrc/js/application/dashboard/behavior-dashboard-move-panels.js' => 'fa187a68',
|
'rsrc/js/application/dashboard/behavior-dashboard-move-panels.js' => 'fa187a68',
|
||||||
'rsrc/js/application/differential/DifferentialInlineCommentEditor.js' => 'f2441746',
|
'rsrc/js/application/differential/DifferentialInlineCommentEditor.js' => 'f2441746',
|
||||||
'rsrc/js/application/differential/behavior-add-reviewers-and-ccs.js' => '533a187b',
|
'rsrc/js/application/differential/behavior-add-reviewers-and-ccs.js' => '533a187b',
|
||||||
|
@ -550,7 +550,7 @@ return array(
|
||||||
'javelin-behavior-conpherence-widget-pane' => '40b1ff90',
|
'javelin-behavior-conpherence-widget-pane' => '40b1ff90',
|
||||||
'javelin-behavior-countdown-timer' => '889c96f3',
|
'javelin-behavior-countdown-timer' => '889c96f3',
|
||||||
'javelin-behavior-dark-console' => 'e9fdb5e5',
|
'javelin-behavior-dark-console' => 'e9fdb5e5',
|
||||||
'javelin-behavior-dashboard-async-panel' => 'f1375ea5',
|
'javelin-behavior-dashboard-async-panel' => '469c0d9e',
|
||||||
'javelin-behavior-dashboard-move-panels' => 'fa187a68',
|
'javelin-behavior-dashboard-move-panels' => 'fa187a68',
|
||||||
'javelin-behavior-device' => '03d6ed07',
|
'javelin-behavior-device' => '03d6ed07',
|
||||||
'javelin-behavior-differential-add-reviewers-and-ccs' => '533a187b',
|
'javelin-behavior-differential-add-reviewers-and-ccs' => '533a187b',
|
||||||
|
@ -698,7 +698,7 @@ return array(
|
||||||
'phabricator-core-css' => '40151074',
|
'phabricator-core-css' => '40151074',
|
||||||
'phabricator-countdown-css' => '86b7b0a0',
|
'phabricator-countdown-css' => '86b7b0a0',
|
||||||
'phabricator-crumbs-view-css' => '6a23399c',
|
'phabricator-crumbs-view-css' => '6a23399c',
|
||||||
'phabricator-dashboard-css' => '2b41640b',
|
'phabricator-dashboard-css' => 'fbf815b5',
|
||||||
'phabricator-drag-and-drop-file-upload' => 'ae6abfba',
|
'phabricator-drag-and-drop-file-upload' => 'ae6abfba',
|
||||||
'phabricator-draggable-list' => '1681c4d4',
|
'phabricator-draggable-list' => '1681c4d4',
|
||||||
'phabricator-fatal-config-template-css' => '25d446d6',
|
'phabricator-fatal-config-template-css' => '25d446d6',
|
||||||
|
@ -1129,6 +1129,12 @@ return array(
|
||||||
1 => 'javelin-stratcom',
|
1 => 'javelin-stratcom',
|
||||||
2 => 'javelin-dom',
|
2 => 'javelin-dom',
|
||||||
),
|
),
|
||||||
|
'469c0d9e' =>
|
||||||
|
array(
|
||||||
|
0 => 'javelin-behavior',
|
||||||
|
1 => 'javelin-dom',
|
||||||
|
2 => 'javelin-workflow',
|
||||||
|
),
|
||||||
'46efd18e' =>
|
'46efd18e' =>
|
||||||
array(
|
array(
|
||||||
0 => 'multirow-row-manager',
|
0 => 'multirow-row-manager',
|
||||||
|
@ -1254,6 +1260,13 @@ return array(
|
||||||
2 => 'javelin-util',
|
2 => 'javelin-util',
|
||||||
3 => 'phabricator-shaped-request',
|
3 => 'phabricator-shaped-request',
|
||||||
),
|
),
|
||||||
|
'62e18640' =>
|
||||||
|
array(
|
||||||
|
0 => 'javelin-install',
|
||||||
|
1 => 'javelin-util',
|
||||||
|
2 => 'javelin-dom',
|
||||||
|
3 => 'javelin-typeahead-normalizer',
|
||||||
|
),
|
||||||
'6453c869' =>
|
'6453c869' =>
|
||||||
array(
|
array(
|
||||||
0 => 'javelin-install',
|
0 => 'javelin-install',
|
||||||
|
@ -1322,13 +1335,6 @@ return array(
|
||||||
0 => 'javelin-behavior',
|
0 => 'javelin-behavior',
|
||||||
1 => 'javelin-dom',
|
1 => 'javelin-dom',
|
||||||
),
|
),
|
||||||
'62e18640' =>
|
|
||||||
array(
|
|
||||||
0 => 'javelin-install',
|
|
||||||
1 => 'javelin-util',
|
|
||||||
2 => 'javelin-dom',
|
|
||||||
3 => 'javelin-typeahead-normalizer',
|
|
||||||
),
|
|
||||||
'76f4ebed' =>
|
'76f4ebed' =>
|
||||||
array(
|
array(
|
||||||
0 => 'javelin-install',
|
0 => 'javelin-install',
|
||||||
|
@ -1961,12 +1967,6 @@ return array(
|
||||||
0 => 'javelin-install',
|
0 => 'javelin-install',
|
||||||
1 => 'javelin-util',
|
1 => 'javelin-util',
|
||||||
),
|
),
|
||||||
'f1375ea5' =>
|
|
||||||
array(
|
|
||||||
0 => 'javelin-behavior',
|
|
||||||
1 => 'javelin-dom',
|
|
||||||
2 => 'javelin-workflow',
|
|
||||||
),
|
|
||||||
'f2441746' =>
|
'f2441746' =>
|
||||||
array(
|
array(
|
||||||
0 => 'javelin-dom',
|
0 => 'javelin-dom',
|
||||||
|
|
|
@ -1487,6 +1487,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorDashboardPanelTypeText' => 'applications/dashboard/paneltype/PhabricatorDashboardPanelTypeText.php',
|
'PhabricatorDashboardPanelTypeText' => 'applications/dashboard/paneltype/PhabricatorDashboardPanelTypeText.php',
|
||||||
'PhabricatorDashboardPanelViewController' => 'applications/dashboard/controller/PhabricatorDashboardPanelViewController.php',
|
'PhabricatorDashboardPanelViewController' => 'applications/dashboard/controller/PhabricatorDashboardPanelViewController.php',
|
||||||
'PhabricatorDashboardQuery' => 'applications/dashboard/query/PhabricatorDashboardQuery.php',
|
'PhabricatorDashboardQuery' => 'applications/dashboard/query/PhabricatorDashboardQuery.php',
|
||||||
|
'PhabricatorDashboardRemovePanelController' => 'applications/dashboard/controller/PhabricatorDashboardRemovePanelController.php',
|
||||||
'PhabricatorDashboardRenderingEngine' => 'applications/dashboard/engine/PhabricatorDashboardRenderingEngine.php',
|
'PhabricatorDashboardRenderingEngine' => 'applications/dashboard/engine/PhabricatorDashboardRenderingEngine.php',
|
||||||
'PhabricatorDashboardSearchEngine' => 'applications/dashboard/query/PhabricatorDashboardSearchEngine.php',
|
'PhabricatorDashboardSearchEngine' => 'applications/dashboard/query/PhabricatorDashboardSearchEngine.php',
|
||||||
'PhabricatorDashboardTransaction' => 'applications/dashboard/storage/PhabricatorDashboardTransaction.php',
|
'PhabricatorDashboardTransaction' => 'applications/dashboard/storage/PhabricatorDashboardTransaction.php',
|
||||||
|
@ -4278,6 +4279,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorDashboardPanelTypeText' => 'PhabricatorDashboardPanelType',
|
'PhabricatorDashboardPanelTypeText' => 'PhabricatorDashboardPanelType',
|
||||||
'PhabricatorDashboardPanelViewController' => 'PhabricatorDashboardController',
|
'PhabricatorDashboardPanelViewController' => 'PhabricatorDashboardController',
|
||||||
'PhabricatorDashboardQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhabricatorDashboardQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
|
'PhabricatorDashboardRemovePanelController' => 'PhabricatorDashboardController',
|
||||||
'PhabricatorDashboardRenderingEngine' => 'Phobject',
|
'PhabricatorDashboardRenderingEngine' => 'Phobject',
|
||||||
'PhabricatorDashboardSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
'PhabricatorDashboardSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||||
'PhabricatorDashboardTransaction' => 'PhabricatorApplicationTransaction',
|
'PhabricatorDashboardTransaction' => 'PhabricatorApplicationTransaction',
|
||||||
|
|
|
@ -26,6 +26,8 @@ final class PhabricatorApplicationDashboard extends PhabricatorApplication {
|
||||||
'edit/(?:(?P<id>\d+)/)?' => 'PhabricatorDashboardEditController',
|
'edit/(?:(?P<id>\d+)/)?' => 'PhabricatorDashboardEditController',
|
||||||
'addpanel/(?P<id>\d+)/' => 'PhabricatorDashboardAddPanelController',
|
'addpanel/(?P<id>\d+)/' => 'PhabricatorDashboardAddPanelController',
|
||||||
'movepanel/(?P<id>\d+)/' => 'PhabricatorDashboardMovePanelController',
|
'movepanel/(?P<id>\d+)/' => 'PhabricatorDashboardMovePanelController',
|
||||||
|
'removepanel/(?P<id>\d+)/'
|
||||||
|
=> 'PhabricatorDashboardRemovePanelController',
|
||||||
'panel/' => array(
|
'panel/' => array(
|
||||||
'(?:query/(?P<queryKey>[^/]+)/)?'
|
'(?:query/(?P<queryKey>[^/]+)/)?'
|
||||||
=> 'PhabricatorDashboardPanelListController',
|
=> 'PhabricatorDashboardPanelListController',
|
||||||
|
|
|
@ -68,12 +68,10 @@ final class PhabricatorDashboardAddPanelController
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
||||||
if ($layout_config->isMultiColumnLayout()) {
|
|
||||||
$layout_config->setPanelLocation(
|
$layout_config->setPanelLocation(
|
||||||
$request->getInt('column'),
|
$request->getInt('column', 0),
|
||||||
$panel->getPHID());
|
$panel->getPHID());
|
||||||
$dashboard->setLayoutConfigFromObject($layout_config);
|
$dashboard->setLayoutConfigFromObject($layout_config);
|
||||||
}
|
|
||||||
|
|
||||||
$editor = id(new PhabricatorDashboardTransactionEditor())
|
$editor = id(new PhabricatorDashboardTransactionEditor())
|
||||||
->setActor($viewer)
|
->setActor($viewer)
|
||||||
|
|
|
@ -38,21 +38,9 @@ final class PhabricatorDashboardMovePanelController
|
||||||
}
|
}
|
||||||
|
|
||||||
$layout_config = $dashboard->getLayoutConfigObject();
|
$layout_config = $dashboard->getLayoutConfigObject();
|
||||||
|
$layout_config->removePanel($panel_phid);
|
||||||
$panel_location_grid = $layout_config->getPanelLocations();
|
$panel_location_grid = $layout_config->getPanelLocations();
|
||||||
|
|
||||||
foreach ($panel_location_grid as $column => $panel_columns) {
|
|
||||||
$found_old_column = array_search($panel_phid, $panel_columns);
|
|
||||||
if ($found_old_column !== false) {
|
|
||||||
$new_panel_columns = $panel_columns;
|
|
||||||
array_splice(
|
|
||||||
$new_panel_columns,
|
|
||||||
$found_old_column,
|
|
||||||
1,
|
|
||||||
array());
|
|
||||||
$panel_location_grid[$column] = $new_panel_columns;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$panel_columns = idx($panel_location_grid, $column_id, array());
|
$panel_columns = idx($panel_location_grid, $column_id, array());
|
||||||
if ($panel_columns) {
|
if ($panel_columns) {
|
||||||
$insert_at = 0;
|
$insert_at = 0;
|
||||||
|
|
|
@ -52,7 +52,7 @@ final class PhabricatorDashboardPanelEditController
|
||||||
$title = pht('Edit %s', $panel->getMonogram());
|
$title = pht('Edit %s', $panel->getMonogram());
|
||||||
$header = pht('Edit %s %s', $panel->getMonogram(), $panel->getName());
|
$header = pht('Edit %s %s', $panel->getMonogram(), $panel->getName());
|
||||||
$button = pht('Save Panel');
|
$button = pht('Save Panel');
|
||||||
$cancel_uri = '/'.$panel->getMonogram();
|
$cancel_uri = $this->getPanelRedirectURI($panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
$v_name = $panel->getName();
|
$v_name = $panel->getName();
|
||||||
|
@ -89,7 +89,7 @@ final class PhabricatorDashboardPanelEditController
|
||||||
->applyTransactions($panel, $xactions);
|
->applyTransactions($panel, $xactions);
|
||||||
|
|
||||||
return id(new AphrontRedirectResponse())
|
return id(new AphrontRedirectResponse())
|
||||||
->setURI('/'.$panel->getMonogram());
|
->setURI($this->getPanelRedirectURI($panel));
|
||||||
} catch (PhabricatorApplicationTransactionValidationException $ex) {
|
} catch (PhabricatorApplicationTransactionValidationException $ex) {
|
||||||
$validation_exception = $ex;
|
$validation_exception = $ex;
|
||||||
|
|
||||||
|
@ -144,4 +144,16 @@ final class PhabricatorDashboardPanelEditController
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getPanelRedirectURI(PhabricatorDashboardPanel $panel) {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$dashboard_id = $request->getInt('dashboardID');
|
||||||
|
if ($dashboard_id) {
|
||||||
|
$uri = $this->getApplicationURI('arrange/'.$dashboard_id.'/');
|
||||||
|
} else {
|
||||||
|
$uri = '/'.$panel->getMonogram();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $uri;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,8 @@ final class PhabricatorDashboardPanelRenderController
|
||||||
->setViewer($viewer)
|
->setViewer($viewer)
|
||||||
->setPanel($panel)
|
->setPanel($panel)
|
||||||
->setParentPanelPHIDs($parent_phids)
|
->setParentPanelPHIDs($parent_phids)
|
||||||
->setHeaderless($request->getBool('headerless'))
|
->setHeaderMode($request->getStr('headerMode'))
|
||||||
|
->setDashboardID($request->getInt('dashboardID'))
|
||||||
->renderPanel();
|
->renderPanel();
|
||||||
|
|
||||||
if ($request->isAjax()) {
|
if ($request->isAjax()) {
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorDashboardRemovePanelController
|
||||||
|
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))
|
||||||
|
->requireCapabilities(
|
||||||
|
array(
|
||||||
|
PhabricatorPolicyCapability::CAN_VIEW,
|
||||||
|
PhabricatorPolicyCapability::CAN_EDIT,
|
||||||
|
))
|
||||||
|
->executeOne();
|
||||||
|
if (!$dashboard) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
$v_panel = $request->getStr('panelPHID');
|
||||||
|
$panel = id(new PhabricatorDashboardPanelQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withPHIDs(array($v_panel))
|
||||||
|
->executeOne();
|
||||||
|
if (!$panel) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
$redirect_uri = $this->getApplicationURI(
|
||||||
|
'arrange/'.$dashboard->getID().'/');
|
||||||
|
$layout_config = $dashboard->getLayoutConfigObject();
|
||||||
|
|
||||||
|
if ($request->isFormPost()) {
|
||||||
|
$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->removePanel($panel->getPHID());
|
||||||
|
$dashboard->setLayoutConfigFromObject($layout_config);
|
||||||
|
|
||||||
|
$editor = id(new PhabricatorDashboardTransactionEditor())
|
||||||
|
->setActor($viewer)
|
||||||
|
->setContentSourceFromRequest($request)
|
||||||
|
->setContinueOnMissingFields(true)
|
||||||
|
->setContinueOnNoEffect(true)
|
||||||
|
->applyTransactions($dashboard, $xactions);
|
||||||
|
|
||||||
|
return id(new AphrontRedirectResponse())->setURI($redirect_uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
$form = id(new AphrontFormView())
|
||||||
|
->setUser($viewer)
|
||||||
|
->addHiddenInput('confirm', true)
|
||||||
|
->addHiddenInput('panelPHID', $v_panel)
|
||||||
|
->appendChild(pht('Are you sure you want to remove this panel?'));
|
||||||
|
|
||||||
|
return $this->newDialog()
|
||||||
|
->setTitle(pht('Remove Panel %s', $panel->getMonogram()))
|
||||||
|
->appendChild($form->buildLayoutView())
|
||||||
|
->addCancelButton($redirect_uri)
|
||||||
|
->addSubmitButton(pht('Remove Panel'));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,19 +2,33 @@
|
||||||
|
|
||||||
final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
|
final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
|
||||||
|
|
||||||
|
const HEADER_MODE_NORMAL = 'normal';
|
||||||
|
const HEADER_MODE_NONE = 'none';
|
||||||
|
const HEADER_MODE_EDIT = 'edit';
|
||||||
|
|
||||||
private $panel;
|
private $panel;
|
||||||
private $viewer;
|
private $viewer;
|
||||||
private $enableAsyncRendering;
|
private $enableAsyncRendering;
|
||||||
private $parentPanelPHIDs;
|
private $parentPanelPHIDs;
|
||||||
private $headerless;
|
private $headerMode = self::HEADER_MODE_NORMAL;
|
||||||
|
private $dashboardID;
|
||||||
|
|
||||||
public function setHeaderless($headerless) {
|
public function setDashboardID($id) {
|
||||||
$this->headerless = $headerless;
|
$this->dashboardID = $id;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getHeaderless() {
|
public function getDashboardID() {
|
||||||
return $this->headerless;
|
return $this->dashboardID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setHeaderMode($header_mode) {
|
||||||
|
$this->headerMode = $header_mode;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHeaderMode() {
|
||||||
|
return $this->headerMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,14 +53,22 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getViewer() {
|
||||||
|
return $this->viewer;
|
||||||
|
}
|
||||||
|
|
||||||
public function setPanel(PhabricatorDashboardPanel $panel) {
|
public function setPanel(PhabricatorDashboardPanel $panel) {
|
||||||
$this->panel = $panel;
|
$this->panel = $panel;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getPanel() {
|
||||||
|
return $this->panel;
|
||||||
|
}
|
||||||
|
|
||||||
public function renderPanel() {
|
public function renderPanel() {
|
||||||
$panel = $this->panel;
|
$panel = $this->getPanel();
|
||||||
$viewer = $this->viewer;
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
if (!$panel) {
|
if (!$panel) {
|
||||||
return $this->renderErrorPanel(
|
return $this->renderErrorPanel(
|
||||||
|
@ -69,11 +91,11 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
|
||||||
|
|
||||||
if ($this->enableAsyncRendering) {
|
if ($this->enableAsyncRendering) {
|
||||||
if ($panel_type->shouldRenderAsync()) {
|
if ($panel_type->shouldRenderAsync()) {
|
||||||
return $this->renderAsyncPanel($panel);
|
return $this->renderAsyncPanel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $panel_type->renderPanel($viewer, $panel, $this);
|
return $this->renderNormalPanel($viewer, $panel, $this);
|
||||||
} catch (Exception $ex) {
|
} catch (Exception $ex) {
|
||||||
return $this->renderErrorPanel(
|
return $this->renderErrorPanel(
|
||||||
$panel->getName(),
|
$panel->getName(),
|
||||||
|
@ -84,47 +106,146 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function renderErrorPanel($title, $body) {
|
private function renderNormalPanel() {
|
||||||
if ($this->getHeaderless()) {
|
$panel = $this->getPanel();
|
||||||
return id(new AphrontErrorView())
|
$panel_type = $panel->getImplementation();
|
||||||
->setErrors(array($body));
|
|
||||||
} else {
|
$content = $panel_type->renderPanelContent(
|
||||||
return id(new PHUIObjectBoxView())
|
$this->getViewer(),
|
||||||
->setHeaderText($title)
|
$panel,
|
||||||
->setFormErrors(array($body));
|
$this);
|
||||||
}
|
$header = $this->renderPanelHeader();
|
||||||
|
|
||||||
|
return $this->renderPanelDiv(
|
||||||
|
$content,
|
||||||
|
$header);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function renderAsyncPanel(PhabricatorDashboardPanel $panel) {
|
|
||||||
|
private function renderAsyncPanel() {
|
||||||
|
$panel = $this->getPanel();
|
||||||
|
|
||||||
$panel_id = celerity_generate_unique_node_id();
|
$panel_id = celerity_generate_unique_node_id();
|
||||||
|
$dashboard_id = $this->getDashboardID();
|
||||||
|
|
||||||
Javelin::initBehavior(
|
Javelin::initBehavior(
|
||||||
'dashboard-async-panel',
|
'dashboard-async-panel',
|
||||||
array(
|
array(
|
||||||
'panelID' => $panel_id,
|
'panelID' => $panel_id,
|
||||||
'parentPanelPHIDs' => $this->getParentPanelPHIDs(),
|
'parentPanelPHIDs' => $this->getParentPanelPHIDs(),
|
||||||
'headerless' => $this->getHeaderless(),
|
'headerMode' => $this->getHeaderMode(),
|
||||||
|
'dashboardID' => $dashboard_id,
|
||||||
'uri' => '/dashboard/panel/render/'.$panel->getID().'/',
|
'uri' => '/dashboard/panel/render/'.$panel->getID().'/',
|
||||||
));
|
));
|
||||||
|
|
||||||
$content = pht('Loading...');
|
$header = $this->renderPanelHeader();
|
||||||
|
$content = id(new PHUIPropertyListView())
|
||||||
|
->addTextContent(pht('Loading...'));
|
||||||
|
|
||||||
if ($this->headerless) {
|
return $this->renderPanelDiv(
|
||||||
return phutil_tag(
|
$content,
|
||||||
|
$header,
|
||||||
|
$panel_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function renderErrorPanel($title, $body) {
|
||||||
|
switch ($this->getHeaderMode()) {
|
||||||
|
case self::HEADER_MODE_NONE:
|
||||||
|
$header = null;
|
||||||
|
break;
|
||||||
|
case self::HEADER_MODE_EDIT:
|
||||||
|
$header = id(new PhabricatorActionHeaderView())
|
||||||
|
->setHeaderTitle($title)
|
||||||
|
->setHeaderColor(PhabricatorActionHeaderView::HEADER_RED);
|
||||||
|
$header = $this->addPanelHeaderActions($header);
|
||||||
|
break;
|
||||||
|
case self::HEADER_MODE_NORMAL:
|
||||||
|
default:
|
||||||
|
$header = id(new PhabricatorActionHeaderView())
|
||||||
|
->setHeaderTitle($title)
|
||||||
|
->setHeaderColor(PhabricatorActionHeaderView::HEADER_RED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return $this->renderPanelDiv(
|
||||||
|
id(new AphrontErrorView())
|
||||||
|
->appendChild($body),
|
||||||
|
$header);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function renderPanelDiv(
|
||||||
|
$content,
|
||||||
|
$header = null,
|
||||||
|
$id = null) {
|
||||||
|
|
||||||
|
$panel = $this->getPanel();
|
||||||
|
if (!$id) {
|
||||||
|
$id = celerity_generate_unique_node_id();
|
||||||
|
}
|
||||||
|
return javelin_tag(
|
||||||
'div',
|
'div',
|
||||||
array(
|
array(
|
||||||
'id' => $panel_id,
|
'id' => $id,
|
||||||
),
|
'sigil' => 'dashboard-panel',
|
||||||
$content);
|
'meta' => array(
|
||||||
} else {
|
'objectPHID' => $panel->getPHID()),
|
||||||
return id(new PHUIObjectBoxView())
|
'class' => 'dashboard-panel'),
|
||||||
->addSigil('dashboard-panel')
|
array(
|
||||||
->setMetadata(array(
|
$header,
|
||||||
'objectPHID' => $panel->getPHID()))
|
$content));
|
||||||
->setHeaderText($panel->getName())
|
|
||||||
->setID($panel_id)
|
|
||||||
->appendChild($content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function renderPanelHeader() {
|
||||||
|
|
||||||
|
$panel = $this->getPanel();
|
||||||
|
switch ($this->getHeaderMode()) {
|
||||||
|
case self::HEADER_MODE_NONE:
|
||||||
|
$header = null;
|
||||||
|
break;
|
||||||
|
case self::HEADER_MODE_EDIT:
|
||||||
|
$header = id(new PhabricatorActionHeaderView())
|
||||||
|
->setHeaderTitle($panel->getName())
|
||||||
|
->setHeaderColor(PhabricatorActionHeaderView::HEADER_GREY);
|
||||||
|
$header = $this->addPanelHeaderActions($header);
|
||||||
|
break;
|
||||||
|
case self::HEADER_MODE_NORMAL:
|
||||||
|
default:
|
||||||
|
$header = id(new PhabricatorActionHeaderView())
|
||||||
|
->setHeaderTitle($panel->getName())
|
||||||
|
->setHeaderColor(PhabricatorActionHeaderView::HEADER_GREY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return $header;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function addPanelHeaderActions(
|
||||||
|
PhabricatorActionHeaderView $header) {
|
||||||
|
$panel = $this->getPanel();
|
||||||
|
|
||||||
|
$dashboard_id = $this->getDashboardID();
|
||||||
|
$edit_uri = id(new PhutilURI(
|
||||||
|
'/dashboard/panel/edit/'.$panel->getID().'/'));
|
||||||
|
if ($dashboard_id) {
|
||||||
|
$edit_uri->setQueryParam('dashboardID', $dashboard_id);
|
||||||
|
}
|
||||||
|
$action_edit = id(new PHUIIconView())
|
||||||
|
->setSpriteSheet(PHUIIconView::SPRITE_ACTIONS)
|
||||||
|
->setSpriteIcon('settings-grey')
|
||||||
|
->setHref((string) $edit_uri);
|
||||||
|
$header->addAction($action_edit);
|
||||||
|
|
||||||
|
if ($dashboard_id) {
|
||||||
|
$uri = id(new PhutilURI(
|
||||||
|
'/dashboard/removepanel/'.$dashboard_id.'/'))
|
||||||
|
->setQueryParam('panelPHID', $panel->getPHID());
|
||||||
|
$action_remove = id(new PHUIIconView())
|
||||||
|
->setSpriteSheet(PHUIIconView::SPRITE_ACTIONS)
|
||||||
|
->setSpriteIcon('close-grey')
|
||||||
|
->setHref((string) $uri)
|
||||||
|
->setWorkflow(true);
|
||||||
|
$header->addAction($action_remove);
|
||||||
|
}
|
||||||
|
return $header;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -34,6 +34,11 @@ final class PhabricatorDashboardRenderingEngine extends Phobject {
|
||||||
->setID($dashboard_id)
|
->setID($dashboard_id)
|
||||||
->setFluidlayout(true);
|
->setFluidlayout(true);
|
||||||
|
|
||||||
|
if ($this->arrangeMode) {
|
||||||
|
$h_mode = PhabricatorDashboardPanelRenderingEngine::HEADER_MODE_EDIT;
|
||||||
|
} else {
|
||||||
|
$h_mode = PhabricatorDashboardPanelRenderingEngine::HEADER_MODE_NORMAL;
|
||||||
|
}
|
||||||
foreach ($panel_grid_locations as $column => $panel_column_locations) {
|
foreach ($panel_grid_locations as $column => $panel_column_locations) {
|
||||||
$panel_phids = $panel_column_locations;
|
$panel_phids = $panel_column_locations;
|
||||||
$column_panels = array_select_keys($panels, $panel_phids);
|
$column_panels = array_select_keys($panels, $panel_phids);
|
||||||
|
@ -42,8 +47,10 @@ final class PhabricatorDashboardRenderingEngine extends Phobject {
|
||||||
$column_result[] = id(new PhabricatorDashboardPanelRenderingEngine())
|
$column_result[] = id(new PhabricatorDashboardPanelRenderingEngine())
|
||||||
->setViewer($viewer)
|
->setViewer($viewer)
|
||||||
->setPanel($panel)
|
->setPanel($panel)
|
||||||
|
->setDashboardID($dashboard->getID())
|
||||||
->setEnableAsyncRendering(true)
|
->setEnableAsyncRendering(true)
|
||||||
->setParentPanelPHIDs(array())
|
->setParentPanelPHIDs(array())
|
||||||
|
->setHeaderMode($h_mode)
|
||||||
->renderPanel();
|
->renderPanel();
|
||||||
}
|
}
|
||||||
$column_class = $layout_config->getColumnClass(
|
$column_class = $layout_config->getColumnClass(
|
||||||
|
|
|
@ -32,6 +32,24 @@ final class PhabricatorDashboardLayoutConfig {
|
||||||
return $this->panelLocations;
|
return $this->panelLocations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function removePanel($panel_phid) {
|
||||||
|
$panel_location_grid = $this->getPanelLocations();
|
||||||
|
foreach ($panel_location_grid as $column => $panel_columns) {
|
||||||
|
$found_old_column = array_search($panel_phid, $panel_columns);
|
||||||
|
if ($found_old_column !== false) {
|
||||||
|
$new_panel_columns = $panel_columns;
|
||||||
|
array_splice(
|
||||||
|
$new_panel_columns,
|
||||||
|
$found_old_column,
|
||||||
|
1,
|
||||||
|
array());
|
||||||
|
$panel_location_grid[$column] = $new_panel_columns;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->setPanelLocations($panel_location_grid);
|
||||||
|
}
|
||||||
|
|
||||||
public function getDefaultPanelLocations() {
|
public function getDefaultPanelLocations() {
|
||||||
switch ($this->getLayoutMode()) {
|
switch ($this->getLayoutMode()) {
|
||||||
case self::MODE_HALF_AND_HALF:
|
case self::MODE_HALF_AND_HALF:
|
||||||
|
|
|
@ -40,26 +40,9 @@ abstract class PhabricatorDashboardPanelType extends Phobject {
|
||||||
return $types;
|
return $types;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function renderPanel(
|
|
||||||
PhabricatorUser $viewer,
|
|
||||||
PhabricatorDashboardPanel $panel,
|
|
||||||
PhabricatorDashboardPanelRenderingEngine $engine) {
|
|
||||||
|
|
||||||
$content = $this->renderPanelContent($viewer, $panel, $engine);
|
|
||||||
|
|
||||||
if ($engine->getHeaderless()) {
|
public function renderPanelContent(
|
||||||
return $content;
|
|
||||||
}
|
|
||||||
|
|
||||||
return id(new PHUIObjectBoxView())
|
|
||||||
->addSigil('dashboard-panel')
|
|
||||||
->setMetadata(array(
|
|
||||||
'objectPHID' => $panel->getPHID()))
|
|
||||||
->setHeaderText($panel->getName())
|
|
||||||
->appendChild($content);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function renderPanelContent(
|
|
||||||
PhabricatorUser $viewer,
|
PhabricatorUser $viewer,
|
||||||
PhabricatorDashboardPanel $panel,
|
PhabricatorDashboardPanel $panel,
|
||||||
PhabricatorDashboardPanelRenderingEngine $engine) {
|
PhabricatorDashboardPanelRenderingEngine $engine) {
|
||||||
|
|
|
@ -30,7 +30,7 @@ final class PhabricatorDashboardPanelTypeQuery
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function renderPanelContent(
|
public function renderPanelContent(
|
||||||
PhabricatorUser $viewer,
|
PhabricatorUser $viewer,
|
||||||
PhabricatorDashboardPanel $panel,
|
PhabricatorDashboardPanel $panel,
|
||||||
PhabricatorDashboardPanelRenderingEngine $engine) {
|
PhabricatorDashboardPanelRenderingEngine $engine) {
|
||||||
|
|
|
@ -25,7 +25,7 @@ final class PhabricatorDashboardPanelTypeTabs
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function renderPanelContent(
|
public function renderPanelContent(
|
||||||
PhabricatorUser $viewer,
|
PhabricatorUser $viewer,
|
||||||
PhabricatorDashboardPanel $panel,
|
PhabricatorDashboardPanel $panel,
|
||||||
PhabricatorDashboardPanelRenderingEngine $engine) {
|
PhabricatorDashboardPanelRenderingEngine $engine) {
|
||||||
|
@ -81,6 +81,7 @@ final class PhabricatorDashboardPanelTypeTabs
|
||||||
$parent_phids[] = $panel->getPHID();
|
$parent_phids[] = $panel->getPHID();
|
||||||
|
|
||||||
$content = array();
|
$content = array();
|
||||||
|
$no_headers = PhabricatorDashboardPanelRenderingEngine::HEADER_MODE_NONE;
|
||||||
foreach ($config as $idx => $tab_spec) {
|
foreach ($config as $idx => $tab_spec) {
|
||||||
$panel_id = idx($tab_spec, 'panelID');
|
$panel_id = idx($tab_spec, 'panelID');
|
||||||
$panel = idx($panels, $panel_id);
|
$panel = idx($panels, $panel_id);
|
||||||
|
@ -91,7 +92,7 @@ final class PhabricatorDashboardPanelTypeTabs
|
||||||
->setEnableAsyncRendering(true)
|
->setEnableAsyncRendering(true)
|
||||||
->setParentPanelPHIDs($parent_phids)
|
->setParentPanelPHIDs($parent_phids)
|
||||||
->setPanel($panel)
|
->setPanel($panel)
|
||||||
->setHeaderless(true)
|
->setHeaderMode($no_headers)
|
||||||
->renderPanel();
|
->renderPanel();
|
||||||
} else {
|
} else {
|
||||||
$panel_content = pht('(Invalid Panel)');
|
$panel_content = pht('(Invalid Panel)');
|
||||||
|
|
|
@ -26,7 +26,7 @@ final class PhabricatorDashboardPanelTypeText
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function renderPanelContent(
|
public function renderPanelContent(
|
||||||
PhabricatorUser $viewer,
|
PhabricatorUser $viewer,
|
||||||
PhabricatorDashboardPanel $panel,
|
PhabricatorDashboardPanel $panel,
|
||||||
PhabricatorDashboardPanelRenderingEngine $engine) {
|
PhabricatorDashboardPanelRenderingEngine $engine) {
|
||||||
|
|
|
@ -17,9 +17,15 @@
|
||||||
width: 66.66%;
|
width: 66.66%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.aphront-multi-column-fluid
|
||||||
|
.aphront-multi-column-column-outer
|
||||||
|
.aphront-multi-column-column .dashboard-panel {
|
||||||
|
margin: 16px 16px 0px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
.aphront-multi-column-fluid
|
.aphront-multi-column-fluid
|
||||||
.aphront-multi-column-column-outer.grippable
|
.aphront-multi-column-column-outer.grippable
|
||||||
.aphront-multi-column-column .phui-object-box {
|
.aphront-multi-column-column .dashboard-panel {
|
||||||
cursor: move;
|
cursor: move;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,3 +63,9 @@
|
||||||
.dashboard-panel-placeholder {
|
.dashboard-panel-placeholder {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.aphront-multi-column-fluid
|
||||||
|
.aphront-multi-column-column-outer
|
||||||
|
.aphront-multi-column-column .aphront-error-view {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
|
@ -11,7 +11,8 @@ JX.behavior('dashboard-async-panel', function(config) {
|
||||||
|
|
||||||
var data = {
|
var data = {
|
||||||
parentPanelPHIDs: config.parentPanelPHIDs.join(','),
|
parentPanelPHIDs: config.parentPanelPHIDs.join(','),
|
||||||
headerless: config.headerless ? 1 : 0
|
headerMode: config.headerMode,
|
||||||
|
dashboardID: config.dashboardID
|
||||||
};
|
};
|
||||||
|
|
||||||
new JX.Workflow(config.uri)
|
new JX.Workflow(config.uri)
|
||||||
|
|
Loading…
Reference in a new issue