diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index e947ff08c8..fa4a5397df 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -3921,7 +3921,7 @@ celerity_register_resource_map(array( ), 'phui-property-list-view-css' => 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', 'requires' => array( @@ -4309,7 +4309,7 @@ celerity_register_resource_map(array( ), array( 'packages' => array( - '7a1959db' => + '71e32b00' => array( 'name' => 'core.pkg.css', 'symbols' => @@ -4358,7 +4358,7 @@ celerity_register_resource_map(array( 41 => 'phabricator-tag-view-css', 42 => 'phui-list-view-css', ), - 'uri' => '/res/pkg/7a1959db/core.pkg.css', + 'uri' => '/res/pkg/71e32b00/core.pkg.css', 'type' => 'css', ), '2c1dba03' => @@ -4550,15 +4550,15 @@ celerity_register_resource_map(array( ), 'reverse' => array( - 'aphront-dialog-view-css' => '7a1959db', - 'aphront-error-view-css' => '7a1959db', - 'aphront-list-filter-view-css' => '7a1959db', - 'aphront-pager-view-css' => '7a1959db', - 'aphront-panel-view-css' => '7a1959db', - 'aphront-table-view-css' => '7a1959db', - 'aphront-tokenizer-control-css' => '7a1959db', - 'aphront-tooltip-css' => '7a1959db', - 'aphront-typeahead-control-css' => '7a1959db', + 'aphront-dialog-view-css' => '71e32b00', + 'aphront-error-view-css' => '71e32b00', + 'aphront-list-filter-view-css' => '71e32b00', + 'aphront-pager-view-css' => '71e32b00', + 'aphront-panel-view-css' => '71e32b00', + 'aphront-table-view-css' => '71e32b00', + 'aphront-tokenizer-control-css' => '71e32b00', + 'aphront-tooltip-css' => '71e32b00', + 'aphront-typeahead-control-css' => '71e32b00', 'differential-changeset-view-css' => '7cd7e387', 'differential-core-view-css' => '7cd7e387', 'differential-inline-comment-editor' => '5e9e5c4e', @@ -4572,7 +4572,7 @@ celerity_register_resource_map(array( 'differential-table-of-contents-css' => '7cd7e387', 'diffusion-commit-view-css' => '270f4eb4', 'diffusion-icons-css' => '270f4eb4', - 'global-drag-and-drop-css' => '7a1959db', + 'global-drag-and-drop-css' => '71e32b00', 'inline-comment-summary-css' => '7cd7e387', 'javelin-aphlict' => '2c1dba03', 'javelin-behavior' => '3e3be199', @@ -4647,56 +4647,56 @@ celerity_register_resource_map(array( 'javelin-util' => '3e3be199', 'javelin-vector' => '3e3be199', 'javelin-workflow' => '3e3be199', - 'lightbox-attachment-css' => '7a1959db', + 'lightbox-attachment-css' => '71e32b00', 'maniphest-task-summary-css' => '49898640', - 'phabricator-action-list-view-css' => '7a1959db', - 'phabricator-application-launch-view-css' => '7a1959db', + 'phabricator-action-list-view-css' => '71e32b00', + 'phabricator-application-launch-view-css' => '71e32b00', 'phabricator-busy' => '2c1dba03', 'phabricator-content-source-view-css' => '7cd7e387', - 'phabricator-core-css' => '7a1959db', - 'phabricator-crumbs-view-css' => '7a1959db', + 'phabricator-core-css' => '71e32b00', + 'phabricator-crumbs-view-css' => '71e32b00', 'phabricator-drag-and-drop-file-upload' => '5e9e5c4e', 'phabricator-dropdown-menu' => '2c1dba03', 'phabricator-file-upload' => '2c1dba03', - 'phabricator-filetree-view-css' => '7a1959db', - 'phabricator-flag-css' => '7a1959db', + 'phabricator-filetree-view-css' => '71e32b00', + 'phabricator-flag-css' => '71e32b00', 'phabricator-hovercard' => '2c1dba03', - 'phabricator-jump-nav' => '7a1959db', + 'phabricator-jump-nav' => '71e32b00', 'phabricator-keyboard-shortcut' => '2c1dba03', 'phabricator-keyboard-shortcut-manager' => '2c1dba03', - 'phabricator-main-menu-view' => '7a1959db', + 'phabricator-main-menu-view' => '71e32b00', 'phabricator-menu-item' => '2c1dba03', - 'phabricator-nav-view-css' => '7a1959db', + 'phabricator-nav-view-css' => '71e32b00', 'phabricator-notification' => '2c1dba03', - 'phabricator-notification-css' => '7a1959db', - 'phabricator-notification-menu-css' => '7a1959db', + 'phabricator-notification-css' => '71e32b00', + 'phabricator-notification-menu-css' => '71e32b00', 'phabricator-object-selector-css' => '7cd7e387', 'phabricator-phtize' => '2c1dba03', 'phabricator-prefab' => '2c1dba03', 'phabricator-project-tag-css' => '49898640', - 'phabricator-remarkup-css' => '7a1959db', + 'phabricator-remarkup-css' => '71e32b00', 'phabricator-shaped-request' => '5e9e5c4e', - 'phabricator-side-menu-view-css' => '7a1959db', - 'phabricator-standard-page-view' => '7a1959db', - 'phabricator-tag-view-css' => '7a1959db', + 'phabricator-side-menu-view-css' => '71e32b00', + 'phabricator-standard-page-view' => '71e32b00', + 'phabricator-tag-view-css' => '71e32b00', 'phabricator-textareautils' => '2c1dba03', 'phabricator-tooltip' => '2c1dba03', - 'phabricator-transaction-view-css' => '7a1959db', - 'phabricator-zindex-css' => '7a1959db', - 'phui-button-css' => '7a1959db', - 'phui-form-css' => '7a1959db', - 'phui-form-view-css' => '7a1959db', - 'phui-header-view-css' => '7a1959db', - 'phui-icon-view-css' => '7a1959db', - 'phui-list-view-css' => '7a1959db', - 'phui-object-item-list-view-css' => '7a1959db', - 'phui-property-list-view-css' => '7a1959db', - 'phui-spacing-css' => '7a1959db', - 'sprite-apps-large-css' => '7a1959db', - 'sprite-gradient-css' => '7a1959db', - 'sprite-icons-css' => '7a1959db', - 'sprite-menu-css' => '7a1959db', - 'sprite-status-css' => '7a1959db', - 'syntax-highlighting-css' => '7a1959db', + 'phabricator-transaction-view-css' => '71e32b00', + 'phabricator-zindex-css' => '71e32b00', + 'phui-button-css' => '71e32b00', + 'phui-form-css' => '71e32b00', + 'phui-form-view-css' => '71e32b00', + 'phui-header-view-css' => '71e32b00', + 'phui-icon-view-css' => '71e32b00', + 'phui-list-view-css' => '71e32b00', + 'phui-object-item-list-view-css' => '71e32b00', + 'phui-property-list-view-css' => '71e32b00', + 'phui-spacing-css' => '71e32b00', + 'sprite-apps-large-css' => '71e32b00', + 'sprite-gradient-css' => '71e32b00', + 'sprite-icons-css' => '71e32b00', + 'sprite-menu-css' => '71e32b00', + 'sprite-status-css' => '71e32b00', + 'syntax-highlighting-css' => '71e32b00', ), )); diff --git a/src/applications/files/controller/PhabricatorFileInfoController.php b/src/applications/files/controller/PhabricatorFileInfoController.php index de6183646f..11c51e2c3f 100644 --- a/src/applications/files/controller/PhabricatorFileInfoController.php +++ b/src/applications/files/controller/PhabricatorFileInfoController.php @@ -44,7 +44,6 @@ final class PhabricatorFileInfoController extends PhabricatorFileController { } $actions = $this->buildActionView($file); - $properties_array = $this->buildPropertyView($file, $actions); $timeline = $this->buildTransactionView($file, $xactions); $crumbs = $this->buildApplicationCrumbs(); $crumbs->setActionList($actions); @@ -56,9 +55,7 @@ final class PhabricatorFileInfoController extends PhabricatorFileController { $object_box = id(new PHUIObjectBoxView()) ->setHeader($header); - foreach ($properties_array as $property_item) { - $object_box->addPropertyList($property_item); - } + $this->buildPropertyViews($object_box, $file, $actions); return $this->buildApplicationPage( array( @@ -164,15 +161,17 @@ final class PhabricatorFileInfoController extends PhabricatorFileController { return $view; } - private function buildPropertyView( + private function buildPropertyViews( + PHUIObjectBoxView $box, PhabricatorFile $file, PhabricatorActionListView $actions) { $request = $this->getRequest(); $user = $request->getUser(); - $listview = array(); + $properties = id(new PHUIPropertyListView()); $properties->setActionList($actions); + $box->addPropertyList($properties, pht('Details')); if ($file->getAuthorPHID()) { $properties->addProperty( @@ -184,55 +183,61 @@ final class PhabricatorFileInfoController extends PhabricatorFileController { pht('Created'), phabricator_datetime($file->getDateCreated(), $user)); - $properties->addProperty( + + $finfo = id(new PHUIPropertyListView()); + $box->addPropertyList($finfo, pht('File Info')); + + $finfo->addProperty( pht('Size'), phabricator_format_bytes($file->getByteSize())); - $properties->addSectionHeader(pht('Technical Details')); - - $properties->addProperty( + $finfo->addProperty( pht('Mime Type'), $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'), $file->getStorageEngine()); - $properties->addProperty( + $storage_properties->addProperty( pht('Format'), $file->getStorageFormat()); - $properties->addProperty( + $storage_properties->addProperty( pht('Handle'), $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(); if ($phids) { $attached = new PHUIPropertyListView(); - $attached->addSectionHeader(pht('Attached')); + $box->addPropertyList($attached, pht('Attached')); + $attached->addProperty( pht('Attached To'), $this->renderHandlesForPHIDs($phids)); - $listview[] = $attached; } - if ($file->isViewableImage()) { + if ($file->isViewableImage()) { $image = phutil_tag( 'img', array( @@ -249,7 +254,8 @@ final class PhabricatorFileInfoController extends PhabricatorFileController { $media = id(new PHUIPropertyListView()) ->addImageContent($linked_image); - $listview[] = $media; + + $box->addPropertyList($media); } else if ($file->isAudio()) { $audio = phutil_tag( 'audio', @@ -265,10 +271,9 @@ final class PhabricatorFileInfoController extends PhabricatorFileController { ))); $media = id(new PHUIPropertyListView()) ->addImageContent($audio); - $listview[] = $media; - } - return $listview; + $box->addPropertyList($media); + } } } diff --git a/src/applications/files/storage/PhabricatorFile.php b/src/applications/files/storage/PhabricatorFile.php index 37bd60af16..62f116d67b 100644 --- a/src/applications/files/storage/PhabricatorFile.php +++ b/src/applications/files/storage/PhabricatorFile.php @@ -725,22 +725,6 @@ final class PhabricatorFile extends PhabricatorFileDAO 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 diff --git a/src/applications/uiexample/examples/PHUIPropertyListExample.php b/src/applications/uiexample/examples/PHUIPropertyListExample.php index 5daf821390..6438f31e65 100644 --- a/src/applications/uiexample/examples/PHUIPropertyListExample.php +++ b/src/applications/uiexample/examples/PHUIPropertyListExample.php @@ -17,18 +17,15 @@ final class PHUIPropertyListExample extends PhabricatorUIExample { $details1 = id(new PHUIListItemView()) ->setName('Details') - ->setSelected(true) - ->setType(PHUIListItemView::TYPE_LINK); + ->setSelected(true); $details2 = id(new PHUIListItemView()) ->setName('Rainbow Info') - ->setStatusColor(PHUIListItemView::STATUS_WARN) - ->setType(PHUIListItemView::TYPE_LINK); + ->setStatusColor(PHUIListItemView::STATUS_WARN); $details3 = id(new PHUIListItemView()) ->setName('Pasta Haiku') - ->setStatusColor(PHUIListItemView::STATUS_FAIL) - ->setType(PHUIListItemView::TYPE_LINK); + ->setStatusColor(PHUIListItemView::STATUS_FAIL); $statustabs = id(new PHUIListView()) ->setType(PHUIListView::NAVBAR_LIST) diff --git a/src/view/phui/PHUIObjectBoxView.php b/src/view/phui/PHUIObjectBoxView.php index 8be3ee364d..856229ce74 100644 --- a/src/view/phui/PHUIObjectBoxView.php +++ b/src/view/phui/PHUIObjectBoxView.php @@ -11,21 +11,15 @@ final class PHUIObjectBoxView extends AphrontView { private $tabs = array(); private $propertyLists = array(); - private $selectedTab; public function addPropertyList( PHUIPropertyListView $property_list, - PHUIListItemView $tab = null) { + $tab = null) { - if ($this->propertyLists) { - $already_has_tabs = (bool)$this->tabs; - $adding_new_tab = (bool)$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 instanceof PHUIListItemView) && + ($tab !== null)) { + assert_stringlike($tab); + $tab = id(new PHUIListItemView())->setName($tab); } if ($tab) { @@ -40,10 +34,6 @@ final class PHUIObjectBoxView extends AphrontView { } if ($tab) { - if (!$this->tabs) { - $this->selectedTab = $key; - } - if (empty($this->tabs[$key])) { $tab->addSigil('phui-object-box-tab'); $tab->setMetadata( @@ -55,6 +45,10 @@ final class PHUIObjectBoxView extends AphrontView { $tab->setHref('#'); } + if (!$tab->getType()) { + $tab->setType(PHUIListItemView::TYPE_LINK); + } + $this->tabs[$key] = $tab; } } @@ -121,25 +115,44 @@ final class PHUIObjectBoxView extends AphrontView { } } + $tab_lists = array(); $property_lists = 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) { $group = new PHUIPropertyGroupView(); foreach ($list as $item) { $group->addPropertyList($item); } - if ($this->tabs) { + if ($this->tabs && $key != $default_key) { $tab_id = celerity_generate_unique_node_id(); $tab_map[$key] = $tab_id; - if ($key === $this->selectedTab) { + if ($key === $selected_tab) { $style = null; } else { $style = 'display: none'; } - $property_lists[] = phutil_tag( + $tab_lists[] = phutil_tag( 'div', array( 'style' => $style, @@ -147,6 +160,9 @@ final class PHUIObjectBoxView extends AphrontView { ), $group); } else { + if ($this->tabs) { + $group->addClass('phui-property-group-noninitial'); + } $property_lists[] = $group; } } @@ -170,6 +186,7 @@ final class PHUIObjectBoxView extends AphrontView { $exception_errors, $this->form, $tabs, + $tab_lists, $property_lists, $this->renderChildren(), )) diff --git a/webroot/rsrc/css/phui/phui-property-list-view.css b/webroot/rsrc/css/phui/phui-property-list-view.css index b16d1b7eeb..31edfc1901 100644 --- a/webroot/rsrc/css/phui/phui-property-list-view.css +++ b/webroot/rsrc/css/phui/phui-property-list-view.css @@ -24,7 +24,8 @@ } .phui-property-list-section + - .phui-property-list-section { + .phui-property-list-section, +.phui-property-group-noninitial { border-color: {$thinblueborder}; border-style: solid; border-width: 1px 0 0;