@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+327 -99
+17 -17
resources/celerity/map.php
··· 52 52 'rsrc/css/application/conpherence/widget-pane.css' => 'bf275a6c', 53 53 'rsrc/css/application/contentsource/content-source-view.css' => '4b8b05d4', 54 54 'rsrc/css/application/countdown/timer.css' => '86b7b0a0', 55 - 'rsrc/css/application/dashboard/dashboard.css' => '2b41640b', 55 + 'rsrc/css/application/dashboard/dashboard.css' => 'fbf815b5', 56 56 'rsrc/css/application/diff/inline-comment-summary.css' => '8cfd34e8', 57 57 'rsrc/css/application/differential/add-comment.css' => 'c478bcaa', 58 58 'rsrc/css/application/differential/changeset-view.css' => 'c45747f0', ··· 355 355 'rsrc/js/application/conpherence/behavior-pontificate.js' => '53f6f2dd', 356 356 'rsrc/js/application/conpherence/behavior-widget-pane.js' => '40b1ff90', 357 357 'rsrc/js/application/countdown/timer.js' => '889c96f3', 358 - 'rsrc/js/application/dashboard/behavior-dashboard-async-panel.js' => 'f1375ea5', 358 + 'rsrc/js/application/dashboard/behavior-dashboard-async-panel.js' => '469c0d9e', 359 359 'rsrc/js/application/dashboard/behavior-dashboard-move-panels.js' => 'fa187a68', 360 360 'rsrc/js/application/differential/DifferentialInlineCommentEditor.js' => 'f2441746', 361 361 'rsrc/js/application/differential/behavior-add-reviewers-and-ccs.js' => '533a187b', ··· 550 550 'javelin-behavior-conpherence-widget-pane' => '40b1ff90', 551 551 'javelin-behavior-countdown-timer' => '889c96f3', 552 552 'javelin-behavior-dark-console' => 'e9fdb5e5', 553 - 'javelin-behavior-dashboard-async-panel' => 'f1375ea5', 553 + 'javelin-behavior-dashboard-async-panel' => '469c0d9e', 554 554 'javelin-behavior-dashboard-move-panels' => 'fa187a68', 555 555 'javelin-behavior-device' => '03d6ed07', 556 556 'javelin-behavior-differential-add-reviewers-and-ccs' => '533a187b', ··· 698 698 'phabricator-core-css' => '40151074', 699 699 'phabricator-countdown-css' => '86b7b0a0', 700 700 'phabricator-crumbs-view-css' => '6a23399c', 701 - 'phabricator-dashboard-css' => '2b41640b', 701 + 'phabricator-dashboard-css' => 'fbf815b5', 702 702 'phabricator-drag-and-drop-file-upload' => 'ae6abfba', 703 703 'phabricator-draggable-list' => '1681c4d4', 704 704 'phabricator-fatal-config-template-css' => '25d446d6', ··· 1129 1129 1 => 'javelin-stratcom', 1130 1130 2 => 'javelin-dom', 1131 1131 ), 1132 + '469c0d9e' => 1133 + array( 1134 + 0 => 'javelin-behavior', 1135 + 1 => 'javelin-dom', 1136 + 2 => 'javelin-workflow', 1137 + ), 1132 1138 '46efd18e' => 1133 1139 array( 1134 1140 0 => 'multirow-row-manager', ··· 1254 1260 2 => 'javelin-util', 1255 1261 3 => 'phabricator-shaped-request', 1256 1262 ), 1263 + '62e18640' => 1264 + array( 1265 + 0 => 'javelin-install', 1266 + 1 => 'javelin-util', 1267 + 2 => 'javelin-dom', 1268 + 3 => 'javelin-typeahead-normalizer', 1269 + ), 1257 1270 '6453c869' => 1258 1271 array( 1259 1272 0 => 'javelin-install', ··· 1321 1334 array( 1322 1335 0 => 'javelin-behavior', 1323 1336 1 => 'javelin-dom', 1324 - ), 1325 - '62e18640' => 1326 - array( 1327 - 0 => 'javelin-install', 1328 - 1 => 'javelin-util', 1329 - 2 => 'javelin-dom', 1330 - 3 => 'javelin-typeahead-normalizer', 1331 1337 ), 1332 1338 '76f4ebed' => 1333 1339 array( ··· 1960 1966 array( 1961 1967 0 => 'javelin-install', 1962 1968 1 => 'javelin-util', 1963 - ), 1964 - 'f1375ea5' => 1965 - array( 1966 - 0 => 'javelin-behavior', 1967 - 1 => 'javelin-dom', 1968 - 2 => 'javelin-workflow', 1969 1969 ), 1970 1970 'f2441746' => 1971 1971 array(
+2
src/__phutil_library_map__.php
··· 1487 1487 'PhabricatorDashboardPanelTypeText' => 'applications/dashboard/paneltype/PhabricatorDashboardPanelTypeText.php', 1488 1488 'PhabricatorDashboardPanelViewController' => 'applications/dashboard/controller/PhabricatorDashboardPanelViewController.php', 1489 1489 'PhabricatorDashboardQuery' => 'applications/dashboard/query/PhabricatorDashboardQuery.php', 1490 + 'PhabricatorDashboardRemovePanelController' => 'applications/dashboard/controller/PhabricatorDashboardRemovePanelController.php', 1490 1491 'PhabricatorDashboardRenderingEngine' => 'applications/dashboard/engine/PhabricatorDashboardRenderingEngine.php', 1491 1492 'PhabricatorDashboardSearchEngine' => 'applications/dashboard/query/PhabricatorDashboardSearchEngine.php', 1492 1493 'PhabricatorDashboardTransaction' => 'applications/dashboard/storage/PhabricatorDashboardTransaction.php', ··· 4278 4279 'PhabricatorDashboardPanelTypeText' => 'PhabricatorDashboardPanelType', 4279 4280 'PhabricatorDashboardPanelViewController' => 'PhabricatorDashboardController', 4280 4281 'PhabricatorDashboardQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 4282 + 'PhabricatorDashboardRemovePanelController' => 'PhabricatorDashboardController', 4281 4283 'PhabricatorDashboardRenderingEngine' => 'Phobject', 4282 4284 'PhabricatorDashboardSearchEngine' => 'PhabricatorApplicationSearchEngine', 4283 4285 'PhabricatorDashboardTransaction' => 'PhabricatorApplicationTransaction',
+2
src/applications/dashboard/application/PhabricatorApplicationDashboard.php
··· 26 26 'edit/(?:(?P<id>\d+)/)?' => 'PhabricatorDashboardEditController', 27 27 'addpanel/(?P<id>\d+)/' => 'PhabricatorDashboardAddPanelController', 28 28 'movepanel/(?P<id>\d+)/' => 'PhabricatorDashboardMovePanelController', 29 + 'removepanel/(?P<id>\d+)/' 30 + => 'PhabricatorDashboardRemovePanelController', 29 31 'panel/' => array( 30 32 '(?:query/(?P<queryKey>[^/]+)/)?' 31 33 => 'PhabricatorDashboardPanelListController',
+4 -6
src/applications/dashboard/controller/PhabricatorDashboardAddPanelController.php
··· 68 68 ), 69 69 )); 70 70 71 - if ($layout_config->isMultiColumnLayout()) { 72 - $layout_config->setPanelLocation( 73 - $request->getInt('column'), 74 - $panel->getPHID()); 75 - $dashboard->setLayoutConfigFromObject($layout_config); 76 - } 71 + $layout_config->setPanelLocation( 72 + $request->getInt('column', 0), 73 + $panel->getPHID()); 74 + $dashboard->setLayoutConfigFromObject($layout_config); 77 75 78 76 $editor = id(new PhabricatorDashboardTransactionEditor()) 79 77 ->setActor($viewer)
+1 -13
src/applications/dashboard/controller/PhabricatorDashboardMovePanelController.php
··· 38 38 } 39 39 40 40 $layout_config = $dashboard->getLayoutConfigObject(); 41 + $layout_config->removePanel($panel_phid); 41 42 $panel_location_grid = $layout_config->getPanelLocations(); 42 43 43 - foreach ($panel_location_grid as $column => $panel_columns) { 44 - $found_old_column = array_search($panel_phid, $panel_columns); 45 - if ($found_old_column !== false) { 46 - $new_panel_columns = $panel_columns; 47 - array_splice( 48 - $new_panel_columns, 49 - $found_old_column, 50 - 1, 51 - array()); 52 - $panel_location_grid[$column] = $new_panel_columns; 53 - break; 54 - } 55 - } 56 44 $panel_columns = idx($panel_location_grid, $column_id, array()); 57 45 if ($panel_columns) { 58 46 $insert_at = 0;
+14 -2
src/applications/dashboard/controller/PhabricatorDashboardPanelEditController.php
··· 52 52 $title = pht('Edit %s', $panel->getMonogram()); 53 53 $header = pht('Edit %s %s', $panel->getMonogram(), $panel->getName()); 54 54 $button = pht('Save Panel'); 55 - $cancel_uri = '/'.$panel->getMonogram(); 55 + $cancel_uri = $this->getPanelRedirectURI($panel); 56 56 } 57 57 58 58 $v_name = $panel->getName(); ··· 89 89 ->applyTransactions($panel, $xactions); 90 90 91 91 return id(new AphrontRedirectResponse()) 92 - ->setURI('/'.$panel->getMonogram()); 92 + ->setURI($this->getPanelRedirectURI($panel)); 93 93 } catch (PhabricatorApplicationTransactionValidationException $ex) { 94 94 $validation_exception = $ex; 95 95 ··· 142 142 'title' => $title, 143 143 'device' => true, 144 144 )); 145 + } 146 + 147 + private function getPanelRedirectURI(PhabricatorDashboardPanel $panel) { 148 + $request = $this->getRequest(); 149 + $dashboard_id = $request->getInt('dashboardID'); 150 + if ($dashboard_id) { 151 + $uri = $this->getApplicationURI('arrange/'.$dashboard_id.'/'); 152 + } else { 153 + $uri = '/'.$panel->getMonogram(); 154 + } 155 + 156 + return $uri; 145 157 } 146 158 147 159 }
+2 -1
src/applications/dashboard/controller/PhabricatorDashboardPanelRenderController.php
··· 37 37 ->setViewer($viewer) 38 38 ->setPanel($panel) 39 39 ->setParentPanelPHIDs($parent_phids) 40 - ->setHeaderless($request->getBool('headerless')) 40 + ->setHeaderMode($request->getStr('headerMode')) 41 + ->setDashboardID($request->getInt('dashboardID')) 41 42 ->renderPanel(); 42 43 43 44 if ($request->isAjax()) {
+82
src/applications/dashboard/controller/PhabricatorDashboardRemovePanelController.php
··· 1 + <?php 2 + 3 + final class PhabricatorDashboardRemovePanelController 4 + extends PhabricatorDashboardController { 5 + 6 + private $id; 7 + 8 + public function willProcessRequest(array $data) { 9 + $this->id = idx($data, 'id'); 10 + } 11 + 12 + public function processRequest() { 13 + $request = $this->getRequest(); 14 + $viewer = $request->getUser(); 15 + 16 + $dashboard = id(new PhabricatorDashboardQuery()) 17 + ->setViewer($viewer) 18 + ->withIDs(array($this->id)) 19 + ->requireCapabilities( 20 + array( 21 + PhabricatorPolicyCapability::CAN_VIEW, 22 + PhabricatorPolicyCapability::CAN_EDIT, 23 + )) 24 + ->executeOne(); 25 + if (!$dashboard) { 26 + return new Aphront404Response(); 27 + } 28 + 29 + $v_panel = $request->getStr('panelPHID'); 30 + $panel = id(new PhabricatorDashboardPanelQuery()) 31 + ->setViewer($viewer) 32 + ->withPHIDs(array($v_panel)) 33 + ->executeOne(); 34 + if (!$panel) { 35 + return new Aphront404Response(); 36 + } 37 + 38 + $redirect_uri = $this->getApplicationURI( 39 + 'arrange/'.$dashboard->getID().'/'); 40 + $layout_config = $dashboard->getLayoutConfigObject(); 41 + 42 + if ($request->isFormPost()) { 43 + $xactions = array(); 44 + $xactions[] = id(new PhabricatorDashboardTransaction()) 45 + ->setTransactionType(PhabricatorTransactions::TYPE_EDGE) 46 + ->setMetadataValue( 47 + 'edge:type', 48 + PhabricatorEdgeConfig::TYPE_DASHBOARD_HAS_PANEL) 49 + ->setNewValue( 50 + array( 51 + '-' => array( 52 + $panel->getPHID() => $panel->getPHID(), 53 + ), 54 + )); 55 + 56 + $layout_config->removePanel($panel->getPHID()); 57 + $dashboard->setLayoutConfigFromObject($layout_config); 58 + 59 + $editor = id(new PhabricatorDashboardTransactionEditor()) 60 + ->setActor($viewer) 61 + ->setContentSourceFromRequest($request) 62 + ->setContinueOnMissingFields(true) 63 + ->setContinueOnNoEffect(true) 64 + ->applyTransactions($dashboard, $xactions); 65 + 66 + return id(new AphrontRedirectResponse())->setURI($redirect_uri); 67 + } 68 + 69 + $form = id(new AphrontFormView()) 70 + ->setUser($viewer) 71 + ->addHiddenInput('confirm', true) 72 + ->addHiddenInput('panelPHID', $v_panel) 73 + ->appendChild(pht('Are you sure you want to remove this panel?')); 74 + 75 + return $this->newDialog() 76 + ->setTitle(pht('Remove Panel %s', $panel->getMonogram())) 77 + ->appendChild($form->buildLayoutView()) 78 + ->addCancelButton($redirect_uri) 79 + ->addSubmitButton(pht('Remove Panel')); 80 + } 81 + 82 + }
+157 -36
src/applications/dashboard/engine/PhabricatorDashboardPanelRenderingEngine.php
··· 2 2 3 3 final class PhabricatorDashboardPanelRenderingEngine extends Phobject { 4 4 5 + const HEADER_MODE_NORMAL = 'normal'; 6 + const HEADER_MODE_NONE = 'none'; 7 + const HEADER_MODE_EDIT = 'edit'; 8 + 5 9 private $panel; 6 10 private $viewer; 7 11 private $enableAsyncRendering; 8 12 private $parentPanelPHIDs; 9 - private $headerless; 13 + private $headerMode = self::HEADER_MODE_NORMAL; 14 + private $dashboardID; 15 + 16 + public function setDashboardID($id) { 17 + $this->dashboardID = $id; 18 + return $this; 19 + } 20 + 21 + public function getDashboardID() { 22 + return $this->dashboardID; 23 + } 10 24 11 - public function setHeaderless($headerless) { 12 - $this->headerless = $headerless; 25 + public function setHeaderMode($header_mode) { 26 + $this->headerMode = $header_mode; 13 27 return $this; 14 28 } 15 29 16 - public function getHeaderless() { 17 - return $this->headerless; 30 + public function getHeaderMode() { 31 + return $this->headerMode; 18 32 } 19 33 20 34 /** ··· 39 53 return $this; 40 54 } 41 55 56 + public function getViewer() { 57 + return $this->viewer; 58 + } 59 + 42 60 public function setPanel(PhabricatorDashboardPanel $panel) { 43 61 $this->panel = $panel; 44 62 return $this; 45 63 } 46 64 65 + public function getPanel() { 66 + return $this->panel; 67 + } 68 + 47 69 public function renderPanel() { 48 - $panel = $this->panel; 49 - $viewer = $this->viewer; 70 + $panel = $this->getPanel(); 71 + $viewer = $this->getViewer(); 50 72 51 73 if (!$panel) { 52 74 return $this->renderErrorPanel( ··· 69 91 70 92 if ($this->enableAsyncRendering) { 71 93 if ($panel_type->shouldRenderAsync()) { 72 - return $this->renderAsyncPanel($panel); 94 + return $this->renderAsyncPanel(); 73 95 } 74 96 } 75 97 76 - return $panel_type->renderPanel($viewer, $panel, $this); 98 + return $this->renderNormalPanel($viewer, $panel, $this); 77 99 } catch (Exception $ex) { 78 100 return $this->renderErrorPanel( 79 101 $panel->getName(), ··· 84 106 } 85 107 } 86 108 87 - private function renderErrorPanel($title, $body) { 88 - if ($this->getHeaderless()) { 89 - return id(new AphrontErrorView()) 90 - ->setErrors(array($body)); 91 - } else { 92 - return id(new PHUIObjectBoxView()) 93 - ->setHeaderText($title) 94 - ->setFormErrors(array($body)); 95 - } 109 + private function renderNormalPanel() { 110 + $panel = $this->getPanel(); 111 + $panel_type = $panel->getImplementation(); 112 + 113 + $content = $panel_type->renderPanelContent( 114 + $this->getViewer(), 115 + $panel, 116 + $this); 117 + $header = $this->renderPanelHeader(); 118 + 119 + return $this->renderPanelDiv( 120 + $content, 121 + $header); 96 122 } 97 123 98 - private function renderAsyncPanel(PhabricatorDashboardPanel $panel) { 124 + 125 + private function renderAsyncPanel() { 126 + $panel = $this->getPanel(); 127 + 99 128 $panel_id = celerity_generate_unique_node_id(); 129 + $dashboard_id = $this->getDashboardID(); 100 130 101 131 Javelin::initBehavior( 102 132 'dashboard-async-panel', 103 133 array( 104 134 'panelID' => $panel_id, 105 135 'parentPanelPHIDs' => $this->getParentPanelPHIDs(), 106 - 'headerless' => $this->getHeaderless(), 136 + 'headerMode' => $this->getHeaderMode(), 137 + 'dashboardID' => $dashboard_id, 107 138 'uri' => '/dashboard/panel/render/'.$panel->getID().'/', 108 139 )); 109 140 110 - $content = pht('Loading...'); 141 + $header = $this->renderPanelHeader(); 142 + $content = id(new PHUIPropertyListView()) 143 + ->addTextContent(pht('Loading...')); 144 + 145 + return $this->renderPanelDiv( 146 + $content, 147 + $header, 148 + $panel_id); 149 + } 150 + 151 + private function renderErrorPanel($title, $body) { 152 + switch ($this->getHeaderMode()) { 153 + case self::HEADER_MODE_NONE: 154 + $header = null; 155 + break; 156 + case self::HEADER_MODE_EDIT: 157 + $header = id(new PhabricatorActionHeaderView()) 158 + ->setHeaderTitle($title) 159 + ->setHeaderColor(PhabricatorActionHeaderView::HEADER_RED); 160 + $header = $this->addPanelHeaderActions($header); 161 + break; 162 + case self::HEADER_MODE_NORMAL: 163 + default: 164 + $header = id(new PhabricatorActionHeaderView()) 165 + ->setHeaderTitle($title) 166 + ->setHeaderColor(PhabricatorActionHeaderView::HEADER_RED); 167 + break; 168 + } 169 + return $this->renderPanelDiv( 170 + id(new AphrontErrorView()) 171 + ->appendChild($body), 172 + $header); 173 + } 111 174 112 - if ($this->headerless) { 113 - return phutil_tag( 114 - 'div', 115 - array( 116 - 'id' => $panel_id, 117 - ), 118 - $content); 119 - } else { 120 - return id(new PHUIObjectBoxView()) 121 - ->addSigil('dashboard-panel') 122 - ->setMetadata(array( 123 - 'objectPHID' => $panel->getPHID())) 124 - ->setHeaderText($panel->getName()) 125 - ->setID($panel_id) 126 - ->appendChild($content); 175 + private function renderPanelDiv( 176 + $content, 177 + $header = null, 178 + $id = null) { 179 + 180 + $panel = $this->getPanel(); 181 + if (!$id) { 182 + $id = celerity_generate_unique_node_id(); 127 183 } 184 + return javelin_tag( 185 + 'div', 186 + array( 187 + 'id' => $id, 188 + 'sigil' => 'dashboard-panel', 189 + 'meta' => array( 190 + 'objectPHID' => $panel->getPHID()), 191 + 'class' => 'dashboard-panel'), 192 + array( 193 + $header, 194 + $content)); 195 + } 196 + 197 + 198 + private function renderPanelHeader() { 199 + 200 + $panel = $this->getPanel(); 201 + switch ($this->getHeaderMode()) { 202 + case self::HEADER_MODE_NONE: 203 + $header = null; 204 + break; 205 + case self::HEADER_MODE_EDIT: 206 + $header = id(new PhabricatorActionHeaderView()) 207 + ->setHeaderTitle($panel->getName()) 208 + ->setHeaderColor(PhabricatorActionHeaderView::HEADER_GREY); 209 + $header = $this->addPanelHeaderActions($header); 210 + break; 211 + case self::HEADER_MODE_NORMAL: 212 + default: 213 + $header = id(new PhabricatorActionHeaderView()) 214 + ->setHeaderTitle($panel->getName()) 215 + ->setHeaderColor(PhabricatorActionHeaderView::HEADER_GREY); 216 + break; 217 + } 218 + return $header; 219 + } 220 + 221 + private function addPanelHeaderActions( 222 + PhabricatorActionHeaderView $header) { 223 + $panel = $this->getPanel(); 224 + 225 + $dashboard_id = $this->getDashboardID(); 226 + $edit_uri = id(new PhutilURI( 227 + '/dashboard/panel/edit/'.$panel->getID().'/')); 228 + if ($dashboard_id) { 229 + $edit_uri->setQueryParam('dashboardID', $dashboard_id); 230 + } 231 + $action_edit = id(new PHUIIconView()) 232 + ->setSpriteSheet(PHUIIconView::SPRITE_ACTIONS) 233 + ->setSpriteIcon('settings-grey') 234 + ->setHref((string) $edit_uri); 235 + $header->addAction($action_edit); 236 + 237 + if ($dashboard_id) { 238 + $uri = id(new PhutilURI( 239 + '/dashboard/removepanel/'.$dashboard_id.'/')) 240 + ->setQueryParam('panelPHID', $panel->getPHID()); 241 + $action_remove = id(new PHUIIconView()) 242 + ->setSpriteSheet(PHUIIconView::SPRITE_ACTIONS) 243 + ->setSpriteIcon('close-grey') 244 + ->setHref((string) $uri) 245 + ->setWorkflow(true); 246 + $header->addAction($action_remove); 247 + } 248 + return $header; 128 249 } 129 250 130 251 /**
+7
src/applications/dashboard/engine/PhabricatorDashboardRenderingEngine.php
··· 34 34 ->setID($dashboard_id) 35 35 ->setFluidlayout(true); 36 36 37 + if ($this->arrangeMode) { 38 + $h_mode = PhabricatorDashboardPanelRenderingEngine::HEADER_MODE_EDIT; 39 + } else { 40 + $h_mode = PhabricatorDashboardPanelRenderingEngine::HEADER_MODE_NORMAL; 41 + } 37 42 foreach ($panel_grid_locations as $column => $panel_column_locations) { 38 43 $panel_phids = $panel_column_locations; 39 44 $column_panels = array_select_keys($panels, $panel_phids); ··· 42 47 $column_result[] = id(new PhabricatorDashboardPanelRenderingEngine()) 43 48 ->setViewer($viewer) 44 49 ->setPanel($panel) 50 + ->setDashboardID($dashboard->getID()) 45 51 ->setEnableAsyncRendering(true) 46 52 ->setParentPanelPHIDs(array()) 53 + ->setHeaderMode($h_mode) 47 54 ->renderPanel(); 48 55 } 49 56 $column_class = $layout_config->getColumnClass(
+18
src/applications/dashboard/layoutconfig/PhabricatorDashboardLayoutConfig.php
··· 32 32 return $this->panelLocations; 33 33 } 34 34 35 + public function removePanel($panel_phid) { 36 + $panel_location_grid = $this->getPanelLocations(); 37 + foreach ($panel_location_grid as $column => $panel_columns) { 38 + $found_old_column = array_search($panel_phid, $panel_columns); 39 + if ($found_old_column !== false) { 40 + $new_panel_columns = $panel_columns; 41 + array_splice( 42 + $new_panel_columns, 43 + $found_old_column, 44 + 1, 45 + array()); 46 + $panel_location_grid[$column] = $new_panel_columns; 47 + break; 48 + } 49 + } 50 + $this->setPanelLocations($panel_location_grid); 51 + } 52 + 35 53 public function getDefaultPanelLocations() { 36 54 switch ($this->getLayoutMode()) { 37 55 case self::MODE_HALF_AND_HALF:
+1 -18
src/applications/dashboard/paneltype/PhabricatorDashboardPanelType.php
··· 40 40 return $types; 41 41 } 42 42 43 - public function renderPanel( 44 - PhabricatorUser $viewer, 45 - PhabricatorDashboardPanel $panel, 46 - PhabricatorDashboardPanelRenderingEngine $engine) { 47 43 48 - $content = $this->renderPanelContent($viewer, $panel, $engine); 49 44 50 - if ($engine->getHeaderless()) { 51 - return $content; 52 - } 53 - 54 - return id(new PHUIObjectBoxView()) 55 - ->addSigil('dashboard-panel') 56 - ->setMetadata(array( 57 - 'objectPHID' => $panel->getPHID())) 58 - ->setHeaderText($panel->getName()) 59 - ->appendChild($content); 60 - } 61 - 62 - protected function renderPanelContent( 45 + public function renderPanelContent( 63 46 PhabricatorUser $viewer, 64 47 PhabricatorDashboardPanel $panel, 65 48 PhabricatorDashboardPanelRenderingEngine $engine) {
+1 -1
src/applications/dashboard/paneltype/PhabricatorDashboardPanelTypeQuery.php
··· 30 30 ); 31 31 } 32 32 33 - protected function renderPanelContent( 33 + public function renderPanelContent( 34 34 PhabricatorUser $viewer, 35 35 PhabricatorDashboardPanel $panel, 36 36 PhabricatorDashboardPanelRenderingEngine $engine) {
+3 -2
src/applications/dashboard/paneltype/PhabricatorDashboardPanelTypeTabs.php
··· 25 25 ); 26 26 } 27 27 28 - protected function renderPanelContent( 28 + public function renderPanelContent( 29 29 PhabricatorUser $viewer, 30 30 PhabricatorDashboardPanel $panel, 31 31 PhabricatorDashboardPanelRenderingEngine $engine) { ··· 81 81 $parent_phids[] = $panel->getPHID(); 82 82 83 83 $content = array(); 84 + $no_headers = PhabricatorDashboardPanelRenderingEngine::HEADER_MODE_NONE; 84 85 foreach ($config as $idx => $tab_spec) { 85 86 $panel_id = idx($tab_spec, 'panelID'); 86 87 $panel = idx($panels, $panel_id); ··· 91 92 ->setEnableAsyncRendering(true) 92 93 ->setParentPanelPHIDs($parent_phids) 93 94 ->setPanel($panel) 94 - ->setHeaderless(true) 95 + ->setHeaderMode($no_headers) 95 96 ->renderPanel(); 96 97 } else { 97 98 $panel_content = pht('(Invalid Panel)');
+1 -1
src/applications/dashboard/paneltype/PhabricatorDashboardPanelTypeText.php
··· 26 26 ); 27 27 } 28 28 29 - protected function renderPanelContent( 29 + public function renderPanelContent( 30 30 PhabricatorUser $viewer, 31 31 PhabricatorDashboardPanel $panel, 32 32 PhabricatorDashboardPanelRenderingEngine $engine) {
+13 -1
webroot/rsrc/css/application/dashboard/dashboard.css
··· 18 18 } 19 19 20 20 .aphront-multi-column-fluid 21 + .aphront-multi-column-column-outer 22 + .aphront-multi-column-column .dashboard-panel { 23 + margin: 16px 16px 0px 16px; 24 + } 25 + 26 + .aphront-multi-column-fluid 21 27 .aphront-multi-column-column-outer.grippable 22 - .aphront-multi-column-column .phui-object-box { 28 + .aphront-multi-column-column .dashboard-panel { 23 29 cursor: move; 24 30 } 25 31 ··· 57 63 .dashboard-panel-placeholder { 58 64 display: none; 59 65 } 66 + 67 + .aphront-multi-column-fluid 68 + .aphront-multi-column-column-outer 69 + .aphront-multi-column-column .aphront-error-view { 70 + margin: 0; 71 + }
+2 -1
webroot/rsrc/js/application/dashboard/behavior-dashboard-async-panel.js
··· 11 11 12 12 var data = { 13 13 parentPanelPHIDs: config.parentPanelPHIDs.join(','), 14 - headerless: config.headerless ? 1 : 0 14 + headerMode: config.headerMode, 15 + dashboardID: config.dashboardID 15 16 }; 16 17 17 18 new JX.Workflow(config.uri)