mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-18 12:52:42 +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/contentsource/content-source-view.css' => '4b8b05d4',
|
||||
'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/differential/add-comment.css' => 'c478bcaa',
|
||||
'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-widget-pane.js' => '40b1ff90',
|
||||
'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/differential/DifferentialInlineCommentEditor.js' => 'f2441746',
|
||||
'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-countdown-timer' => '889c96f3',
|
||||
'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-device' => '03d6ed07',
|
||||
'javelin-behavior-differential-add-reviewers-and-ccs' => '533a187b',
|
||||
|
@ -698,7 +698,7 @@ return array(
|
|||
'phabricator-core-css' => '40151074',
|
||||
'phabricator-countdown-css' => '86b7b0a0',
|
||||
'phabricator-crumbs-view-css' => '6a23399c',
|
||||
'phabricator-dashboard-css' => '2b41640b',
|
||||
'phabricator-dashboard-css' => 'fbf815b5',
|
||||
'phabricator-drag-and-drop-file-upload' => 'ae6abfba',
|
||||
'phabricator-draggable-list' => '1681c4d4',
|
||||
'phabricator-fatal-config-template-css' => '25d446d6',
|
||||
|
@ -1129,6 +1129,12 @@ return array(
|
|||
1 => 'javelin-stratcom',
|
||||
2 => 'javelin-dom',
|
||||
),
|
||||
'469c0d9e' =>
|
||||
array(
|
||||
0 => 'javelin-behavior',
|
||||
1 => 'javelin-dom',
|
||||
2 => 'javelin-workflow',
|
||||
),
|
||||
'46efd18e' =>
|
||||
array(
|
||||
0 => 'multirow-row-manager',
|
||||
|
@ -1254,6 +1260,13 @@ return array(
|
|||
2 => 'javelin-util',
|
||||
3 => 'phabricator-shaped-request',
|
||||
),
|
||||
'62e18640' =>
|
||||
array(
|
||||
0 => 'javelin-install',
|
||||
1 => 'javelin-util',
|
||||
2 => 'javelin-dom',
|
||||
3 => 'javelin-typeahead-normalizer',
|
||||
),
|
||||
'6453c869' =>
|
||||
array(
|
||||
0 => 'javelin-install',
|
||||
|
@ -1322,13 +1335,6 @@ return array(
|
|||
0 => 'javelin-behavior',
|
||||
1 => 'javelin-dom',
|
||||
),
|
||||
'62e18640' =>
|
||||
array(
|
||||
0 => 'javelin-install',
|
||||
1 => 'javelin-util',
|
||||
2 => 'javelin-dom',
|
||||
3 => 'javelin-typeahead-normalizer',
|
||||
),
|
||||
'76f4ebed' =>
|
||||
array(
|
||||
0 => 'javelin-install',
|
||||
|
@ -1961,12 +1967,6 @@ return array(
|
|||
0 => 'javelin-install',
|
||||
1 => 'javelin-util',
|
||||
),
|
||||
'f1375ea5' =>
|
||||
array(
|
||||
0 => 'javelin-behavior',
|
||||
1 => 'javelin-dom',
|
||||
2 => 'javelin-workflow',
|
||||
),
|
||||
'f2441746' =>
|
||||
array(
|
||||
0 => 'javelin-dom',
|
||||
|
|
|
@ -1487,6 +1487,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorDashboardPanelTypeText' => 'applications/dashboard/paneltype/PhabricatorDashboardPanelTypeText.php',
|
||||
'PhabricatorDashboardPanelViewController' => 'applications/dashboard/controller/PhabricatorDashboardPanelViewController.php',
|
||||
'PhabricatorDashboardQuery' => 'applications/dashboard/query/PhabricatorDashboardQuery.php',
|
||||
'PhabricatorDashboardRemovePanelController' => 'applications/dashboard/controller/PhabricatorDashboardRemovePanelController.php',
|
||||
'PhabricatorDashboardRenderingEngine' => 'applications/dashboard/engine/PhabricatorDashboardRenderingEngine.php',
|
||||
'PhabricatorDashboardSearchEngine' => 'applications/dashboard/query/PhabricatorDashboardSearchEngine.php',
|
||||
'PhabricatorDashboardTransaction' => 'applications/dashboard/storage/PhabricatorDashboardTransaction.php',
|
||||
|
@ -4278,6 +4279,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorDashboardPanelTypeText' => 'PhabricatorDashboardPanelType',
|
||||
'PhabricatorDashboardPanelViewController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhabricatorDashboardRemovePanelController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardRenderingEngine' => 'Phobject',
|
||||
'PhabricatorDashboardSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PhabricatorDashboardTransaction' => 'PhabricatorApplicationTransaction',
|
||||
|
|
|
@ -26,6 +26,8 @@ final class PhabricatorApplicationDashboard extends PhabricatorApplication {
|
|||
'edit/(?:(?P<id>\d+)/)?' => 'PhabricatorDashboardEditController',
|
||||
'addpanel/(?P<id>\d+)/' => 'PhabricatorDashboardAddPanelController',
|
||||
'movepanel/(?P<id>\d+)/' => 'PhabricatorDashboardMovePanelController',
|
||||
'removepanel/(?P<id>\d+)/'
|
||||
=> 'PhabricatorDashboardRemovePanelController',
|
||||
'panel/' => array(
|
||||
'(?:query/(?P<queryKey>[^/]+)/)?'
|
||||
=> 'PhabricatorDashboardPanelListController',
|
||||
|
|
|
@ -68,12 +68,10 @@ final class PhabricatorDashboardAddPanelController
|
|||
),
|
||||
));
|
||||
|
||||
if ($layout_config->isMultiColumnLayout()) {
|
||||
$layout_config->setPanelLocation(
|
||||
$request->getInt('column'),
|
||||
$request->getInt('column', 0),
|
||||
$panel->getPHID());
|
||||
$dashboard->setLayoutConfigFromObject($layout_config);
|
||||
}
|
||||
|
||||
$editor = id(new PhabricatorDashboardTransactionEditor())
|
||||
->setActor($viewer)
|
||||
|
|
|
@ -38,21 +38,9 @@ final class PhabricatorDashboardMovePanelController
|
|||
}
|
||||
|
||||
$layout_config = $dashboard->getLayoutConfigObject();
|
||||
$layout_config->removePanel($panel_phid);
|
||||
$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());
|
||||
if ($panel_columns) {
|
||||
$insert_at = 0;
|
||||
|
|
|
@ -52,7 +52,7 @@ final class PhabricatorDashboardPanelEditController
|
|||
$title = pht('Edit %s', $panel->getMonogram());
|
||||
$header = pht('Edit %s %s', $panel->getMonogram(), $panel->getName());
|
||||
$button = pht('Save Panel');
|
||||
$cancel_uri = '/'.$panel->getMonogram();
|
||||
$cancel_uri = $this->getPanelRedirectURI($panel);
|
||||
}
|
||||
|
||||
$v_name = $panel->getName();
|
||||
|
@ -89,7 +89,7 @@ final class PhabricatorDashboardPanelEditController
|
|||
->applyTransactions($panel, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/'.$panel->getMonogram());
|
||||
->setURI($this->getPanelRedirectURI($panel));
|
||||
} catch (PhabricatorApplicationTransactionValidationException $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)
|
||||
->setPanel($panel)
|
||||
->setParentPanelPHIDs($parent_phids)
|
||||
->setHeaderless($request->getBool('headerless'))
|
||||
->setHeaderMode($request->getStr('headerMode'))
|
||||
->setDashboardID($request->getInt('dashboardID'))
|
||||
->renderPanel();
|
||||
|
||||
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 {
|
||||
|
||||
const HEADER_MODE_NORMAL = 'normal';
|
||||
const HEADER_MODE_NONE = 'none';
|
||||
const HEADER_MODE_EDIT = 'edit';
|
||||
|
||||
private $panel;
|
||||
private $viewer;
|
||||
private $enableAsyncRendering;
|
||||
private $parentPanelPHIDs;
|
||||
private $headerless;
|
||||
private $headerMode = self::HEADER_MODE_NORMAL;
|
||||
private $dashboardID;
|
||||
|
||||
public function setHeaderless($headerless) {
|
||||
$this->headerless = $headerless;
|
||||
public function setDashboardID($id) {
|
||||
$this->dashboardID = $id;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getHeaderless() {
|
||||
return $this->headerless;
|
||||
public function getDashboardID() {
|
||||
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;
|
||||
}
|
||||
|
||||
public function getViewer() {
|
||||
return $this->viewer;
|
||||
}
|
||||
|
||||
public function setPanel(PhabricatorDashboardPanel $panel) {
|
||||
$this->panel = $panel;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPanel() {
|
||||
return $this->panel;
|
||||
}
|
||||
|
||||
public function renderPanel() {
|
||||
$panel = $this->panel;
|
||||
$viewer = $this->viewer;
|
||||
$panel = $this->getPanel();
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
if (!$panel) {
|
||||
return $this->renderErrorPanel(
|
||||
|
@ -69,11 +91,11 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
|
|||
|
||||
if ($this->enableAsyncRendering) {
|
||||
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) {
|
||||
return $this->renderErrorPanel(
|
||||
$panel->getName(),
|
||||
|
@ -84,47 +106,146 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
|
|||
}
|
||||
}
|
||||
|
||||
private function renderErrorPanel($title, $body) {
|
||||
if ($this->getHeaderless()) {
|
||||
return id(new AphrontErrorView())
|
||||
->setErrors(array($body));
|
||||
} else {
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeaderText($title)
|
||||
->setFormErrors(array($body));
|
||||
}
|
||||
private function renderNormalPanel() {
|
||||
$panel = $this->getPanel();
|
||||
$panel_type = $panel->getImplementation();
|
||||
|
||||
$content = $panel_type->renderPanelContent(
|
||||
$this->getViewer(),
|
||||
$panel,
|
||||
$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();
|
||||
$dashboard_id = $this->getDashboardID();
|
||||
|
||||
Javelin::initBehavior(
|
||||
'dashboard-async-panel',
|
||||
array(
|
||||
'panelID' => $panel_id,
|
||||
'parentPanelPHIDs' => $this->getParentPanelPHIDs(),
|
||||
'headerless' => $this->getHeaderless(),
|
||||
'headerMode' => $this->getHeaderMode(),
|
||||
'dashboardID' => $dashboard_id,
|
||||
'uri' => '/dashboard/panel/render/'.$panel->getID().'/',
|
||||
));
|
||||
|
||||
$content = pht('Loading...');
|
||||
$header = $this->renderPanelHeader();
|
||||
$content = id(new PHUIPropertyListView())
|
||||
->addTextContent(pht('Loading...'));
|
||||
|
||||
if ($this->headerless) {
|
||||
return phutil_tag(
|
||||
return $this->renderPanelDiv(
|
||||
$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',
|
||||
array(
|
||||
'id' => $panel_id,
|
||||
),
|
||||
$content);
|
||||
} else {
|
||||
return id(new PHUIObjectBoxView())
|
||||
->addSigil('dashboard-panel')
|
||||
->setMetadata(array(
|
||||
'objectPHID' => $panel->getPHID()))
|
||||
->setHeaderText($panel->getName())
|
||||
->setID($panel_id)
|
||||
->appendChild($content);
|
||||
'id' => $id,
|
||||
'sigil' => 'dashboard-panel',
|
||||
'meta' => array(
|
||||
'objectPHID' => $panel->getPHID()),
|
||||
'class' => 'dashboard-panel'),
|
||||
array(
|
||||
$header,
|
||||
$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)
|
||||
->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) {
|
||||
$panel_phids = $panel_column_locations;
|
||||
$column_panels = array_select_keys($panels, $panel_phids);
|
||||
|
@ -42,8 +47,10 @@ final class PhabricatorDashboardRenderingEngine extends Phobject {
|
|||
$column_result[] = id(new PhabricatorDashboardPanelRenderingEngine())
|
||||
->setViewer($viewer)
|
||||
->setPanel($panel)
|
||||
->setDashboardID($dashboard->getID())
|
||||
->setEnableAsyncRendering(true)
|
||||
->setParentPanelPHIDs(array())
|
||||
->setHeaderMode($h_mode)
|
||||
->renderPanel();
|
||||
}
|
||||
$column_class = $layout_config->getColumnClass(
|
||||
|
|
|
@ -32,6 +32,24 @@ final class PhabricatorDashboardLayoutConfig {
|
|||
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() {
|
||||
switch ($this->getLayoutMode()) {
|
||||
case self::MODE_HALF_AND_HALF:
|
||||
|
|
|
@ -40,26 +40,9 @@ abstract class PhabricatorDashboardPanelType extends Phobject {
|
|||
return $types;
|
||||
}
|
||||
|
||||
public function renderPanel(
|
||||
PhabricatorUser $viewer,
|
||||
PhabricatorDashboardPanel $panel,
|
||||
PhabricatorDashboardPanelRenderingEngine $engine) {
|
||||
|
||||
$content = $this->renderPanelContent($viewer, $panel, $engine);
|
||||
|
||||
if ($engine->getHeaderless()) {
|
||||
return $content;
|
||||
}
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->addSigil('dashboard-panel')
|
||||
->setMetadata(array(
|
||||
'objectPHID' => $panel->getPHID()))
|
||||
->setHeaderText($panel->getName())
|
||||
->appendChild($content);
|
||||
}
|
||||
|
||||
protected function renderPanelContent(
|
||||
public function renderPanelContent(
|
||||
PhabricatorUser $viewer,
|
||||
PhabricatorDashboardPanel $panel,
|
||||
PhabricatorDashboardPanelRenderingEngine $engine) {
|
||||
|
|
|
@ -30,7 +30,7 @@ final class PhabricatorDashboardPanelTypeQuery
|
|||
);
|
||||
}
|
||||
|
||||
protected function renderPanelContent(
|
||||
public function renderPanelContent(
|
||||
PhabricatorUser $viewer,
|
||||
PhabricatorDashboardPanel $panel,
|
||||
PhabricatorDashboardPanelRenderingEngine $engine) {
|
||||
|
|
|
@ -25,7 +25,7 @@ final class PhabricatorDashboardPanelTypeTabs
|
|||
);
|
||||
}
|
||||
|
||||
protected function renderPanelContent(
|
||||
public function renderPanelContent(
|
||||
PhabricatorUser $viewer,
|
||||
PhabricatorDashboardPanel $panel,
|
||||
PhabricatorDashboardPanelRenderingEngine $engine) {
|
||||
|
@ -81,6 +81,7 @@ final class PhabricatorDashboardPanelTypeTabs
|
|||
$parent_phids[] = $panel->getPHID();
|
||||
|
||||
$content = array();
|
||||
$no_headers = PhabricatorDashboardPanelRenderingEngine::HEADER_MODE_NONE;
|
||||
foreach ($config as $idx => $tab_spec) {
|
||||
$panel_id = idx($tab_spec, 'panelID');
|
||||
$panel = idx($panels, $panel_id);
|
||||
|
@ -91,7 +92,7 @@ final class PhabricatorDashboardPanelTypeTabs
|
|||
->setEnableAsyncRendering(true)
|
||||
->setParentPanelPHIDs($parent_phids)
|
||||
->setPanel($panel)
|
||||
->setHeaderless(true)
|
||||
->setHeaderMode($no_headers)
|
||||
->renderPanel();
|
||||
} else {
|
||||
$panel_content = pht('(Invalid Panel)');
|
||||
|
|
|
@ -26,7 +26,7 @@ final class PhabricatorDashboardPanelTypeText
|
|||
);
|
||||
}
|
||||
|
||||
protected function renderPanelContent(
|
||||
public function renderPanelContent(
|
||||
PhabricatorUser $viewer,
|
||||
PhabricatorDashboardPanel $panel,
|
||||
PhabricatorDashboardPanelRenderingEngine $engine) {
|
||||
|
|
|
@ -17,9 +17,15 @@
|
|||
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-column-outer.grippable
|
||||
.aphront-multi-column-column .phui-object-box {
|
||||
.aphront-multi-column-column .dashboard-panel {
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
|
@ -57,3 +63,9 @@
|
|||
.dashboard-panel-placeholder {
|
||||
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 = {
|
||||
parentPanelPHIDs: config.parentPanelPHIDs.join(','),
|
||||
headerless: config.headerless ? 1 : 0
|
||||
headerMode: config.headerMode,
|
||||
dashboardID: config.dashboardID
|
||||
};
|
||||
|
||||
new JX.Workflow(config.uri)
|
||||
|
|
Loading…
Reference in a new issue