@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.

Add a "tabs" dashboard panel type

Summary:
Ref T4986. Allows you to create a dashboard panel out of dashboard panels.

bwahaha

Test Plan:
{F155472}

{F155473}

Reviewers: chad, btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T4986

Differential Revision: https://secure.phabricator.com/D9141

+129 -7
+2
src/__phutil_library_map__.php
··· 1481 1481 'PhabricatorDashboardPanelTransactionQuery' => 'applications/dashboard/query/PhabricatorDashboardPanelTransactionQuery.php', 1482 1482 'PhabricatorDashboardPanelType' => 'applications/dashboard/paneltype/PhabricatorDashboardPanelType.php', 1483 1483 'PhabricatorDashboardPanelTypeQuery' => 'applications/dashboard/paneltype/PhabricatorDashboardPanelTypeQuery.php', 1484 + 'PhabricatorDashboardPanelTypeTabs' => 'applications/dashboard/paneltype/PhabricatorDashboardPanelTypeTabs.php', 1484 1485 'PhabricatorDashboardPanelTypeText' => 'applications/dashboard/paneltype/PhabricatorDashboardPanelTypeText.php', 1485 1486 'PhabricatorDashboardPanelViewController' => 'applications/dashboard/controller/PhabricatorDashboardPanelViewController.php', 1486 1487 'PhabricatorDashboardQuery' => 'applications/dashboard/query/PhabricatorDashboardQuery.php', ··· 4268 4269 'PhabricatorDashboardPanelTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 4269 4270 'PhabricatorDashboardPanelType' => 'Phobject', 4270 4271 'PhabricatorDashboardPanelTypeQuery' => 'PhabricatorDashboardPanelType', 4272 + 'PhabricatorDashboardPanelTypeTabs' => 'PhabricatorDashboardPanelType', 4271 4273 'PhabricatorDashboardPanelTypeText' => 'PhabricatorDashboardPanelType', 4272 4274 'PhabricatorDashboardPanelViewController' => 'PhabricatorDashboardController', 4273 4275 'PhabricatorDashboardQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
+6 -2
src/applications/dashboard/engine/PhabricatorDashboardPanelRenderingEngine.php
··· 20 20 return $this; 21 21 } 22 22 23 + public function getParentPanelPHIDs() { 24 + return $this->parentPanelPHIDs; 25 + } 26 + 23 27 public function setViewer(PhabricatorUser $viewer) { 24 28 $this->viewer = $viewer; 25 29 return $this; ··· 59 63 } 60 64 } 61 65 62 - return $panel_type->renderPanel($viewer, $panel); 66 + return $panel_type->renderPanel($viewer, $panel, $this); 63 67 } catch (Exception $ex) { 64 68 return $this->renderErrorPanel( 65 69 $panel->getName(), ··· 83 87 'dashboard-async-panel', 84 88 array( 85 89 'panelID' => $panel_id, 86 - 'parentPanelPHIDs' => $this->parentPanelPHIDs, 90 + 'parentPanelPHIDs' => $this->getParentPanelPHIDs(), 87 91 'uri' => '/dashboard/panel/render/'.$panel->getID().'/', 88 92 )); 89 93
+5 -3
src/applications/dashboard/paneltype/PhabricatorDashboardPanelType.php
··· 42 42 43 43 public function renderPanel( 44 44 PhabricatorUser $viewer, 45 - PhabricatorDashboardPanel $panel) { 45 + PhabricatorDashboardPanel $panel, 46 + PhabricatorDashboardPanelRenderingEngine $engine) { 46 47 47 - $content = $this->renderPanelContent($viewer, $panel); 48 + $content = $this->renderPanelContent($viewer, $panel, $engine); 48 49 49 50 return id(new PHUIObjectBoxView()) 50 51 ->addSigil('dashboard-panel') ··· 56 57 57 58 protected function renderPanelContent( 58 59 PhabricatorUser $viewer, 59 - PhabricatorDashboardPanel $panel) { 60 + PhabricatorDashboardPanel $panel, 61 + PhabricatorDashboardPanelRenderingEngine $engine) { 60 62 return pht('TODO: Panel content goes here.'); 61 63 } 62 64
+2 -1
src/applications/dashboard/paneltype/PhabricatorDashboardPanelTypeQuery.php
··· 32 32 33 33 protected function renderPanelContent( 34 34 PhabricatorUser $viewer, 35 - PhabricatorDashboardPanel $panel) { 35 + PhabricatorDashboardPanel $panel, 36 + PhabricatorDashboardPanelRenderingEngine $engine) { 36 37 37 38 $class = $panel->getProperty('class'); 38 39
+112
src/applications/dashboard/paneltype/PhabricatorDashboardPanelTypeTabs.php
··· 1 + <?php 2 + 3 + final class PhabricatorDashboardPanelTypeTabs 4 + extends PhabricatorDashboardPanelType { 5 + 6 + public function getPanelTypeKey() { 7 + return 'tabs'; 8 + } 9 + 10 + public function getPanelTypeName() { 11 + return pht('Tab Panel'); 12 + } 13 + 14 + public function getPanelTypeDescription() { 15 + return pht( 16 + 'Use tabs to switch between several other panels.'); 17 + } 18 + 19 + public function getFieldSpecifications() { 20 + return array( 21 + 'config' => array( 22 + 'name' => pht('JSON Config'), 23 + 'type' => 'remarkup', 24 + ), 25 + ); 26 + } 27 + 28 + protected function renderPanelContent( 29 + PhabricatorUser $viewer, 30 + PhabricatorDashboardPanel $panel, 31 + PhabricatorDashboardPanelRenderingEngine $engine) { 32 + 33 + $config = phutil_json_decode($panel->getProperty('config'), null); 34 + if ($config === null) { 35 + throw new Exception(pht('The configuration is not valid JSON.')); 36 + } 37 + 38 + $list = id(new PHUIListView()) 39 + ->setType(PHUIListView::NAVBAR_LIST); 40 + 41 + $selected = 0; 42 + 43 + // TODO: Instead of using reveal-content here, we should write some nice 44 + // JS which loads panels on demand, manages tab selected states, and maybe 45 + // saves the tab you selected. 46 + 47 + $node_ids = array(); 48 + foreach ($config as $idx => $tab_spec) { 49 + $node_ids[$idx] = celerity_generate_unique_node_id(); 50 + } 51 + 52 + Javelin::initBehavior('phabricator-reveal-content'); 53 + 54 + foreach ($config as $idx => $tab_spec) { 55 + $hide_ids = $node_ids; 56 + unset($hide_ids[$idx]); 57 + 58 + $list->addMenuItem( 59 + id(new PHUIListItemView()) 60 + ->setHref('#') 61 + ->addSigil('reveal-content') 62 + ->setMetadata( 63 + array( 64 + 'showIDs' => array(idx($node_ids, $idx)), 65 + 'hideIDs' => array_values($hide_ids), 66 + )) 67 + ->setName(idx($tab_spec, 'name', pht('Nameless Tab')))); 68 + } 69 + 70 + $ids = ipull($config, 'panelID'); 71 + if ($ids) { 72 + $panels = id(new PhabricatorDashboardPanelQuery()) 73 + ->setViewer($viewer) 74 + ->withIDs($ids) 75 + ->execute(); 76 + } else { 77 + $panels = array(); 78 + } 79 + 80 + $parent_phids = $engine->getParentPanelPHIDs(); 81 + $parent_phids[] = $panel->getPHID(); 82 + 83 + $content = array(); 84 + foreach ($config as $idx => $tab_spec) { 85 + $panel_id = idx($tab_spec, 'panelID'); 86 + $panel = idx($panels, $panel_id); 87 + 88 + if ($panel) { 89 + $panel_content = id(new PhabricatorDashboardPanelRenderingEngine()) 90 + ->setViewer($viewer) 91 + ->setEnableAsyncRendering(true) 92 + ->setParentPanelPHIDs($parent_phids) 93 + ->setPanel($panel) 94 + ->renderPanel(); 95 + } else { 96 + $panel_content = 'nope'; 97 + } 98 + 99 + $content[] = phutil_tag( 100 + 'div', 101 + array( 102 + 'id' => $node_ids[$idx], 103 + 'style' => ($idx == $selected) ? null : 'display: none', 104 + ), 105 + $panel_content); 106 + } 107 + 108 + 109 + return array($list, $content); 110 + } 111 + 112 + }
+2 -1
src/applications/dashboard/paneltype/PhabricatorDashboardPanelTypeText.php
··· 28 28 29 29 protected function renderPanelContent( 30 30 PhabricatorUser $viewer, 31 - PhabricatorDashboardPanel $panel) { 31 + PhabricatorDashboardPanel $panel, 32 + PhabricatorDashboardPanelRenderingEngine $engine) { 32 33 33 34 $text = $panel->getProperty('text', ''); 34 35