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

Wire up object box tabs

Summary: Make tabs do stuff when you click 'em.

Test Plan:
- Clicked object box tabs in UIExample.
- Viewed some existing non-tab UIs (Differential, Maniphest).
- Viewed some existing non-tab, multiple-list UIs (Diffusion).
- Grepped for methods I changed.

Reviewers: chad, btrahan

Reviewed By: chad

CC: aran

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

+153 -27
+12
src/__celerity_resource_map__.php
··· 2318 2318 ), 2319 2319 'disk' => '/rsrc/js/application/pholio/behavior-pholio-mock-view.js', 2320 2320 ), 2321 + 'javelin-behavior-phui-object-box-tabs' => 2322 + array( 2323 + 'uri' => '/res/c2318be8/rsrc/js/phui/behavior-phui-object-box-tabs.js', 2324 + 'type' => 'js', 2325 + 'requires' => 2326 + array( 2327 + 0 => 'javelin-behavior', 2328 + 1 => 'javelin-stratcom', 2329 + 2 => 'javelin-dom', 2330 + ), 2331 + 'disk' => '/rsrc/js/phui/behavior-phui-object-box-tabs.js', 2332 + ), 2321 2333 'javelin-behavior-policy-control' => 2322 2334 array( 2323 2335 'uri' => '/res/ce9f54c8/rsrc/js/application/policy/behavior-policy-control.js',
+5 -9
src/applications/uiexample/examples/PHUIPropertyListExample.php
··· 17 17 18 18 $details1 = id(new PHUIListItemView()) 19 19 ->setName('Details') 20 - ->setHref('#') 21 20 ->setSelected(true) 22 21 ->setType(PHUIListItemView::TYPE_LINK); 23 22 24 23 $details2 = id(new PHUIListItemView()) 25 - ->setName('Lint (Warn)') 26 - ->setHref('#') 24 + ->setName('Rainbow Info') 27 25 ->setStatusColor(PHUIListItemView::STATUS_WARN) 28 26 ->setType(PHUIListItemView::TYPE_LINK); 29 27 30 28 $details3 = id(new PHUIListItemView()) 31 - ->setName('Unit (3/5)') 32 - ->setHref('#') 29 + ->setName('Pasta Haiku') 33 30 ->setStatusColor(PHUIListItemView::STATUS_FAIL) 34 31 ->setType(PHUIListItemView::TYPE_LINK); 35 32 ··· 40 37 ->addMenuItem($details3); 41 38 42 39 $view = new PHUIPropertyListView(); 43 - $view->setTabs($statustabs); 44 40 45 41 $view->addProperty( 46 42 pht('Color'), ··· 84 80 85 81 $object_box1 = id(new PHUIObjectBoxView()) 86 82 ->setHeaderText('PHUIPropertyListView Stackered') 87 - ->addPropertyList($view) 88 - ->addPropertyList($view2) 89 - ->addPropertyList($view3); 83 + ->addPropertyList($view, $details1) 84 + ->addPropertyList($view2, $details2) 85 + ->addPropertyList($view3, $details3); 90 86 91 87 $edge_cases_view = new PHUIPropertyListView(); 92 88
+100 -11
src/view/phui/PHUIObjectBoxView.php
··· 8 8 private $validationException; 9 9 private $header; 10 10 private $flush; 11 - private $propertyList = array(); 12 11 13 - // This is mostly a conveinence method to lessen code dupe 14 - // when building objectboxes. 15 - public function addPropertyList(PHUIPropertyListView $property_list) { 16 - $this->propertyList[] = $property_list; 12 + private $tabs = array(); 13 + private $propertyLists = array(); 14 + private $selectedTab; 15 + 16 + public function addPropertyList( 17 + PHUIPropertyListView $property_list, 18 + PHUIListItemView $tab = null) { 19 + 20 + if ($this->propertyLists) { 21 + $already_has_tabs = (bool)$this->tabs; 22 + $adding_new_tab = (bool)$tab; 23 + 24 + if ($already_has_tabs xor $adding_new_tab) { 25 + throw new Exception( 26 + "You can not mix tabbed and un-tabbed property lists in the same ". 27 + "BoxView."); 28 + } 29 + } 30 + 31 + if ($tab) { 32 + if ($tab->getKey()) { 33 + $key = $tab->getKey(); 34 + } else { 35 + $key = 'tab.default.'.spl_object_hash($tab); 36 + $tab->setKey($key); 37 + } 38 + } else { 39 + $key = 'tab.default'; 40 + } 41 + 42 + if ($tab) { 43 + if (!$this->tabs) { 44 + $this->selectedTab = $key; 45 + } 46 + 47 + if (empty($this->tabs[$key])) { 48 + $tab->addSigil('phui-object-box-tab'); 49 + $tab->setMetadata( 50 + array( 51 + 'tabKey' => $key, 52 + )); 53 + 54 + if (!$tab->getHref()) { 55 + $tab->setHref('#'); 56 + } 57 + 58 + $this->tabs[$key] = $tab; 59 + } 60 + } 61 + 62 + $this->propertyLists[$key][] = $property_list; 63 + 17 64 return $this; 18 65 } 19 66 ··· 74 121 } 75 122 } 76 123 77 - $property_list = null; 78 - if ($this->propertyList) { 79 - $property_list = new PHUIPropertyGroupView(); 80 - foreach ($this->propertyList as $item) { 81 - $property_list->addPropertyList($item); 124 + $property_lists = array(); 125 + $tab_map = array(); 126 + foreach ($this->propertyLists as $key => $list) { 127 + $group = new PHUIPropertyGroupView(); 128 + foreach ($list as $item) { 129 + $group->addPropertyList($item); 130 + } 131 + 132 + if ($this->tabs) { 133 + $tab_id = celerity_generate_unique_node_id(); 134 + $tab_map[$key] = $tab_id; 135 + 136 + if ($key === $this->selectedTab) { 137 + $style = null; 138 + } else { 139 + $style = 'display: none'; 140 + } 141 + 142 + $property_lists[] = phutil_tag( 143 + 'div', 144 + array( 145 + 'style' => $style, 146 + 'id' => $tab_id, 147 + ), 148 + $group); 149 + } else { 150 + $property_lists[] = $group; 82 151 } 83 152 } 84 153 154 + $tabs = null; 155 + if ($this->tabs) { 156 + $tabs = id(new PHUIListView()) 157 + ->setType(PHUIListView::NAVBAR_LIST); 158 + foreach ($this->tabs as $tab) { 159 + $tabs->addMenuItem($tab); 160 + } 161 + 162 + Javelin::initBehavior('phui-object-box-tabs'); 163 + } 164 + 85 165 $content = id(new PHUIBoxView()) 86 166 ->appendChild( 87 167 array( ··· 89 169 $this->formError, 90 170 $exception_errors, 91 171 $this->form, 92 - $property_list, 172 + $tabs, 173 + $property_lists, 93 174 $this->renderChildren(), 94 175 )) 95 176 ->setBorder(true) ··· 97 178 ->addMargin(PHUI::MARGIN_LARGE_LEFT) 98 179 ->addMargin(PHUI::MARGIN_LARGE_RIGHT) 99 180 ->addClass('phui-object-box'); 181 + 182 + if ($this->tabs) { 183 + $content->addSigil('phui-object-box'); 184 + $content->setMetadata( 185 + array( 186 + 'tabMap' => $tab_map, 187 + )); 188 + } 100 189 101 190 if ($this->flush) { 102 191 $content->addClass('phui-object-box-flush');
-7
src/view/phui/PHUIPropertyListView.php
··· 7 7 private $object; 8 8 private $invokedWillRenderEvent; 9 9 private $actionList; 10 - private $tabs; 11 10 12 11 protected function canAppendChild() { 13 12 return false; ··· 48 47 49 48 $this->parts[] = $current; 50 49 return $this; 51 - } 52 - 53 - public function setTabs(PHUIListView $tabs) { 54 - $this->tabs = $tabs; 55 - return $tabs; 56 50 } 57 51 58 52 public function addSectionHeader($name) { ··· 123 117 'class' => 'phui-property-list-section', 124 118 ), 125 119 array( 126 - $this->tabs, 127 120 $items, 128 121 )); 129 122 }
+36
webroot/rsrc/js/phui/behavior-phui-object-box-tabs.js
··· 1 + /** 2 + * @provides javelin-behavior-phui-object-box-tabs 3 + * @requires javelin-behavior 4 + * javelin-stratcom 5 + * javelin-dom 6 + */ 7 + 8 + JX.behavior('phui-object-box-tabs', function() { 9 + 10 + JX.Stratcom.listen( 11 + 'click', 12 + 'phui-object-box-tab', 13 + function (e) { 14 + var key = e.getNodeData('phui-object-box-tab').tabKey; 15 + var map = e.getNodeData('phui-object-box').tabMap; 16 + var tab = e.getNode('phui-object-box-tab'); 17 + 18 + var box = e.getNode('phui-object-box'); 19 + var tabs = JX.DOM.scry(box, 'li', 'phui-object-box-tab'); 20 + for (var ii = 0; ii < tabs.length; ii++) { 21 + JX.DOM.alterClass( 22 + tabs[ii], 23 + 'phui-list-item-selected', 24 + (tabs[ii] == tab)); 25 + } 26 + 27 + for (var k in map) { 28 + if (k == key) { 29 + JX.DOM.show(JX.$(map[k])); 30 + } else { 31 + JX.DOM.hide(JX.$(map[k])); 32 + } 33 + } 34 + }); 35 + 36 + });