diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 9cdc676350..2a93c39f6e 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -920,6 +920,8 @@ phutil_register_library_map(array( 'PhabricatorPeopleLogsController' => 'applications/people/controller/PhabricatorPeopleLogsController.php', 'PhabricatorPeopleProfileController' => 'applications/people/controller/PhabricatorPeopleProfileController.php', 'PhabricatorPeopleQuery' => 'applications/people/PhabricatorPeopleQuery.php', + 'PhabricatorPinboardItemView' => 'view/layout/PhabricatorPinboardItemView.php', + 'PhabricatorPinboardView' => 'view/layout/PhabricatorPinboardView.php', 'PhabricatorPolicies' => 'applications/policy/constants/PhabricatorPolicies.php', 'PhabricatorPolicy' => 'applications/policy/filter/PhabricatorPolicy.php', 'PhabricatorPolicyAwareQuery' => 'infrastructure/query/policy/PhabricatorPolicyAwareQuery.php', @@ -2049,6 +2051,8 @@ phutil_register_library_map(array( 'PhabricatorPeopleLogsController' => 'PhabricatorPeopleController', 'PhabricatorPeopleProfileController' => 'PhabricatorPeopleController', 'PhabricatorPeopleQuery' => 'PhabricatorOffsetPagedQuery', + 'PhabricatorPinboardItemView' => 'AphrontView', + 'PhabricatorPinboardView' => 'AphrontView', 'PhabricatorPolicies' => 'PhabricatorPolicyConstants', 'PhabricatorPolicyAwareQuery' => 'PhabricatorOffsetPagedQuery', 'PhabricatorPolicyAwareTestQuery' => 'PhabricatorPolicyAwareQuery', diff --git a/src/applications/macro/controller/PhabricatorMacroListController.php b/src/applications/macro/controller/PhabricatorMacroListController.php index c516a3dd09..3cb522f227 100644 --- a/src/applications/macro/controller/PhabricatorMacroListController.php +++ b/src/applications/macro/controller/PhabricatorMacroListController.php @@ -22,12 +22,19 @@ final class PhabricatorMacroListController public function processRequest() { $request = $this->getRequest(); + $viewer = $request->getUser(); $macro_table = new PhabricatorFileImageMacro(); - if ($request->getStr('name') !== null) { + + $filter = $request->getStr('name'); + if (strlen($filter)) { $macros = $macro_table->loadAllWhere( 'name LIKE %~', - $request->getStr('name')); + $filter); + + $nodata = pht( + 'There are no macros matching the filter "%s".', + phutil_escape_html($filter)); } else { $pager = new AphrontPagerView(); $pager->setOffset($request->getInt('page')); @@ -47,6 +54,8 @@ final class PhabricatorMacroListController $pager->setCount($count); $pager->setURI($request->getRequestURI(), 'page'); + + $nodata = pht('There are no image macros yet.'); } $file_phids = mpull($macros, 'getFilePHID'); @@ -57,66 +66,11 @@ final class PhabricatorMacroListController "phid IN (%Ls)", $file_phids); $author_phids = mpull($files, 'getAuthorPHID', 'getPHID'); - $handles = $this->loadViewerHandles($author_phids); + + $this->loadHandles($author_phids); } $files_map = mpull($files, null, 'getPHID'); - $rows = array(); - foreach ($macros as $macro) { - $file_phid = $macro->getFilePHID(); - $file = idx($files_map, $file_phid); - - $author_link = isset($author_phids[$file_phid]) - ? $handles[$author_phids[$file_phid]]->renderLink() - : null; - - $rows[] = array( - phutil_render_tag( - 'a', - array( - 'href' => $this->getApplicationURI('/edit/'.$macro->getID().'/'), - ), - phutil_escape_html($macro->getName())), - - $author_link, - phutil_render_tag( - 'a', - array( - 'href' => $file ? $file->getBestURI() : null, - 'target' => '_blank', - ), - phutil_render_tag( - 'img', - array( - 'src' => $file ? $file->getBestURI() : null, - ))), - javelin_render_tag( - 'a', - array( - 'href' => $this->getApplicationURI('/delete/'.$macro->getID().'/'), - 'sigil' => 'workflow', - 'class' => 'grey small button', - ), - 'Delete'), - ); - } - - $table = new AphrontTableView($rows); - $table->setHeaders( - array( - 'Name', - 'Author', - 'Image', - '', - )); - $table->setColumnClasses( - array( - 'pri', - '', - 'wide thumb', - 'action', - )); - $filter_form = id(new AphrontFormView()) ->setMethod('GET') ->setUser($request->getUser()) @@ -124,7 +78,7 @@ final class PhabricatorMacroListController id(new AphrontFormTextControl()) ->setName('name') ->setLabel('Name') - ->setValue($request->getStr('name'))) + ->setValue($filter)) ->appendChild( id(new AphrontFormSubmitControl()) ->setValue('Filter Image Macros')); @@ -132,22 +86,55 @@ final class PhabricatorMacroListController $filter_view = new AphrontListFilterView(); $filter_view->appendChild($filter_form); - $panel = new AphrontPanelView(); - $panel->appendChild($table); - $panel->setHeader('Image Macros'); - if ($request->getStr('name') === null) { - $panel->appendChild($pager); - } - $nav = $this->buildSideNavView(); $nav->selectFilter('/'); $nav->appendChild($filter_view); - $nav->appendChild($panel); + + + if ($macros) { + $pinboard = new PhabricatorPinboardView(); + foreach ($macros as $macro) { + $file_phid = $macro->getFilePHID(); + $file = idx($files_map, $file_phid); + + $item = new PhabricatorPinboardItemView(); + $item->setImageURI($file->getThumb160x120URI()); + $item->setImageSize(160, 120); + $item->setURI($this->getApplicationURI('/edit/'.$macro->getID().'/')); + $item->setHeader($macro->getName()); + + if ($file->getAuthorPHID()) { + $author_handle = $this->getHandle($file->getAuthorPHID()); + $item->appendChild( + 'Created by '.$author_handle->renderLink()); + } + + $datetime = phabricator_date($file->getDateCreated(), $viewer); + $item->appendChild( + phutil_render_tag( + 'div', + array(), + 'Created on '.$datetime)); + + $pinboard->addItem($item); + } + $nav->appendChild($pinboard); + } else { + $list = new PhabricatorObjectItemListView(); + $list->setNoDataString($nodata); + $nav->appendChild($list); + } + + + if ($filter === null) { + $nav->appendChild($pager); + } return $this->buildApplicationPage( $nav, array( + 'device' => true, 'title' => 'Image Macros', )); } diff --git a/src/view/layout/PhabricatorPinboardItemView.php b/src/view/layout/PhabricatorPinboardItemView.php new file mode 100644 index 0000000000..f3325c4fc0 --- /dev/null +++ b/src/view/layout/PhabricatorPinboardItemView.php @@ -0,0 +1,93 @@ +header = $header; + return $this; + } + + public function setURI($uri) { + $this->uri = $uri; + return $this; + } + + public function setImageURI($image_uri) { + $this->imageURI = $image_uri; + return $this; + } + + public function setImageSize($x, $y) { + $this->imageWidth = $x; + $this->imageHeight = $y; + return $this; + } + + public function render() { + $header = null; + if ($this->header) { + $header = phutil_render_tag( + 'a', + array( + 'href' => $this->uri, + 'class' => 'phabricator-pinboard-item-header', + ), + phutil_escape_html($this->header)); + } + + $image = phutil_render_tag( + 'a', + array( + 'href' => $this->uri, + 'class' => 'phabricator-pinboard-item-image-link', + ), + phutil_render_tag( + 'img', + array( + 'src' => $this->imageURI, + 'width' => $this->imageWidth, + 'height' => $this->imageHeight, + ))); + + $content = $this->renderChildren(); + if ($content) { + $content = phutil_render_tag( + 'div', + array( + 'class' => 'phabricator-pinboard-item-content', + ), + $content); + } + + return phutil_render_tag( + 'div', + array( + 'class' => 'phabricator-pinboard-item-view', + ), + $header. + $image. + $content); + } + +} diff --git a/src/view/layout/PhabricatorPinboardView.php b/src/view/layout/PhabricatorPinboardView.php new file mode 100644 index 0000000000..3848f6a54d --- /dev/null +++ b/src/view/layout/PhabricatorPinboardView.php @@ -0,0 +1,39 @@ +items[] = $item; + return $this; + } + + public function render() { + require_celerity_resource('phabricator-pinboard-view-css'); + + return phutil_render_tag( + 'div', + array( + 'class' => 'phabricator-pinboard-view', + ), + $this->renderSingleView($this->items)); + } + +} diff --git a/webroot/rsrc/css/layout/phabricator-pinboard-view.css b/webroot/rsrc/css/layout/phabricator-pinboard-view.css new file mode 100644 index 0000000000..1ea96ca423 --- /dev/null +++ b/webroot/rsrc/css/layout/phabricator-pinboard-view.css @@ -0,0 +1,53 @@ +/** + * @provides phabricator-pinboard-view-css + */ + +.phabricator-pinboard-view { + padding: 0 2%; + overflow: hidden; +} + +.device-phone .phabricator-pinboard-view { + padding: 0; +} + +.phabricator-pinboard-item-view { + margin: 0 10px 20px; + border: 1px solid #aaaaaa; + background: #ffffff; + + display: block; + float: left; + box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.15); + text-align: left; +} + + +/* On phones, show a single column of items. */ +.device-phone .phabricator-pinboard-item-view { + float: none; + margin: 0 auto 20px; + + /* NOTE: This needs to be changed if we use images other than 160px wide. */ + width: 200px; +} + +.phabricator-pinboard-item-header { + padding: 5px 20px; + display: block; + background: #f3f3f3; + font-weight: bold; +} + +.phabricator-pinboard-item-image-link { + padding: 20px; + display: block; +} + +.phabricator-pinboard-item-content { + padding: 5px 20px; + overflow: hidden; + background: #f3f3f3; + color: #666666; + font-size: smaller; +}