Skip to content

Commit 189910d

Browse files
author
epriestley
committedJul 1, 2016
Make TabGroups a standalone UI element
Summary: Ref T10628. Currently, tabs are part of ObjectBoxes. However, the code is a bit of a mess and I want to use them in some other contexts, notably the "prose diff" dialog to show "old raw, new raw, diff". Pull them out, and update Files to use the new stuff. My plan is: - Update all callsites to this stuff. - Remove the builtin-in ObjectBox integration to simplify ObjectBox a bit. - Move forward with T10628. This is pretty straightforward. A couple of the sigils are a little weird, but I'll update the JS later. For now, the same JS can drive both old and new tabs. Test Plan: Viewed files, everything was unchanged. Reviewers: chad Reviewed By: chad Maniphest Tasks: T10628 Differential Revision: https://secure.phabricator.com/D16205
1 parent 01862b8 commit 189910d

File tree

5 files changed

+202
-7
lines changed

5 files changed

+202
-7
lines changed
 

‎src/__phutil_library_map__.php

+4
Original file line numberDiff line numberDiff line change
@@ -1663,6 +1663,8 @@
16631663
'PHUISpacesNamespaceContextView' => 'applications/spaces/view/PHUISpacesNamespaceContextView.php',
16641664
'PHUIStatusItemView' => 'view/phui/PHUIStatusItemView.php',
16651665
'PHUIStatusListView' => 'view/phui/PHUIStatusListView.php',
1666+
'PHUITabGroupView' => 'view/phui/PHUITabGroupView.php',
1667+
'PHUITabView' => 'view/phui/PHUITabView.php',
16661668
'PHUITagExample' => 'applications/uiexample/examples/PHUITagExample.php',
16671669
'PHUITagView' => 'view/phui/PHUITagView.php',
16681670
'PHUITimelineEventView' => 'view/phui/PHUITimelineEventView.php',
@@ -6194,6 +6196,8 @@
61946196
'PHUISpacesNamespaceContextView' => 'AphrontView',
61956197
'PHUIStatusItemView' => 'AphrontTagView',
61966198
'PHUIStatusListView' => 'AphrontTagView',
6199+
'PHUITabGroupView' => 'AphrontTagView',
6200+
'PHUITabView' => 'AphrontTagView',
61976201
'PHUITagExample' => 'PhabricatorUIExample',
61986202
'PHUITagView' => 'AphrontTagView',
61996203
'PHUITimelineEventView' => 'AphrontView',

‎src/applications/files/controller/PhabricatorFileInfoController.php

