1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-26 16:52:41 +01:00

Use property tabs in Files

Summary:
See screenshots. Some simplifications:

  - Tabbed and non-tabbed lists are now allowed to be mixed. We just make the non-tabbed lists permanent and put them on the bottom (e.g., image and audio data in Files).
  - You can provide a tab name instead of an entire tab object and we'll build an object for you.
  - We respect `setSelected()` on the tab objects now.

Test Plan: See screenshots.

Reviewers: chad, btrahan

Reviewed By: chad

CC: chad, aran

Differential Revision: https://secure.phabricator.com/D7362
This commit is contained in:
epriestley 2013-10-19 12:08:06 -07:00
parent 2228029201
commit 3643fe1498
6 changed files with 125 additions and 121 deletions

View file

@ -3921,7 +3921,7 @@ celerity_register_resource_map(array(
), ),
'phui-property-list-view-css' => 'phui-property-list-view-css' =>
array( array(
'uri' => '/res/7c39fbe1/rsrc/css/phui/phui-property-list-view.css', 'uri' => '/res/81bdc80f/rsrc/css/phui/phui-property-list-view.css',
'type' => 'css', 'type' => 'css',
'requires' => 'requires' =>
array( array(
@ -4309,7 +4309,7 @@ celerity_register_resource_map(array(
), array( ), array(
'packages' => 'packages' =>
array( array(
'7a1959db' => '71e32b00' =>
array( array(
'name' => 'core.pkg.css', 'name' => 'core.pkg.css',
'symbols' => 'symbols' =>
@ -4358,7 +4358,7 @@ celerity_register_resource_map(array(
41 => 'phabricator-tag-view-css', 41 => 'phabricator-tag-view-css',
42 => 'phui-list-view-css', 42 => 'phui-list-view-css',
), ),
'uri' => '/res/pkg/7a1959db/core.pkg.css', 'uri' => '/res/pkg/71e32b00/core.pkg.css',
'type' => 'css', 'type' => 'css',
), ),
'2c1dba03' => '2c1dba03' =>
@ -4550,15 +4550,15 @@ celerity_register_resource_map(array(
), ),
'reverse' => 'reverse' =>
array( array(
'aphront-dialog-view-css' => '7a1959db', 'aphront-dialog-view-css' => '71e32b00',
'aphront-error-view-css' => '7a1959db', 'aphront-error-view-css' => '71e32b00',
'aphront-list-filter-view-css' => '7a1959db', 'aphront-list-filter-view-css' => '71e32b00',
'aphront-pager-view-css' => '7a1959db', 'aphront-pager-view-css' => '71e32b00',
'aphront-panel-view-css' => '7a1959db', 'aphront-panel-view-css' => '71e32b00',
'aphront-table-view-css' => '7a1959db', 'aphront-table-view-css' => '71e32b00',
'aphront-tokenizer-control-css' => '7a1959db', 'aphront-tokenizer-control-css' => '71e32b00',
'aphront-tooltip-css' => '7a1959db', 'aphront-tooltip-css' => '71e32b00',
'aphront-typeahead-control-css' => '7a1959db', 'aphront-typeahead-control-css' => '71e32b00',
'differential-changeset-view-css' => '7cd7e387', 'differential-changeset-view-css' => '7cd7e387',
'differential-core-view-css' => '7cd7e387', 'differential-core-view-css' => '7cd7e387',
'differential-inline-comment-editor' => '5e9e5c4e', 'differential-inline-comment-editor' => '5e9e5c4e',
@ -4572,7 +4572,7 @@ celerity_register_resource_map(array(
'differential-table-of-contents-css' => '7cd7e387', 'differential-table-of-contents-css' => '7cd7e387',
'diffusion-commit-view-css' => '270f4eb4', 'diffusion-commit-view-css' => '270f4eb4',
'diffusion-icons-css' => '270f4eb4', 'diffusion-icons-css' => '270f4eb4',
'global-drag-and-drop-css' => '7a1959db', 'global-drag-and-drop-css' => '71e32b00',
'inline-comment-summary-css' => '7cd7e387', 'inline-comment-summary-css' => '7cd7e387',
'javelin-aphlict' => '2c1dba03', 'javelin-aphlict' => '2c1dba03',
'javelin-behavior' => '3e3be199', 'javelin-behavior' => '3e3be199',
@ -4647,56 +4647,56 @@ celerity_register_resource_map(array(
'javelin-util' => '3e3be199', 'javelin-util' => '3e3be199',
'javelin-vector' => '3e3be199', 'javelin-vector' => '3e3be199',
'javelin-workflow' => '3e3be199', 'javelin-workflow' => '3e3be199',
'lightbox-attachment-css' => '7a1959db', 'lightbox-attachment-css' => '71e32b00',
'maniphest-task-summary-css' => '49898640', 'maniphest-task-summary-css' => '49898640',
'phabricator-action-list-view-css' => '7a1959db', 'phabricator-action-list-view-css' => '71e32b00',
'phabricator-application-launch-view-css' => '7a1959db', 'phabricator-application-launch-view-css' => '71e32b00',
'phabricator-busy' => '2c1dba03', 'phabricator-busy' => '2c1dba03',
'phabricator-content-source-view-css' => '7cd7e387', 'phabricator-content-source-view-css' => '7cd7e387',
'phabricator-core-css' => '7a1959db', 'phabricator-core-css' => '71e32b00',
'phabricator-crumbs-view-css' => '7a1959db', 'phabricator-crumbs-view-css' => '71e32b00',
'phabricator-drag-and-drop-file-upload' => '5e9e5c4e', 'phabricator-drag-and-drop-file-upload' => '5e9e5c4e',
'phabricator-dropdown-menu' => '2c1dba03', 'phabricator-dropdown-menu' => '2c1dba03',
'phabricator-file-upload' => '2c1dba03', 'phabricator-file-upload' => '2c1dba03',
'phabricator-filetree-view-css' => '7a1959db', 'phabricator-filetree-view-css' => '71e32b00',
'phabricator-flag-css' => '7a1959db', 'phabricator-flag-css' => '71e32b00',
'phabricator-hovercard' => '2c1dba03', 'phabricator-hovercard' => '2c1dba03',
'phabricator-jump-nav' => '7a1959db', 'phabricator-jump-nav' => '71e32b00',
'phabricator-keyboard-shortcut' => '2c1dba03', 'phabricator-keyboard-shortcut' => '2c1dba03',
'phabricator-keyboard-shortcut-manager' => '2c1dba03', 'phabricator-keyboard-shortcut-manager' => '2c1dba03',
'phabricator-main-menu-view' => '7a1959db', 'phabricator-main-menu-view' => '71e32b00',
'phabricator-menu-item' => '2c1dba03', 'phabricator-menu-item' => '2c1dba03',
'phabricator-nav-view-css' => '7a1959db', 'phabricator-nav-view-css' => '71e32b00',
'phabricator-notification' => '2c1dba03', 'phabricator-notification' => '2c1dba03',
'phabricator-notification-css' => '7a1959db', 'phabricator-notification-css' => '71e32b00',
'phabricator-notification-menu-css' => '7a1959db', 'phabricator-notification-menu-css' => '71e32b00',
'phabricator-object-selector-css' => '7cd7e387', 'phabricator-object-selector-css' => '7cd7e387',
'phabricator-phtize' => '2c1dba03', 'phabricator-phtize' => '2c1dba03',
'phabricator-prefab' => '2c1dba03', 'phabricator-prefab' => '2c1dba03',
'phabricator-project-tag-css' => '49898640', 'phabricator-project-tag-css' => '49898640',
'phabricator-remarkup-css' => '7a1959db', 'phabricator-remarkup-css' => '71e32b00',
'phabricator-shaped-request' => '5e9e5c4e', 'phabricator-shaped-request' => '5e9e5c4e',
'phabricator-side-menu-view-css' => '7a1959db', 'phabricator-side-menu-view-css' => '71e32b00',
'phabricator-standard-page-view' => '7a1959db', 'phabricator-standard-page-view' => '71e32b00',
'phabricator-tag-view-css' => '7a1959db', 'phabricator-tag-view-css' => '71e32b00',
'phabricator-textareautils' => '2c1dba03', 'phabricator-textareautils' => '2c1dba03',
'phabricator-tooltip' => '2c1dba03', 'phabricator-tooltip' => '2c1dba03',
'phabricator-transaction-view-css' => '7a1959db', 'phabricator-transaction-view-css' => '71e32b00',
'phabricator-zindex-css' => '7a1959db', 'phabricator-zindex-css' => '71e32b00',
'phui-button-css' => '7a1959db', 'phui-button-css' => '71e32b00',
'phui-form-css' => '7a1959db', 'phui-form-css' => '71e32b00',
'phui-form-view-css' => '7a1959db', 'phui-form-view-css' => '71e32b00',
'phui-header-view-css' => '7a1959db', 'phui-header-view-css' => '71e32b00',
'phui-icon-view-css' => '7a1959db', 'phui-icon-view-css' => '71e32b00',
'phui-list-view-css' => '7a1959db', 'phui-list-view-css' => '71e32b00',
'phui-object-item-list-view-css' => '7a1959db', 'phui-object-item-list-view-css' => '71e32b00',
'phui-property-list-view-css' => '7a1959db', 'phui-property-list-view-css' => '71e32b00',
'phui-spacing-css' => '7a1959db', 'phui-spacing-css' => '71e32b00',
'sprite-apps-large-css' => '7a1959db', 'sprite-apps-large-css' => '71e32b00',
'sprite-gradient-css' => '7a1959db', 'sprite-gradient-css' => '71e32b00',
'sprite-icons-css' => '7a1959db', 'sprite-icons-css' => '71e32b00',
'sprite-menu-css' => '7a1959db', 'sprite-menu-css' => '71e32b00',
'sprite-status-css' => '7a1959db', 'sprite-status-css' => '71e32b00',
'syntax-highlighting-css' => '7a1959db', 'syntax-highlighting-css' => '71e32b00',
), ),
)); ));

View file

@ -44,7 +44,6 @@ final class PhabricatorFileInfoController extends PhabricatorFileController {
} }
$actions = $this->buildActionView($file); $actions = $this->buildActionView($file);
$properties_array = $this->buildPropertyView($file, $actions);
$timeline = $this->buildTransactionView($file, $xactions); $timeline = $this->buildTransactionView($file, $xactions);
$crumbs = $this->buildApplicationCrumbs(); $crumbs = $this->buildApplicationCrumbs();
$crumbs->setActionList($actions); $crumbs->setActionList($actions);
@ -56,9 +55,7 @@ final class PhabricatorFileInfoController extends PhabricatorFileController {
$object_box = id(new PHUIObjectBoxView()) $object_box = id(new PHUIObjectBoxView())
->setHeader($header); ->setHeader($header);
foreach ($properties_array as $property_item) { $this->buildPropertyViews($object_box, $file, $actions);
$object_box->addPropertyList($property_item);
}
return $this->buildApplicationPage( return $this->buildApplicationPage(
array( array(
@ -164,15 +161,17 @@ final class PhabricatorFileInfoController extends PhabricatorFileController {
return $view; return $view;
} }
private function buildPropertyView( private function buildPropertyViews(
PHUIObjectBoxView $box,
PhabricatorFile $file, PhabricatorFile $file,
PhabricatorActionListView $actions) { PhabricatorActionListView $actions) {
$request = $this->getRequest(); $request = $this->getRequest();
$user = $request->getUser(); $user = $request->getUser();
$listview = array();
$properties = id(new PHUIPropertyListView()); $properties = id(new PHUIPropertyListView());
$properties->setActionList($actions); $properties->setActionList($actions);
$box->addPropertyList($properties, pht('Details'));
if ($file->getAuthorPHID()) { if ($file->getAuthorPHID()) {
$properties->addProperty( $properties->addProperty(
@ -184,55 +183,61 @@ final class PhabricatorFileInfoController extends PhabricatorFileController {
pht('Created'), pht('Created'),
phabricator_datetime($file->getDateCreated(), $user)); phabricator_datetime($file->getDateCreated(), $user));
$properties->addProperty(
$finfo = id(new PHUIPropertyListView());
$box->addPropertyList($finfo, pht('File Info'));
$finfo->addProperty(
pht('Size'), pht('Size'),
phabricator_format_bytes($file->getByteSize())); phabricator_format_bytes($file->getByteSize()));
$properties->addSectionHeader(pht('Technical Details')); $finfo->addProperty(
$properties->addProperty(
pht('Mime Type'), pht('Mime Type'),
$file->getMimeType()); $file->getMimeType());
$properties->addProperty( $width = $file->getImageWidth();
if ($width) {
$finfo->addProperty(
pht('Width'),
pht('%s px', new PhutilNumber($width)));
}
$height = $file->getImageHeight();
if ($height) {
$finfo->addProperty(
pht('Height'),
pht('%s px', new PhutilNumber($height)));
}
$storage_properties = new PHUIPropertyListView();
$box->addPropertyList($storage_properties, pht('Storage'));
$storage_properties->addProperty(
pht('Engine'), pht('Engine'),
$file->getStorageEngine()); $file->getStorageEngine());
$properties->addProperty( $storage_properties->addProperty(
pht('Format'), pht('Format'),
$file->getStorageFormat()); $file->getStorageFormat());
$properties->addProperty( $storage_properties->addProperty(
pht('Handle'), pht('Handle'),
$file->getStorageHandle()); $file->getStorageHandle());
$listview[] = $properties;
$metadata = $file->getMetadata();
if (!empty($metadata)) {
$mdata = id(new PHUIPropertyListView())
->addSectionHeader(pht('Metadata'));
foreach ($metadata as $key => $value) {
$mdata->addProperty(
PhabricatorFile::getMetadataName($key),
$value);
}
$listview[] = $mdata;
}
$phids = $file->getObjectPHIDs(); $phids = $file->getObjectPHIDs();
if ($phids) { if ($phids) {
$attached = new PHUIPropertyListView(); $attached = new PHUIPropertyListView();
$attached->addSectionHeader(pht('Attached')); $box->addPropertyList($attached, pht('Attached'));
$attached->addProperty( $attached->addProperty(
pht('Attached To'), pht('Attached To'),
$this->renderHandlesForPHIDs($phids)); $this->renderHandlesForPHIDs($phids));
$listview[] = $attached;
} }
if ($file->isViewableImage()) {
if ($file->isViewableImage()) {
$image = phutil_tag( $image = phutil_tag(
'img', 'img',
array( array(
@ -249,7 +254,8 @@ final class PhabricatorFileInfoController extends PhabricatorFileController {
$media = id(new PHUIPropertyListView()) $media = id(new PHUIPropertyListView())
->addImageContent($linked_image); ->addImageContent($linked_image);
$listview[] = $media;
$box->addPropertyList($media);
} else if ($file->isAudio()) { } else if ($file->isAudio()) {
$audio = phutil_tag( $audio = phutil_tag(
'audio', 'audio',
@ -265,10 +271,9 @@ final class PhabricatorFileInfoController extends PhabricatorFileController {
))); )));
$media = id(new PHUIPropertyListView()) $media = id(new PHUIPropertyListView())
->addImageContent($audio); ->addImageContent($audio);
$listview[] = $media;
}
return $listview; $box->addPropertyList($media);
}
} }
} }

View file

@ -725,22 +725,6 @@ final class PhabricatorFile extends PhabricatorFileDAO
return $this; return $this;
} }
public static function getMetadataName($metadata) {
switch ($metadata) {
case self::METADATA_IMAGE_WIDTH:
$name = pht('Width');
break;
case self::METADATA_IMAGE_HEIGHT:
$name = pht('Height');
break;
default:
$name = ucfirst($metadata);
break;
}
return $name;
}
/** /**
* Load (or build) the {@class:PhabricatorFile} objects for builtin file * Load (or build) the {@class:PhabricatorFile} objects for builtin file

View file

@ -17,18 +17,15 @@ final class PHUIPropertyListExample extends PhabricatorUIExample {
$details1 = id(new PHUIListItemView()) $details1 = id(new PHUIListItemView())
->setName('Details') ->setName('Details')
->setSelected(true) ->setSelected(true);
->setType(PHUIListItemView::TYPE_LINK);
$details2 = id(new PHUIListItemView()) $details2 = id(new PHUIListItemView())
->setName('Rainbow Info') ->setName('Rainbow Info')
->setStatusColor(PHUIListItemView::STATUS_WARN) ->setStatusColor(PHUIListItemView::STATUS_WARN);
->setType(PHUIListItemView::TYPE_LINK);
$details3 = id(new PHUIListItemView()) $details3 = id(new PHUIListItemView())
->setName('Pasta Haiku') ->setName('Pasta Haiku')
->setStatusColor(PHUIListItemView::STATUS_FAIL) ->setStatusColor(PHUIListItemView::STATUS_FAIL);
->setType(PHUIListItemView::TYPE_LINK);
$statustabs = id(new PHUIListView()) $statustabs = id(new PHUIListView())
->setType(PHUIListView::NAVBAR_LIST) ->setType(PHUIListView::NAVBAR_LIST)

View file

@ -11,21 +11,15 @@ final class PHUIObjectBoxView extends AphrontView {
private $tabs = array(); private $tabs = array();
private $propertyLists = array(); private $propertyLists = array();
private $selectedTab;
public function addPropertyList( public function addPropertyList(
PHUIPropertyListView $property_list, PHUIPropertyListView $property_list,
PHUIListItemView $tab = null) { $tab = null) {
if ($this->propertyLists) { if (!($tab instanceof PHUIListItemView) &&
$already_has_tabs = (bool)$this->tabs; ($tab !== null)) {
$adding_new_tab = (bool)$tab; assert_stringlike($tab);
$tab = id(new PHUIListItemView())->setName($tab);
if ($already_has_tabs xor $adding_new_tab) {
throw new Exception(
"You can not mix tabbed and un-tabbed property lists in the same ".
"BoxView.");
}
} }
if ($tab) { if ($tab) {
@ -40,10 +34,6 @@ final class PHUIObjectBoxView extends AphrontView {
} }
if ($tab) { if ($tab) {
if (!$this->tabs) {
$this->selectedTab = $key;
}
if (empty($this->tabs[$key])) { if (empty($this->tabs[$key])) {
$tab->addSigil('phui-object-box-tab'); $tab->addSigil('phui-object-box-tab');
$tab->setMetadata( $tab->setMetadata(
@ -55,6 +45,10 @@ final class PHUIObjectBoxView extends AphrontView {
$tab->setHref('#'); $tab->setHref('#');
} }
if (!$tab->getType()) {
$tab->setType(PHUIListItemView::TYPE_LINK);
}
$this->tabs[$key] = $tab; $this->tabs[$key] = $tab;
} }
} }
@ -121,25 +115,44 @@ final class PHUIObjectBoxView extends AphrontView {
} }
} }
$tab_lists = array();
$property_lists = array(); $property_lists = array();
$tab_map = array(); $tab_map = array();
$default_key = 'tab.default';
// Find the selected tab, or select the first tab if none are selected.
if ($this->tabs) {
$selected_tab = null;
foreach ($this->tabs as $key => $tab) {
if ($tab->getSelected()) {
$selected_tab = $key;
break;
}
}
if ($selected_tab === null) {
head($this->tabs)->setSelected(true);
$selected_tab = head_key($this->tabs);
}
}
foreach ($this->propertyLists as $key => $list) { foreach ($this->propertyLists as $key => $list) {
$group = new PHUIPropertyGroupView(); $group = new PHUIPropertyGroupView();
foreach ($list as $item) { foreach ($list as $item) {
$group->addPropertyList($item); $group->addPropertyList($item);
} }
if ($this->tabs) { if ($this->tabs && $key != $default_key) {
$tab_id = celerity_generate_unique_node_id(); $tab_id = celerity_generate_unique_node_id();
$tab_map[$key] = $tab_id; $tab_map[$key] = $tab_id;
if ($key === $this->selectedTab) { if ($key === $selected_tab) {
$style = null; $style = null;
} else { } else {
$style = 'display: none'; $style = 'display: none';
} }
$property_lists[] = phutil_tag( $tab_lists[] = phutil_tag(
'div', 'div',
array( array(
'style' => $style, 'style' => $style,
@ -147,6 +160,9 @@ final class PHUIObjectBoxView extends AphrontView {
), ),
$group); $group);
} else { } else {
if ($this->tabs) {
$group->addClass('phui-property-group-noninitial');
}
$property_lists[] = $group; $property_lists[] = $group;
} }
} }
@ -170,6 +186,7 @@ final class PHUIObjectBoxView extends AphrontView {
$exception_errors, $exception_errors,
$this->form, $this->form,
$tabs, $tabs,
$tab_lists,
$property_lists, $property_lists,
$this->renderChildren(), $this->renderChildren(),
)) ))

View file

@ -24,7 +24,8 @@
} }
.phui-property-list-section + .phui-property-list-section +
.phui-property-list-section { .phui-property-list-section,
.phui-property-group-noninitial {
border-color: {$thinblueborder}; border-color: {$thinblueborder};
border-style: solid; border-style: solid;
border-width: 1px 0 0; border-width: 1px 0 0;