diff --git a/resources/celerity/map.php b/resources/celerity/map.php --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -146,6 +146,7 @@ 'rsrc/css/phui/phui-comment-form.css' => '68a2d99a', 'rsrc/css/phui/phui-comment-panel.css' => 'ec4e31c0', 'rsrc/css/phui/phui-crumbs-view.css' => '614f43cf', + 'rsrc/css/phui/phui-curtain-object-ref-view.css' => 'e3331b60', 'rsrc/css/phui/phui-curtain-view.css' => '68c5efb6', 'rsrc/css/phui/phui-document-pro.css' => 'b9613a10', 'rsrc/css/phui/phui-document-summary.css' => 'b068eed1', @@ -833,6 +834,7 @@ 'phui-comment-form-css' => '68a2d99a', 'phui-comment-panel-css' => 'ec4e31c0', 'phui-crumbs-view-css' => '614f43cf', + 'phui-curtain-object-ref-view-css' => 'e3331b60', 'phui-curtain-view-css' => '68c5efb6', 'phui-document-summary-view-css' => 'b068eed1', 'phui-document-view-css' => '52b748a5', diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1991,6 +1991,8 @@ 'PHUICrumbView' => 'view/phui/PHUICrumbView.php', 'PHUICrumbsView' => 'view/phui/PHUICrumbsView.php', 'PHUICurtainExtension' => 'view/extension/PHUICurtainExtension.php', + 'PHUICurtainObjectRefListView' => 'view/phui/PHUICurtainObjectRefListView.php', + 'PHUICurtainObjectRefView' => 'view/phui/PHUICurtainObjectRefView.php', 'PHUICurtainPanelView' => 'view/layout/PHUICurtainPanelView.php', 'PHUICurtainView' => 'view/layout/PHUICurtainView.php', 'PHUIDiffGraphView' => 'infrastructure/diff/view/PHUIDiffGraphView.php', @@ -8189,6 +8191,8 @@ 'PHUICrumbView' => 'AphrontView', 'PHUICrumbsView' => 'AphrontView', 'PHUICurtainExtension' => 'Phobject', + 'PHUICurtainObjectRefListView' => 'AphrontTagView', + 'PHUICurtainObjectRefView' => 'AphrontTagView', 'PHUICurtainPanelView' => 'AphrontTagView', 'PHUICurtainView' => 'AphrontTagView', 'PHUIDiffGraphView' => 'Phobject', diff --git a/src/applications/maniphest/controller/ManiphestTaskDetailController.php b/src/applications/maniphest/controller/ManiphestTaskDetailController.php --- a/src/applications/maniphest/controller/ManiphestTaskDetailController.php +++ b/src/applications/maniphest/controller/ManiphestTaskDetailController.php @@ -340,37 +340,29 @@ $author_phid = $task->getAuthorPHID(); $handles = $viewer->loadHandles(array($owner_phid, $author_phid)); + $assigned_refs = id(new PHUICurtainObjectRefListView()) + ->setViewer($viewer) + ->setEmptyMessage(pht('None')); + if ($owner_phid) { - $image_uri = $handles[$owner_phid]->getImageURI(); - $image_href = $handles[$owner_phid]->getURI(); - $owner = $viewer->renderHandle($owner_phid)->render(); - $content = phutil_tag('strong', array(), $owner); - $assigned_to = id(new PHUIHeadThingView()) - ->setImage($image_uri) - ->setImageHref($image_href) - ->setContent($content); - } else { - $assigned_to = phutil_tag('em', array(), pht('None')); + $assigned_ref = $assigned_refs->newObjectRefView() + ->setHandle($handles[$owner_phid]); } $curtain->newPanel() ->setHeaderText(pht('Assigned To')) - ->appendChild($assigned_to); - - $author_uri = $handles[$author_phid]->getImageURI(); - $author_href = $handles[$author_phid]->getURI(); - $author = $viewer->renderHandle($author_phid)->render(); - $content = phutil_tag('strong', array(), $author); - $date = phabricator_date($task->getDateCreated(), $viewer); - $content = pht('%s, %s', $content, $date); - $authored_by = id(new PHUIHeadThingView()) - ->setImage($author_uri) - ->setImageHref($author_href) - ->setContent($content); + ->appendChild($assigned_refs); + + $author_refs = id(new PHUICurtainObjectRefListView()) + ->setViewer($viewer); + + $author_ref = $author_refs->newObjectRefView() + ->setHandle($handles[$author_phid]) + ->setEpoch($task->getDateCreated()); $curtain->newPanel() ->setHeaderText(pht('Authored By')) - ->appendChild($authored_by); + ->appendChild($author_refs); return $curtain; } diff --git a/src/view/phui/PHUICurtainObjectRefListView.php b/src/view/phui/PHUICurtainObjectRefListView.php new file mode 100644 --- /dev/null +++ b/src/view/phui/PHUICurtainObjectRefListView.php @@ -0,0 +1,46 @@ + 'phui-curtain-object-ref-list-view', + ); + } + + public function setEmptyMessage($empty_message) { + $this->emptyMessage = $empty_message; + return $this; + } + + protected function getTagContent() { + $refs = $this->refs; + + if (!$refs) { + if ($this->emptyMessage) { + return phutil_tag( + 'div', + array( + 'class' => 'phui-curtain-object-ref-list-view-empty', + ), + $this->emptyMessage); + } + } + + return $refs; + } + + public function newObjectRefView() { + $ref_view = id(new PHUICurtainObjectRefView()) + ->setViewer($this->getViewer()); + + $this->refs[] = $ref_view; + + return $ref_view; + } + +} diff --git a/src/view/phui/PHUICurtainObjectRefView.php b/src/view/phui/PHUICurtainObjectRefView.php new file mode 100644 --- /dev/null +++ b/src/view/phui/PHUICurtainObjectRefView.php @@ -0,0 +1,155 @@ +handle = $handle; + return $this; + } + + public function setEpoch($epoch) { + $this->epoch = $epoch; + return $this; + } + + protected function getTagAttributes() { + return array( + 'class' => 'phui-curtain-object-ref-view', + ); + } + + protected function getTagContent() { + require_celerity_resource('phui-curtain-object-ref-view-css'); + + $viewer = $this->getViewer(); + $handle = $this->handle; + + $more_rows = array(); + + $epoch = $this->epoch; + if ($epoch !== null) { + $epoch_view = phabricator_datetime($epoch, $viewer); + + $epoch_cells = array(); + + $epoch_cells[] = phutil_tag( + 'td', + array( + 'class' => 'phui-curtain-object-ref-view-epoch-cell', + ), + $epoch_view); + + $more_rows[] = phutil_tag('tr', array(), $epoch_cells); + } + + $header_cells = array(); + + $image_view = $this->newImage(); + + if ($more_rows) { + $row_count = 1 + count($more_rows); + } else { + $row_count = null; + } + + $header_cells[] = phutil_tag( + 'td', + array( + 'rowspan' => $row_count, + 'class' => 'phui-curtain-object-ref-view-image-cell', + ), + $image_view); + + $title_view = $this->newTitle(); + + $header_cells[] = phutil_tag( + 'td', + array( + 'class' => 'phui-curtain-object-ref-view-title-cell', + ), + $title_view); + + $rows = array(); + + if (!$more_rows) { + $title_row_class = 'phui-curtain-object-ref-view-without-content'; + } else { + $title_row_class = 'phui-curtain-object-ref-view-with-content'; + } + + $rows[] = phutil_tag( + 'tr', + array( + 'class' => $title_row_class, + ), + $header_cells); + + $body = phutil_tag( + 'tbody', + array(), + array( + $rows, + $more_rows, + )); + + return phutil_tag('table', array(), $body); + } + + private function newTitle() { + $title_view = null; + $handle = $this->handle; + + if ($handle) { + $title_view = $handle->renderLink(); + } + + return $title_view; + } + + private function newImage() { + $image_uri = $this->getImageURI(); + $target_uri = $this->getTargetURI(); + + if ($image_uri !== null) { + $image_view = javelin_tag( + 'a', + array( + 'style' => sprintf('background-image: url(%s)', $image_uri), + 'href' => $target_uri, + 'aural' => false, + )); + } else { + $image_view = null; + } + + return $image_view; + } + + private function getTargetURI() { + $target_uri = null; + $handle = $this->handle; + + if ($handle) { + $target_uri = $handle->getURI(); + } + + return $target_uri; + } + + private function getImageURI() { + $image_uri = null; + $handle = $this->handle; + + if ($handle) { + $image_uri = $handle->getImageURI(); + } + + return $image_uri; + } + + +} diff --git a/webroot/rsrc/css/phui/phui-curtain-object-ref-view.css b/webroot/rsrc/css/phui/phui-curtain-object-ref-view.css new file mode 100644 --- /dev/null +++ b/webroot/rsrc/css/phui/phui-curtain-object-ref-view.css @@ -0,0 +1,48 @@ +/** + * @provides phui-curtain-object-ref-view-css + */ + +.phui-curtain-object-ref-list-view-empty { + font-style: italic; + color: {$greytext}; +} + +.phui-curtain-object-ref-view-image-cell { + min-width: 32px; + min-height: 32px; +} + +.phui-curtain-object-ref-view-image-cell > a { + height: 24px; + width: 24px; + background-size: 100%; + border-radius: 3px; + display: block; +} + +.phui-curtain-object-ref-view-title-cell { + font-weight: bold; + text-overflow: ellipsis; + overflow: hidden; + + /* This is forcing "text-overflow: ellipsis" to actually work. */ + max-width: 225px; +} + +.phui-curtain-object-ref-view-without-content > + .phui-curtain-object-ref-view-title-cell { + vertical-align: middle; +} + +.phui-curtain-object-ref-view-with-content > + .phui-curtain-object-ref-view-image-cell > a { + margin-top: 4px; +} + +.phui-curtain-object-ref-view-title-cell > a { + color: {$darkgreytext}; +} + +.phui-curtain-object-ref-view-epoch-cell { + color: {$greytext}; +}