diff --git a/src/applications/countdown/application/PhabricatorCountdownApplication.php b/src/applications/countdown/application/PhabricatorCountdownApplication.php index 14ef34d2cb..5daaa5021f 100644 --- a/src/applications/countdown/application/PhabricatorCountdownApplication.php +++ b/src/applications/countdown/application/PhabricatorCountdownApplication.php @@ -1,72 +1,74 @@ [1-9]\d*)' => 'PhabricatorCountdownViewController', '/countdown/' => array( '(?:query/(?P[^/]+)/)?' => 'PhabricatorCountdownListController', '(?P[1-9]\d*)/' => 'PhabricatorCountdownViewController', 'comment/(?P[1-9]\d*)/' => 'PhabricatorCountdownCommentController', 'edit/(?:(?P[1-9]\d*)/)?' => 'PhabricatorCountdownEditController', + 'create/' + => 'PhabricatorCountdownEditController', 'delete/(?P[1-9]\d*)/' => 'PhabricatorCountdownDeleteController', ), ); } protected function getCustomCapabilities() { return array( PhabricatorCountdownDefaultViewCapability::CAPABILITY => array( 'caption' => pht('Default view policy for new countdowns.'), 'template' => PhabricatorCountdownCountdownPHIDType::TYPECONST, 'capability' => PhabricatorPolicyCapability::CAN_VIEW, ), PhabricatorCountdownDefaultEditCapability::CAPABILITY => array( 'caption' => pht('Default edit policy for new countdowns.'), 'template' => PhabricatorCountdownCountdownPHIDType::TYPECONST, 'capability' => PhabricatorPolicyCapability::CAN_EDIT, ), ); } } diff --git a/src/applications/countdown/controller/PhabricatorCountdownController.php b/src/applications/countdown/controller/PhabricatorCountdownController.php index e22ce95a47..37b0e49a68 100644 --- a/src/applications/countdown/controller/PhabricatorCountdownController.php +++ b/src/applications/countdown/controller/PhabricatorCountdownController.php @@ -1,22 +1,22 @@ newApplicationMenu() ->setSearchEngine(new PhabricatorCountdownSearchEngine()); } protected function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); $crumbs->addAction( id(new PHUIListItemView()) ->setName(pht('Create Countdown')) - ->setHref($this->getApplicationURI('edit/')) + ->setHref($this->getApplicationURI('create/')) ->setIcon('fa-plus-square')); return $crumbs; } } diff --git a/src/applications/countdown/query/PhabricatorCountdownSearchEngine.php b/src/applications/countdown/query/PhabricatorCountdownSearchEngine.php index b9f438ece8..ae90e5f3e7 100644 --- a/src/applications/countdown/query/PhabricatorCountdownSearchEngine.php +++ b/src/applications/countdown/query/PhabricatorCountdownSearchEngine.php @@ -1,148 +1,168 @@ newQuery(); if ($map['authorPHIDs']) { $query->withAuthorPHIDs($map['authorPHIDs']); } if ($map['upcoming'] && $map['upcoming'][0] == 'upcoming') { $query->withUpcoming(); } return $query; } protected function buildCustomSearchFields() { return array( id(new PhabricatorUsersSearchField()) ->setLabel(pht('Authors')) ->setKey('authorPHIDs') ->setAliases(array('author', 'authors')), id(new PhabricatorSearchCheckboxesField()) ->setKey('upcoming') ->setOptions(array( 'upcoming' => pht('Show only upcoming countdowns.'), )), ); } protected function getURI($path) { return '/countdown/'.$path; } protected function getBuiltinQueryNames() { $names = array( 'upcoming' => pht('Upcoming'), 'all' => pht('All'), ); if ($this->requireViewer()->getPHID()) { $names['authored'] = pht('Authored'); } return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; case 'authored': return $query->setParameter( 'authorPHIDs', array($this->requireViewer()->getPHID())); case 'upcoming': return $query->setParameter('upcoming', array('upcoming')); } return parent::buildSavedQueryFromBuiltin($query_key); } protected function getRequiredHandlePHIDsForResultList( array $countdowns, PhabricatorSavedQuery $query) { return mpull($countdowns, 'getAuthorPHID'); } protected function renderResultList( array $countdowns, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($countdowns, 'PhabricatorCountdown'); $viewer = $this->requireViewer(); $list = new PHUIObjectItemListView(); $list->setUser($viewer); foreach ($countdowns as $countdown) { $id = $countdown->getID(); $ended = false; $epoch = $countdown->getEpoch(); if ($epoch <= PhabricatorTime::getNow()) { $ended = true; } $item = id(new PHUIObjectItemView()) ->setUser($viewer) ->setObject($countdown) ->setObjectName("C{$id}") ->setHeader($countdown->getTitle()) ->setHref($this->getApplicationURI("{$id}/")) ->addByline( pht( 'Created by %s', $handles[$countdown->getAuthorPHID()]->renderLink())); if ($ended) { $item->addAttribute( pht('Launched on %s', phabricator_datetime($epoch, $viewer))); $item->setDisabled(true); } else { $time_left = ($epoch - PhabricatorTime::getNow()); $num = round($time_left / (60 * 60 * 24)); $noun = pht('Days'); if ($num < 1) { $num = round($time_left / (60 * 60), 1); $noun = pht('Hours'); } $item->setCountdown($num, $noun); $item->addAttribute( phabricator_datetime($epoch, $viewer)); } $list->addItem($item); } $result = new PhabricatorApplicationSearchResultView(); $result->setObjectList($list); $result->setNoDataString(pht('No countdowns found.')); return $result; } + protected function getNewUserBody() { + $create_button = id(new PHUIButtonView()) + ->setTag('a') + ->setText(pht('Create a Countdown')) + ->setHref('/countdown/create/') + ->setColor(PHUIButtonView::GREEN); + + $icon = $this->getApplication()->getFontIcon(); + $app_name = $this->getApplication()->getName(); + $view = id(new PHUIBigInfoView()) + ->setIcon($icon) + ->setTitle(pht('Welcome to %s', $app_name)) + ->setDescription( + pht('Keep track of upcoming launch dates with '. + 'embeddable counters.')) + ->addAction($create_button); + + return $view; + } + } diff --git a/src/applications/macro/query/PhabricatorMacroSearchEngine.php b/src/applications/macro/query/PhabricatorMacroSearchEngine.php index 039f396d5f..1619f8185a 100644 --- a/src/applications/macro/query/PhabricatorMacroSearchEngine.php +++ b/src/applications/macro/query/PhabricatorMacroSearchEngine.php @@ -1,192 +1,211 @@ needFiles(true); } protected function buildCustomSearchFields() { return array( id(new PhabricatorSearchSelectField()) ->setLabel(pht('Status')) ->setKey('status') ->setOptions(PhabricatorMacroQuery::getStatusOptions()), id(new PhabricatorUsersSearchField()) ->setLabel(pht('Authors')) ->setKey('authorPHIDs') ->setAliases(array('author', 'authors')), id(new PhabricatorSearchTextField()) ->setLabel(pht('Name Contains')) ->setKey('nameLike'), id(new PhabricatorSearchStringListField()) ->setLabel(pht('Exact Names')) ->setKey('names'), id(new PhabricatorSearchSelectField()) ->setLabel(pht('Marked with Flag')) ->setKey('flagColor') ->setDefault('-1') ->setOptions(PhabricatorMacroQuery::getFlagColorsOptions()), id(new PhabricatorSearchDateField()) ->setLabel(pht('Created After')) ->setKey('createdStart'), id(new PhabricatorSearchDateField()) ->setLabel(pht('Created Before')) ->setKey('createdEnd'), ); } protected function getDefaultFieldOrder() { return array( '...', 'createdStart', 'createdEnd', ); } protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); if ($map['authorPHIDs']) { $query->withAuthorPHIDs($map['authorPHIDs']); } if ($map['status']) { $query->withStatus($map['status']); } if ($map['names']) { $query->withNames($map['names']); } if (strlen($map['nameLike'])) { $query->withNameLike($map['nameLike']); } if ($map['createdStart']) { $query->withDateCreatedAfter($map['createdStart']); } if ($map['createdEnd']) { $query->withDateCreatedBefore($map['createdEnd']); } if ($map['flagColor'] !== null) { $query->withFlagColor($map['flagColor']); } return $query; } protected function getURI($path) { return '/macro/'.$path; } protected function getBuiltinQueryNames() { $names = array( 'active' => pht('Active'), 'all' => pht('All'), ); if ($this->requireViewer()->isLoggedIn()) { $names['authored'] = pht('Authored'); } return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'active': return $query->setParameter( 'status', PhabricatorMacroQuery::STATUS_ACTIVE); case 'all': return $query->setParameter( 'status', PhabricatorMacroQuery::STATUS_ANY); case 'authored': return $query->setParameter( 'authorPHIDs', array($this->requireViewer()->getPHID())); } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $macros, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($macros, 'PhabricatorFileImageMacro'); $viewer = $this->requireViewer(); $handles = $viewer->loadHandles(mpull($macros, 'getAuthorPHID')); $xform = PhabricatorFileTransform::getTransformByKey( PhabricatorFileThumbnailTransform::TRANSFORM_PINBOARD); $pinboard = new PHUIPinboardView(); foreach ($macros as $macro) { $file = $macro->getFile(); $item = id(new PHUIPinboardItemView()) ->setUser($viewer) ->setObject($macro); if ($file) { $item->setImageURI($file->getURIForTransform($xform)); list($x, $y) = $xform->getTransformedDimensions($file); $item->setImageSize($x, $y); } if ($macro->getDateCreated()) { $datetime = phabricator_date($macro->getDateCreated(), $viewer); $item->appendChild( phutil_tag( 'div', array(), pht('Created on %s', $datetime))); } else { // Very old macros don't have a creation date. Rendering something // keeps all the pins at the same height and avoids flow issues. $item->appendChild( phutil_tag( 'div', array(), pht('Created in ages long past'))); } if ($macro->getAuthorPHID()) { $author_handle = $handles[$macro->getAuthorPHID()]; $item->appendChild( pht('Created by %s', $author_handle->renderLink())); } $item->setURI($this->getApplicationURI('/view/'.$macro->getID().'/')); $item->setDisabled($macro->getisDisabled()); $item->setHeader($macro->getName()); $pinboard->addItem($item); } $result = new PhabricatorApplicationSearchResultView(); $result->setContent($pinboard); return $result; } + protected function getNewUserBody() { + $create_button = id(new PHUIButtonView()) + ->setTag('a') + ->setText(pht('Create a Macro')) + ->setHref('/macro/create/') + ->setColor(PHUIButtonView::GREEN); + + $icon = $this->getApplication()->getFontIcon(); + $app_name = $this->getApplication()->getName(); + $view = id(new PHUIBigInfoView()) + ->setIcon($icon) + ->setTitle(pht('Welcome to %s', $app_name)) + ->setDescription( + pht('Create easy to remember shortcuts to images and memes.')) + ->addAction($create_button); + + return $view; + } + } diff --git a/src/applications/paste/query/PhabricatorPasteSearchEngine.php b/src/applications/paste/query/PhabricatorPasteSearchEngine.php index 38aaface64..fdf7824f07 100644 --- a/src/applications/paste/query/PhabricatorPasteSearchEngine.php +++ b/src/applications/paste/query/PhabricatorPasteSearchEngine.php @@ -1,205 +1,224 @@ needSnippets(true); } protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); if ($map['authorPHIDs']) { $query->withAuthorPHIDs($map['authorPHIDs']); } if ($map['languages']) { $query->withLanguages($map['languages']); } if ($map['createdStart']) { $query->withDateCreatedAfter($map['createdStart']); } if ($map['createdEnd']) { $query->withDateCreatedBefore($map['createdEnd']); } if ($map['statuses']) { $query->withStatuses($map['statuses']); } return $query; } protected function buildCustomSearchFields() { return array( id(new PhabricatorUsersSearchField()) ->setAliases(array('authors')) ->setKey('authorPHIDs') ->setConduitKey('authors') ->setLabel(pht('Authors')) ->setDescription( pht('Search for pastes with specific authors.')), id(new PhabricatorSearchStringListField()) ->setKey('languages') ->setLabel(pht('Languages')) ->setDescription( pht('Search for pastes highlighted in specific languages.')), id(new PhabricatorSearchDateField()) ->setKey('createdStart') ->setLabel(pht('Created After')) ->setDescription( pht('Search for pastes created after a given time.')), id(new PhabricatorSearchDateField()) ->setKey('createdEnd') ->setLabel(pht('Created Before')) ->setDescription( pht('Search for pastes created before a given time.')), id(new PhabricatorSearchCheckboxesField()) ->setKey('statuses') ->setLabel(pht('Status')) ->setDescription( pht('Search for archived or active pastes.')) ->setOptions( id(new PhabricatorPaste()) ->getStatusNameMap()), ); } protected function getDefaultFieldOrder() { return array( '...', 'createdStart', 'createdEnd', ); } protected function getURI($path) { return '/paste/'.$path; } protected function getBuiltinQueryNames() { $names = array( 'active' => pht('Active Pastes'), 'all' => pht('All Pastes'), ); if ($this->requireViewer()->isLoggedIn()) { $names['authored'] = pht('Authored'); } return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'active': return $query->setParameter( 'statuses', array( PhabricatorPaste::STATUS_ACTIVE, )); case 'all': return $query; case 'authored': return $query->setParameter( 'authorPHIDs', array($this->requireViewer()->getPHID())); } return parent::buildSavedQueryFromBuiltin($query_key); } protected function getRequiredHandlePHIDsForResultList( array $pastes, PhabricatorSavedQuery $query) { return mpull($pastes, 'getAuthorPHID'); } protected function renderResultList( array $pastes, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($pastes, 'PhabricatorPaste'); $viewer = $this->requireViewer(); $lang_map = PhabricatorEnv::getEnvConfig('pygments.dropdown-choices'); $list = new PHUIObjectItemListView(); $list->setUser($viewer); foreach ($pastes as $paste) { $created = phabricator_date($paste->getDateCreated(), $viewer); $author = $handles[$paste->getAuthorPHID()]->renderLink(); $snippet_type = $paste->getSnippet()->getType(); $lines = phutil_split_lines($paste->getSnippet()->getContent()); $preview = id(new PhabricatorSourceCodeView()) ->setLines($lines) ->setTruncatedFirstBytes( $snippet_type == PhabricatorPasteSnippet::FIRST_BYTES) ->setTruncatedFirstLines( $snippet_type == PhabricatorPasteSnippet::FIRST_LINES) ->setURI(new PhutilURI($paste->getURI())); $source_code = phutil_tag( 'div', array( 'class' => 'phabricator-source-code-summary', ), $preview); $created = phabricator_datetime($paste->getDateCreated(), $viewer); $line_count = count($lines); $line_count = pht( '%s Line(s)', new PhutilNumber($line_count)); $title = nonempty($paste->getTitle(), pht('(An Untitled Masterwork)')); $item = id(new PHUIObjectItemView()) ->setObjectName('P'.$paste->getID()) ->setHeader($title) ->setHref('/P'.$paste->getID()) ->setObject($paste) ->addByline(pht('Author: %s', $author)) ->addIcon('none', $created) ->addIcon('none', $line_count) ->appendChild($source_code); if ($paste->isArchived()) { $item->setDisabled(true); } $lang_name = $paste->getLanguage(); if ($lang_name) { $lang_name = idx($lang_map, $lang_name, $lang_name); $item->addIcon('none', $lang_name); } $list->addItem($item); } $result = new PhabricatorApplicationSearchResultView(); $result->setObjectList($list); $result->setNoDataString(pht('No pastes found.')); return $result; } + + protected function getNewUserBody() { + $create_button = id(new PHUIButtonView()) + ->setTag('a') + ->setText(pht('Create a Paste')) + ->setHref('/paste/create/') + ->setColor(PHUIButtonView::GREEN); + + $icon = $this->getApplication()->getFontIcon(); + $app_name = $this->getApplication()->getName(); + $view = id(new PHUIBigInfoView()) + ->setIcon($icon) + ->setTitle(pht('Welcome to %s', $app_name)) + ->setDescription( + pht('Store, share, and embed snippets of code.')) + ->addAction($create_button); + + return $view; + } } diff --git a/src/applications/pholio/application/PhabricatorPholioApplication.php b/src/applications/pholio/application/PhabricatorPholioApplication.php index 2ed1dff750..16b868b9a1 100644 --- a/src/applications/pholio/application/PhabricatorPholioApplication.php +++ b/src/applications/pholio/application/PhabricatorPholioApplication.php @@ -1,105 +1,106 @@ [1-9]\d*)(?:/(?P\d+)/)?' => 'PholioMockViewController', '/pholio/' => array( '(?:query/(?P[^/]+)/)?' => 'PholioMockListController', 'new/' => 'PholioMockEditController', + 'create/' => 'PholioMockEditController', 'edit/(?P\d+)/' => 'PholioMockEditController', 'archive/(?P\d+)/' => 'PholioMockArchiveController', 'comment/(?P\d+)/' => 'PholioMockCommentController', 'inline/' => array( '(?:(?P\d+)/)?' => 'PholioInlineController', 'list/(?P\d+)/' => 'PholioInlineListController', ), 'image/' => array( 'upload/' => 'PholioImageUploadController', ), ), ); } public function getQuickCreateItems(PhabricatorUser $viewer) { $items = array(); $item = id(new PHUIListItemView()) ->setName(pht('Pholio Mock')) ->setIcon('fa-picture-o') - ->setHref($this->getBaseURI().'new/'); + ->setHref($this->getBaseURI().'create/'); $items[] = $item; return $items; } protected function getCustomCapabilities() { return array( PholioDefaultViewCapability::CAPABILITY => array( 'template' => PholioMockPHIDType::TYPECONST, 'capability' => PhabricatorPolicyCapability::CAN_VIEW, ), PholioDefaultEditCapability::CAPABILITY => array( 'template' => PholioMockPHIDType::TYPECONST, 'capability' => PhabricatorPolicyCapability::CAN_EDIT, ), ); } public function getMailCommandObjects() { return array( 'mock' => array( 'name' => pht('Email Commands: Mocks'), 'header' => pht('Interacting with Pholio Mocks'), 'object' => new PholioMock(), 'summary' => pht( 'This page documents the commands you can use to interact with '. 'mocks in Pholio.'), ), ); } public function getApplicationSearchDocumentTypes() { return array( PholioMockPHIDType::TYPECONST, ); } } diff --git a/src/applications/pholio/controller/PholioController.php b/src/applications/pholio/controller/PholioController.php index 533945c7c3..99a73e8933 100644 --- a/src/applications/pholio/controller/PholioController.php +++ b/src/applications/pholio/controller/PholioController.php @@ -1,22 +1,22 @@ newApplicationMenu() ->setSearchEngine(new PholioMockSearchEngine()); } protected function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); $crumbs->addAction( id(new PHUIListItemView()) ->setName(pht('Create Mock')) - ->setHref($this->getApplicationURI('new/')) + ->setHref($this->getApplicationURI('create/')) ->setIcon('fa-plus-square')); return $crumbs; } } diff --git a/src/applications/pholio/query/PholioMockSearchEngine.php b/src/applications/pholio/query/PholioMockSearchEngine.php index 05f0d08923..3c9d0b0d6b 100644 --- a/src/applications/pholio/query/PholioMockSearchEngine.php +++ b/src/applications/pholio/query/PholioMockSearchEngine.php @@ -1,133 +1,153 @@ needCoverFiles(true) ->needImages(true) ->needTokenCounts(true); } protected function buildCustomSearchFields() { return array( id(new PhabricatorUsersSearchField()) ->setKey('authorPHIDs') ->setAliases(array('authors')) ->setLabel(pht('Authors')), id(new PhabricatorSearchCheckboxesField()) ->setKey('statuses') ->setLabel(pht('Status')) ->setOptions( id(new PholioMock()) ->getStatuses()), ); } protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); if ($map['authorPHIDs']) { $query->withAuthorPHIDs($map['authorPHIDs']); } if ($map['statuses']) { $query->withStatuses($map['statuses']); } return $query; } protected function getURI($path) { return '/pholio/'.$path; } protected function getBuiltinQueryNames() { $names = array( 'open' => pht('Open Mocks'), 'all' => pht('All Mocks'), ); if ($this->requireViewer()->isLoggedIn()) { $names['authored'] = pht('Authored'); } return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'open': return $query->setParameter( 'statuses', array('open')); case 'all': return $query; case 'authored': return $query->setParameter( 'authorPHIDs', array($this->requireViewer()->getPHID())); } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $mocks, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($mocks, 'PholioMock'); $viewer = $this->requireViewer(); $handles = $viewer->loadHandles(mpull($mocks, 'getAuthorPHID')); $xform = PhabricatorFileTransform::getTransformByKey( PhabricatorFileThumbnailTransform::TRANSFORM_PINBOARD); $board = new PHUIPinboardView(); foreach ($mocks as $mock) { $image = $mock->getCoverFile(); $image_uri = $image->getURIForTransform($xform); list($x, $y) = $xform->getTransformedDimensions($image); $header = 'M'.$mock->getID().' '.$mock->getName(); $item = id(new PHUIPinboardItemView()) ->setUser($viewer) ->setHeader($header) ->setObject($mock) ->setURI('/M'.$mock->getID()) ->setImageURI($image_uri) ->setImageSize($x, $y) ->setDisabled($mock->isClosed()) ->addIconCount('fa-picture-o', count($mock->getImages())) ->addIconCount('fa-trophy', $mock->getTokenCount()); if ($mock->getAuthorPHID()) { $author_handle = $handles[$mock->getAuthorPHID()]; $datetime = phabricator_date($mock->getDateCreated(), $viewer); $item->appendChild( pht('By %s on %s', $author_handle->renderLink(), $datetime)); } $board->addItem($item); } $result = new PhabricatorApplicationSearchResultView(); $result->setContent($board); return $result; } + protected function getNewUserBody() { + $create_button = id(new PHUIButtonView()) + ->setTag('a') + ->setText(pht('Create a Mock')) + ->setHref('/pholio/create/') + ->setColor(PHUIButtonView::GREEN); + + $icon = $this->getApplication()->getFontIcon(); + $app_name = $this->getApplication()->getName(); + $view = id(new PHUIBigInfoView()) + ->setIcon($icon) + ->setTitle(pht('Welcome to %s', $app_name)) + ->setDescription( + pht('Upload sets of images for review with revision history and '. + 'inline comments.')) + ->addAction($create_button); + + return $view; + } + } diff --git a/src/applications/phurl/query/PhabricatorPhurlURLSearchEngine.php b/src/applications/phurl/query/PhabricatorPhurlURLSearchEngine.php index 545643b6ae..ed8a336c3a 100644 --- a/src/applications/phurl/query/PhabricatorPhurlURLSearchEngine.php +++ b/src/applications/phurl/query/PhabricatorPhurlURLSearchEngine.php @@ -1,94 +1,113 @@ setLabel(pht('Created By')) ->setKey('authorPHIDs') ->setDatasource(new PhabricatorPeopleUserFunctionDatasource()), ); } protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); if ($map['authorPHIDs']) { $query->withAuthorPHIDs($map['authorPHIDs']); } return $query; } protected function getURI($path) { return '/phurl/'.$path; } protected function getBuiltinQueryNames() { $names = array( 'authored' => pht('Authored'), 'all' => pht('All URLs'), ); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); $viewer = $this->requireViewer(); switch ($query_key) { case 'authored': return $query->setParameter('authorPHIDs', array($viewer->getPHID())); case 'all': return $query; } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $urls, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($urls, 'PhabricatorPhurlURL'); $viewer = $this->requireViewer(); $list = new PHUIObjectItemListView(); $handles = $viewer->loadHandles(mpull($urls, 'getAuthorPHID')); foreach ($urls as $url) { $item = id(new PHUIObjectItemView()) ->setUser($viewer) ->setObject($url) ->setHeader($viewer->renderHandle($url->getPHID())); $list->addItem($item); } $result = new PhabricatorApplicationSearchResultView(); $result->setObjectList($list); $result->setNoDataString(pht('No URLs found.')); return $result; } + + protected function getNewUserBody() { + $create_button = id(new PHUIButtonView()) + ->setTag('a') + ->setText(pht('Shorten a URL')) + ->setHref('/phurl/url/create/') + ->setColor(PHUIButtonView::GREEN); + + $icon = $this->getApplication()->getFontIcon(); + $app_name = $this->getApplication()->getName(); + $view = id(new PHUIBigInfoView()) + ->setIcon($icon) + ->setTitle(pht('Welcome to %s', $app_name)) + ->setDescription( + pht('Create reusable, memorable, shorter URLs for easy accessibility.')) + ->addAction($create_button); + + return $view; + } } diff --git a/src/applications/ponder/query/PonderQuestionSearchEngine.php b/src/applications/ponder/query/PonderQuestionSearchEngine.php index c16c5442db..7e08a3fdf4 100644 --- a/src/applications/ponder/query/PonderQuestionSearchEngine.php +++ b/src/applications/ponder/query/PonderQuestionSearchEngine.php @@ -1,183 +1,202 @@ needProjectPHIDs(true); } protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); if ($map['authorPHIDs']) { $query->withAuthorPHIDs($map['authorPHIDs']); } if ($map['answerers']) { $query->withAnswererPHIDs($map['answerers']); } if ($map['statuses']) { $query->withStatuses($map['statuses']); } return $query; } protected function buildCustomSearchFields() { return array( id(new PhabricatorUsersSearchField()) ->setKey('authorPHIDs') ->setAliases(array('authors')) ->setLabel(pht('Authors')), id(new PhabricatorUsersSearchField()) ->setKey('answerers') ->setAliases(array('answerers')) ->setLabel(pht('Answered By')), id(new PhabricatorSearchCheckboxesField()) ->setLabel(pht('Status')) ->setKey('statuses') ->setOptions(PonderQuestionStatus::getQuestionStatusMap()), ); } protected function getURI($path) { return '/ponder/'.$path; } protected function getBuiltinQueryNames() { $names = array( 'recent' => pht('Recent Questions'), 'open' => pht('Open Questions'), 'resolved' => pht('Resolved Questions'), 'all' => pht('All Questions'), ); if ($this->requireViewer()->isLoggedIn()) { $names['authored'] = pht('Authored'); $names['answered'] = pht('Answered'); } return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; case 'open': return $query->setParameter( 'statuses', array(PonderQuestionStatus::STATUS_OPEN)); case 'recent': return $query->setParameter( 'statuses', array( PonderQuestionStatus::STATUS_OPEN, PonderQuestionStatus::STATUS_CLOSED_RESOLVED, )); case 'resolved': return $query->setParameter( 'statuses', array(PonderQuestionStatus::STATUS_CLOSED_RESOLVED)); case 'authored': return $query->setParameter( 'authorPHIDs', array($this->requireViewer()->getPHID())); case 'answered': return $query->setParameter( 'answerers', array($this->requireViewer()->getPHID())); } return parent::buildSavedQueryFromBuiltin($query_key); } protected function getRequiredHandlePHIDsForResultList( array $questions, PhabricatorSavedQuery $query) { return mpull($questions, 'getAuthorPHID'); } protected function renderResultList( array $questions, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($questions, 'PonderQuestion'); $viewer = $this->requireViewer(); $proj_phids = array(); foreach ($questions as $question) { foreach ($question->getProjectPHIDs() as $project_phid) { $proj_phids[] = $project_phid; } } $proj_handles = id(new PhabricatorHandleQuery()) ->setViewer($viewer) ->withPHIDs($proj_phids) ->execute(); $view = id(new PHUIObjectItemListView()) ->setUser($viewer); foreach ($questions as $question) { $color = PonderQuestionStatus::getQuestionStatusTagColor( $question->getStatus()); $icon = PonderQuestionStatus::getQuestionStatusIcon( $question->getStatus()); $full_status = PonderQuestionStatus::getQuestionStatusFullName( $question->getStatus()); $item = new PHUIObjectItemView(); $item->setObjectName('Q'.$question->getID()); $item->setHeader($question->getTitle()); $item->setHref('/Q'.$question->getID()); $item->setObject($question); $item->setStatusIcon($icon.' '.$color, $full_status); $project_handles = array_select_keys( $proj_handles, $question->getProjectPHIDs()); $created_date = phabricator_date($question->getDateCreated(), $viewer); $item->addIcon('none', $created_date); $item->addByline( pht( 'Asked by %s', $handles[$question->getAuthorPHID()]->renderLink())); $item->addAttribute( pht( '%s Answer(s)', new PhutilNumber($question->getAnswerCount()))); if ($project_handles) { $item->addAttribute( id(new PHUIHandleTagListView()) ->setLimit(4) ->setSlim(true) ->setHandles($project_handles)); } $view->addItem($item); } $result = new PhabricatorApplicationSearchResultView(); $result->setObjectList($view); $result->setNoDataString(pht('No questions found.')); return $result; } + protected function getNewUserBody() { + $create_button = id(new PHUIButtonView()) + ->setTag('a') + ->setText(pht('Ask a Question')) + ->setHref('/ponder/question/create/') + ->setColor(PHUIButtonView::GREEN); + + $icon = $this->getApplication()->getFontIcon(); + $app_name = $this->getApplication()->getName(); + $view = id(new PHUIBigInfoView()) + ->setIcon($icon) + ->setTitle(pht('Welcome to %s', $app_name)) + ->setDescription( + pht('A simple questions and answers application for your teams.')) + ->addAction($create_button); + + return $view; + } + } diff --git a/src/applications/slowvote/query/PhabricatorSlowvoteSearchEngine.php b/src/applications/slowvote/query/PhabricatorSlowvoteSearchEngine.php index 6605bc9ecc..d38683ee06 100644 --- a/src/applications/slowvote/query/PhabricatorSlowvoteSearchEngine.php +++ b/src/applications/slowvote/query/PhabricatorSlowvoteSearchEngine.php @@ -1,166 +1,185 @@ newQuery(); if ($map['voted']) { $query->withVotesByViewer(true); } if ($map['authorPHIDs']) { $query->withAuthorPHIDs($map['authorPHIDs']); } $statuses = $map['statuses']; if (count($statuses) == 1) { $status = head($statuses); if ($status == 'open') { $query->withIsClosed(false); } else { $query->withIsClosed(true); } } return $query; } protected function buildCustomSearchFields() { return array( id(new PhabricatorUsersSearchField()) ->setKey('authorPHIDs') ->setAliases(array('authors')) ->setLabel(pht('Authors')), id(new PhabricatorSearchCheckboxesField()) ->setKey('voted') ->setOptions(array( 'voted' => pht("Show only polls I've voted in."), )), id(new PhabricatorSearchCheckboxesField()) ->setKey('statuses') ->setOptions(array( 'open' => pht('Open'), 'closed' => pht('Closed'), )), ); } protected function getURI($path) { return '/vote/'.$path; } protected function getBuiltinQueryNames() { $names = array( 'open' => pht('Open Polls'), 'all' => pht('All Polls'), ); if ($this->requireViewer()->isLoggedIn()) { $names['authored'] = pht('Authored'); $names['voted'] = pht('Voted In'); } return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'open': return $query->setParameter('statuses', array('open')); case 'all': return $query; case 'authored': return $query->setParameter( 'authorPHIDs', array($this->requireViewer()->getPHID())); case 'voted': return $query->setParameter('voted', array('voted')); } return parent::buildSavedQueryFromBuiltin($query_key); } protected function getRequiredHandlePHIDsForResultList( array $polls, PhabricatorSavedQuery $query) { return mpull($polls, 'getAuthorPHID'); } protected function renderResultList( array $polls, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($polls, 'PhabricatorSlowvotePoll'); $viewer = $this->requireViewer(); $list = id(new PHUIObjectItemListView()) ->setUser($viewer); $phids = mpull($polls, 'getAuthorPHID'); foreach ($polls as $poll) { $date_created = phabricator_datetime($poll->getDateCreated(), $viewer); if ($poll->getAuthorPHID()) { $author = $handles[$poll->getAuthorPHID()]->renderLink(); } else { $author = null; } $item = id(new PHUIObjectItemView()) ->setUser($viewer) ->setObject($poll) ->setObjectName('V'.$poll->getID()) ->setHeader($poll->getQuestion()) ->setHref('/V'.$poll->getID()) ->addIcon('none', $date_created); if ($poll->getIsClosed()) { $item->setStatusIcon('fa-ban grey'); $item->setDisabled(true); } else { $item->setStatusIcon('fa-bar-chart'); } $description = $poll->getDescription(); if (strlen($description)) { $item->addAttribute(id(new PhutilUTF8StringTruncator()) ->setMaximumGlyphs(120) ->truncateString($poll->getDescription())); } if ($author) { $item->addByline(pht('Author: %s', $author)); } $list->addItem($item); } $result = new PhabricatorApplicationSearchResultView(); $result->setObjectList($list); $result->setNoDataString(pht('No polls found.')); return $result; } + protected function getNewUserBody() { + $create_button = id(new PHUIButtonView()) + ->setTag('a') + ->setText(pht('Create a Poll')) + ->setHref('/vote/create/') + ->setColor(PHUIButtonView::GREEN); + + $icon = $this->getApplication()->getFontIcon(); + $app_name = $this->getApplication()->getName(); + $view = id(new PHUIBigInfoView()) + ->setIcon($icon) + ->setTitle(pht('Welcome to %s', $app_name)) + ->setDescription( + pht('Poll other users to help facilitate decision making.')) + ->addAction($create_button); + + return $view; + } + }