+33-6
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,16 @@ private function buildPropertyViews(
182182
$request = $this->getRequest();
183183
$viewer = $request->getUser();
184184

185+
$tab_group = id(new PHUITabGroupView());
186+
$box->addTabGroup($tab_group);
187+
185188
$properties = id(new PHUIPropertyListView());
186-
$box->addPropertyList($properties, pht('Details'));
189+
190+
$tab_group->addTab(
191+
id(new PHUITabView())
192+
->setName(pht('Details'))
193+
->setKey('details')
194+
->appendChild($properties));
187195

188196
if ($file->getAuthorPHID()) {
189197
$properties->addProperty(
@@ -195,9 +203,13 @@ private function buildPropertyViews(
195203
pht('Created'),
196204
phabricator_datetime($file->getDateCreated(), $viewer));
197205

198-
199206
$finfo = id(new PHUIPropertyListView());
200-
$box->addPropertyList($finfo, pht('File Info'));
207+
208+
$tab_group->addTab(
209+
id(new PHUITabView())
210+
->setName(pht('File Info'))
211+
->setKey('info')
212+
->appendChild($finfo));
201213

202214
$finfo->addProperty(
203215
pht('Size'),
@@ -262,7 +274,12 @@ private function buildPropertyViews(
262274
}
263275

264276
$storage_properties = new PHUIPropertyListView();
265-
$box->addPropertyList($storage_properties, pht('Storage'));
277+
278+
$tab_group->addTab(
279+
id(new PHUITabView())
280+
->setName(pht('Storage'))
281+
->setKey('storage')
282+
->appendChild($storage_properties));
266283

267284
$storage_properties->addProperty(
268285
pht('Engine'),
@@ -285,7 +302,12 @@ private function buildPropertyViews(
285302
$phids = $file->getObjectPHIDs();
286303
if ($phids) {
287304
$attached = new PHUIPropertyListView();
288-
$box->addPropertyList($attached, pht('Attached'));
305+
306+
$tab_group->addTab(
307+
id(new PHUITabView())
308+
->setName(pht('Attached'))
309+
->setKey('attached')
310+
->appendChild($attached));
289311

290312
$attached->addProperty(
291313
pht('Attached To'),
@@ -357,7 +379,12 @@ private function buildPropertyViews(
357379
if ($engine) {
358380
if ($engine->isChunkEngine()) {
359381
$chunkinfo = new PHUIPropertyListView();
360-
$box->addPropertyList($chunkinfo, pht('Chunks'));
382+
383+
$tab_group->addTab(
384+
id(new PHUITabView())
385+
->setName(pht('Chunks'))
386+
->setKey('chunks')
387+
->appendChild($chunkinfo));
361388

362389
$chunks = id(new PhabricatorFileChunkQuery())
363390
->setViewer($viewer)

‎src/view/phui/PHUIObjectBoxView.php

+8-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ final class PHUIObjectBoxView extends AphrontTagView {
55
private $headerText;
66
private $color;
77
private $background;
8+
private $tabGroups = array();
89
private $formErrors = null;
910
private $formSaved = false;
1011
private $infoView;
@@ -128,6 +129,11 @@ public function setFormSaved($saved, $text = null) {
128129
return $this;
129130
}
130131

132+
public function addTabGroup(PHUITabGroupView $view) {
133+
$this->tabGroups[] = $view;
134+
return $this;
135+
}
136+
131137
public function setInfoView(PHUIInfoView $view) {
132138
$this->infoView = $view;
133139
return $this;
@@ -211,7 +217,7 @@ public function willRender() {
211217
$i = 0;
212218
foreach ($list as $item) {
213219
$group->addPropertyList($item);
214-
if ($i > 0) {
220+
if ($i > 0 || $this->tabGroups) {
215221
$item->addClass('phui-property-list-section-noninitial');
216222
}
217223
$i++;
@@ -405,6 +411,7 @@ protected function getTagContent() {
405411
$this->formSaved,
406412
$exception_errors,
407413
$this->form,
414+
$this->tabGroups,
408415
$tabs,
409416
$this->tabLists,
410417
$showhide,

‎src/view/phui/PHUITabGroupView.php

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
3+
final class PHUITabGroupView extends AphrontTagView {
4+
5+
private $tabs = array();
6+
7+
protected function canAppendChild() {
8+
return false;
9+
}
10+
11+
public function addTab(PHUITabView $tab) {
12+
$key = $tab->getKey();
13+
$tab->lockKey();
14+
15+
if (isset($this->tabs[$key])) {
16+
throw new Exception(
17+
pht(
18+
'Each tab in a tab group must have a unique key; attempting to add '.
19+
'a second tab with a duplicate key ("%s").',
20+
$key));
21+
}
22+
23+
$this->tabs[$key] = $tab;
24+
25+
return $this;
26+
}
27+
28+
public function getSelectedTab() {
29+
if (!$this->tabs) {
30+
return null;
31+
}
32+
33+
return head($this->tabs)->getKey();
34+
}
35+
36+
protected function getTagAttributes() {
37+
$tab_map = mpull($this->tabs, 'getContentID', 'getKey');
38+
39+
return array(
40+
'sigil' => 'phui-object-box',
41+
'meta' => array(
42+
'tabMap' => $tab_map,
43+
),
44+
);
45+
}
46+
47+
protected function getTagContent() {
48+
Javelin::initBehavior('phui-object-box-tabs');
49+
50+
$tabs = id(new PHUIListView())
51+
->setType(PHUIListView::NAVBAR_LIST);
52+
$content = array();
53+
54+
$selected_tab = $this->getSelectedTab();
55+
foreach ($this->tabs as $tab) {
56+
$item = $tab->newMenuItem();
57+
$tab_key = $tab->getKey();
58+
59+
if ($tab_key == $selected_tab) {
60+
$item->setSelected(true);
61+
$style = null;
62+
} else {
63+
$style = 'display: none;';
64+
}
65+
66+
$tabs->addMenuItem($item);
67+
68+
$content[] = javelin_tag(
69+
'div',
70+
array(
71+
'style' => $style,
72+
'id' => $tab->getContentID(),
73+
),
74+
$tab);
75+
}
76+
77+
return array(
78+
$tabs,
79+
$content,
80+
);
81+
}
82+
83+
}

‎src/view/phui/PHUITabView.php

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
final class PHUITabView extends AphrontTagView {
4+
5+
private $name;
6+
private $key;
7+
private $keyLocked;
8+
private $contentID;
9+
10+
public function setKey($key) {
11+
if ($this->keyLocked) {
12+
throw new Exception(
13+
pht(
14+
'Attempting to change the key of a tab with a locked key ("%s").',
15+
$this->key));
16+
}
17+
18+
$this->key = $key;
19+
return $this;
20+
}
21+
22+
public function hasKey() {
23+
return ($this->key !== null);
24+
}
25+
26+
public function getKey() {
27+
if (!$this->hasKey()) {
28+
throw new PhutilInvalidStateException('setKey');
29+
}
30+
31+
return $this->key;
32+
}
33+
34+
public function lockKey() {
35+
if (!$this->hasKey()) {
36+
throw new PhutilInvalidStateException('setKey');
37+
}
38+
39+
$this->keyLocked = true;
40+
41+
return $this;
42+
}
43+
44+
public function setName($name) {
45+
$this->name = $name;
46+
return $this;
47+
}
48+
49+
public function getName() {
50+
return $this->name;
51+
}
52+
53+
public function getContentID() {
54+
if ($this->contentID === null) {
55+
$this->contentID = celerity_generate_unique_node_id();
56+
}
57+
58+
return $this->contentID;
59+
}
60+
61+
public function newMenuItem() {
62+
return id(new PHUIListItemView())
63+
->setName($this->getName())
64+
->setKey($this->getKey())
65+
->setType(PHUIListItemView::TYPE_LINK)
66+
->setHref('#')
67+
->addSigil('phui-object-box-tab')
68+
->setMetadata(
69+
array(
70+
'tabKey' => $this->getKey(),
71+
));
72+
}
73+
74+
}

0 commit comments

Comments
 (0)
Failed to load comments.