mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-27 07:50:57 +01:00
Improve application query UI/UX
Summary: Ref T2625. @chad, you might have some feedback here. The behaviors this implements are: - When the user selects "Advanced Search", we show the full search UI and no results (for performance and clarity). - When the user submits a search which //is not// a named search, we show the full search UI and the "Save Custom Query..." button. - When the user submits a search which //is// a named search, we show "Results for search X." with an "Edit Query..." button. The button expands the search form. - When the user selects a builtin query (like "All Pastes"), we don't show any search UI, but I'm probably going to make this behave more like named searches. Test Plan: {F44346} {F44347} Reviewers: chad, btrahan, blc Reviewed By: btrahan CC: aran Maniphest Tasks: T2625 Differential Revision: https://secure.phabricator.com/D6063
This commit is contained in:
parent
d0b9b6c908
commit
545dbabbca
6 changed files with 261 additions and 112 deletions
|
@ -809,7 +809,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'aphront-list-filter-view-css' =>
|
||||
array(
|
||||
'uri' => '/res/639ea9e9/rsrc/css/aphront/list-filter-view.css',
|
||||
'uri' => '/res/f754f4c5/rsrc/css/aphront/list-filter-view.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -3973,7 +3973,7 @@ celerity_register_resource_map(array(
|
|||
), array(
|
||||
'packages' =>
|
||||
array(
|
||||
'c3ade478' =>
|
||||
'67ac9423' =>
|
||||
array(
|
||||
'name' => 'core.pkg.css',
|
||||
'symbols' =>
|
||||
|
@ -4022,7 +4022,7 @@ celerity_register_resource_map(array(
|
|||
41 => 'phabricator-property-list-view-css',
|
||||
42 => 'phabricator-tag-view-css',
|
||||
),
|
||||
'uri' => '/res/pkg/c3ade478/core.pkg.css',
|
||||
'uri' => '/res/pkg/67ac9423/core.pkg.css',
|
||||
'type' => 'css',
|
||||
),
|
||||
'98f60e3f' =>
|
||||
|
@ -4216,16 +4216,16 @@ celerity_register_resource_map(array(
|
|||
'reverse' =>
|
||||
array(
|
||||
'aphront-attached-file-view-css' => '6b1fccc6',
|
||||
'aphront-dialog-view-css' => 'c3ade478',
|
||||
'aphront-error-view-css' => 'c3ade478',
|
||||
'aphront-form-view-css' => 'c3ade478',
|
||||
'aphront-list-filter-view-css' => 'c3ade478',
|
||||
'aphront-pager-view-css' => 'c3ade478',
|
||||
'aphront-panel-view-css' => 'c3ade478',
|
||||
'aphront-table-view-css' => 'c3ade478',
|
||||
'aphront-tokenizer-control-css' => 'c3ade478',
|
||||
'aphront-tooltip-css' => 'c3ade478',
|
||||
'aphront-typeahead-control-css' => 'c3ade478',
|
||||
'aphront-dialog-view-css' => '67ac9423',
|
||||
'aphront-error-view-css' => '67ac9423',
|
||||
'aphront-form-view-css' => '67ac9423',
|
||||
'aphront-list-filter-view-css' => '67ac9423',
|
||||
'aphront-pager-view-css' => '67ac9423',
|
||||
'aphront-panel-view-css' => '67ac9423',
|
||||
'aphront-table-view-css' => '67ac9423',
|
||||
'aphront-tokenizer-control-css' => '67ac9423',
|
||||
'aphront-tooltip-css' => '67ac9423',
|
||||
'aphront-typeahead-control-css' => '67ac9423',
|
||||
'differential-changeset-view-css' => 'dd27a69b',
|
||||
'differential-core-view-css' => 'dd27a69b',
|
||||
'differential-inline-comment-editor' => '9488bb69',
|
||||
|
@ -4239,7 +4239,7 @@ celerity_register_resource_map(array(
|
|||
'differential-table-of-contents-css' => 'dd27a69b',
|
||||
'diffusion-commit-view-css' => 'c8ce2d88',
|
||||
'diffusion-icons-css' => 'c8ce2d88',
|
||||
'global-drag-and-drop-css' => 'c3ade478',
|
||||
'global-drag-and-drop-css' => '67ac9423',
|
||||
'inline-comment-summary-css' => 'dd27a69b',
|
||||
'javelin-aphlict' => '98f60e3f',
|
||||
'javelin-behavior' => 'c1359b5d',
|
||||
|
@ -4313,56 +4313,56 @@ celerity_register_resource_map(array(
|
|||
'javelin-util' => 'c1359b5d',
|
||||
'javelin-vector' => 'c1359b5d',
|
||||
'javelin-workflow' => 'c1359b5d',
|
||||
'lightbox-attachment-css' => 'c3ade478',
|
||||
'lightbox-attachment-css' => '67ac9423',
|
||||
'maniphest-task-summary-css' => '6b1fccc6',
|
||||
'maniphest-transaction-detail-css' => '6b1fccc6',
|
||||
'phabricator-action-list-view-css' => 'c3ade478',
|
||||
'phabricator-application-launch-view-css' => 'c3ade478',
|
||||
'phabricator-action-list-view-css' => '67ac9423',
|
||||
'phabricator-application-launch-view-css' => '67ac9423',
|
||||
'phabricator-busy' => '98f60e3f',
|
||||
'phabricator-content-source-view-css' => 'dd27a69b',
|
||||
'phabricator-core-buttons-css' => 'c3ade478',
|
||||
'phabricator-core-css' => 'c3ade478',
|
||||
'phabricator-crumbs-view-css' => 'c3ade478',
|
||||
'phabricator-directory-css' => 'c3ade478',
|
||||
'phabricator-core-buttons-css' => '67ac9423',
|
||||
'phabricator-core-css' => '67ac9423',
|
||||
'phabricator-crumbs-view-css' => '67ac9423',
|
||||
'phabricator-directory-css' => '67ac9423',
|
||||
'phabricator-drag-and-drop-file-upload' => '9488bb69',
|
||||
'phabricator-dropdown-menu' => '98f60e3f',
|
||||
'phabricator-file-upload' => '98f60e3f',
|
||||
'phabricator-filetree-view-css' => 'c3ade478',
|
||||
'phabricator-flag-css' => 'c3ade478',
|
||||
'phabricator-form-view-css' => 'c3ade478',
|
||||
'phabricator-header-view-css' => 'c3ade478',
|
||||
'phabricator-filetree-view-css' => '67ac9423',
|
||||
'phabricator-flag-css' => '67ac9423',
|
||||
'phabricator-form-view-css' => '67ac9423',
|
||||
'phabricator-header-view-css' => '67ac9423',
|
||||
'phabricator-hovercard' => '98f60e3f',
|
||||
'phabricator-jump-nav' => 'c3ade478',
|
||||
'phabricator-jump-nav' => '67ac9423',
|
||||
'phabricator-keyboard-shortcut' => '98f60e3f',
|
||||
'phabricator-keyboard-shortcut-manager' => '98f60e3f',
|
||||
'phabricator-main-menu-view' => 'c3ade478',
|
||||
'phabricator-main-menu-view' => '67ac9423',
|
||||
'phabricator-menu-item' => '98f60e3f',
|
||||
'phabricator-nav-view-css' => 'c3ade478',
|
||||
'phabricator-nav-view-css' => '67ac9423',
|
||||
'phabricator-notification' => '98f60e3f',
|
||||
'phabricator-notification-css' => 'c3ade478',
|
||||
'phabricator-notification-menu-css' => 'c3ade478',
|
||||
'phabricator-object-item-list-view-css' => 'c3ade478',
|
||||
'phabricator-notification-css' => '67ac9423',
|
||||
'phabricator-notification-menu-css' => '67ac9423',
|
||||
'phabricator-object-item-list-view-css' => '67ac9423',
|
||||
'phabricator-object-selector-css' => 'dd27a69b',
|
||||
'phabricator-phtize' => '98f60e3f',
|
||||
'phabricator-prefab' => '98f60e3f',
|
||||
'phabricator-project-tag-css' => '6b1fccc6',
|
||||
'phabricator-property-list-view-css' => 'c3ade478',
|
||||
'phabricator-remarkup-css' => 'c3ade478',
|
||||
'phabricator-property-list-view-css' => '67ac9423',
|
||||
'phabricator-remarkup-css' => '67ac9423',
|
||||
'phabricator-shaped-request' => '9488bb69',
|
||||
'phabricator-side-menu-view-css' => 'c3ade478',
|
||||
'phabricator-standard-page-view' => 'c3ade478',
|
||||
'phabricator-tag-view-css' => 'c3ade478',
|
||||
'phabricator-side-menu-view-css' => '67ac9423',
|
||||
'phabricator-standard-page-view' => '67ac9423',
|
||||
'phabricator-tag-view-css' => '67ac9423',
|
||||
'phabricator-textareautils' => '98f60e3f',
|
||||
'phabricator-tooltip' => '98f60e3f',
|
||||
'phabricator-transaction-view-css' => 'c3ade478',
|
||||
'phabricator-zindex-css' => 'c3ade478',
|
||||
'phui-form-css' => 'c3ade478',
|
||||
'phui-icon-view-css' => 'c3ade478',
|
||||
'spacing-css' => 'c3ade478',
|
||||
'sprite-apps-large-css' => 'c3ade478',
|
||||
'sprite-gradient-css' => 'c3ade478',
|
||||
'sprite-icons-css' => 'c3ade478',
|
||||
'sprite-menu-css' => 'c3ade478',
|
||||
'syntax-highlighting-css' => 'c3ade478',
|
||||
'phabricator-transaction-view-css' => '67ac9423',
|
||||
'phabricator-zindex-css' => '67ac9423',
|
||||
'phui-form-css' => '67ac9423',
|
||||
'phui-icon-view-css' => '67ac9423',
|
||||
'spacing-css' => '67ac9423',
|
||||
'sprite-apps-large-css' => '67ac9423',
|
||||
'sprite-gradient-css' => '67ac9423',
|
||||
'sprite-icons-css' => '67ac9423',
|
||||
'sprite-menu-css' => '67ac9423',
|
||||
'syntax-highlighting-css' => '67ac9423',
|
||||
),
|
||||
));
|
||||
|
|
|
@ -32,7 +32,7 @@ abstract class PhabricatorPasteController extends PhabricatorController {
|
|||
$nav->addFilter('savedqueries', pht('Edit Queries...'));
|
||||
|
||||
$nav->addLabel(pht('Search'));
|
||||
$nav->addFilter('filter/advanced', pht('Advanced Search'));
|
||||
$nav->addFilter('query/advanced', pht('Advanced Search'));
|
||||
|
||||
$nav->selectFilter(null);
|
||||
|
||||
|
|
|
@ -27,59 +27,95 @@ final class PhabricatorPasteListController extends PhabricatorPasteController {
|
|||
|
||||
$nav = $this->buildSideNavView();
|
||||
|
||||
if ($engine->isBuiltinQuery($this->queryKey)) {
|
||||
$saved_query = $engine->buildSavedQueryFromBuiltin($this->queryKey);
|
||||
} else {
|
||||
$named_query = null;
|
||||
$run_query = true;
|
||||
$query_key = $this->queryKey;
|
||||
if ($this->queryKey == 'advanced') {
|
||||
$run_query = false;
|
||||
$query_key = $request->getStr('query');
|
||||
}
|
||||
|
||||
if ($engine->isBuiltinQuery($query_key)) {
|
||||
$saved_query = $engine->buildSavedQueryFromBuiltin($query_key);
|
||||
$named_query = $engine->getBuiltinQuery($query_key);
|
||||
} else if ($query_key) {
|
||||
$saved_query = id(new PhabricatorSavedQueryQuery())
|
||||
->setViewer($user)
|
||||
->withQueryKeys(array($this->queryKey))
|
||||
->withQueryKeys(array($query_key))
|
||||
->executeOne();
|
||||
|
||||
if (!$saved_query) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
}
|
||||
|
||||
$query = id(new PhabricatorPasteSearchEngine())
|
||||
->buildQueryFromSavedQuery($saved_query);
|
||||
$named_query = id(new PhabricatorNamedQueryQuery())
|
||||
->setViewer($user)
|
||||
->withQueryKeys(array($saved_query->getQueryKey()))
|
||||
->withEngineClassNames(array(get_class($engine)))
|
||||
->withUserPHIDs(array($user->getPHID()))
|
||||
->executeOne();
|
||||
} else {
|
||||
$saved_query = $engine->buildSavedQueryFromRequest($request);
|
||||
}
|
||||
|
||||
$filter = $nav->selectFilter(
|
||||
'query/'.$saved_query->getQueryKey(),
|
||||
'filter/advanced');
|
||||
'query/advanced');
|
||||
|
||||
$pager = new AphrontCursorPagerView();
|
||||
$pager->readFromRequest($request);
|
||||
$pastes = $query->setViewer($request->getUser())
|
||||
->needContent(true)
|
||||
->executeWithCursorPager($pager);
|
||||
$form = id(new AphrontFormView())
|
||||
->setNoShading(true)
|
||||
->setUser($user);
|
||||
|
||||
$list = $this->buildPasteList($pastes);
|
||||
$list->setPager($pager);
|
||||
$list->setNoDataString(pht("No results found for this query."));
|
||||
$engine->buildSearchForm($form, $saved_query);
|
||||
|
||||
if ($this->queryKey !== null || $filter == "filter/advanced") {
|
||||
$form = id(new AphrontFormView())
|
||||
->setNoShading(true)
|
||||
->setUser($user);
|
||||
$submit = id(new AphrontFormSubmitControl())
|
||||
->setValue(pht('Execute Query'));
|
||||
|
||||
$engine->buildSearchForm($form, $saved_query);
|
||||
|
||||
$submit = id(new AphrontFormSubmitControl())
|
||||
->setValue(pht('Execute Query'));
|
||||
|
||||
if ($filter == 'filter/advanced') {
|
||||
$submit->addCancelButton(
|
||||
'/search/edit/'.$saved_query->getQueryKey().'/',
|
||||
pht('Save Custom Query...'));
|
||||
}
|
||||
|
||||
$form->appendChild($submit);
|
||||
|
||||
$filter_view = id(new AphrontListFilterView())->appendChild($form);
|
||||
$nav->appendChild($filter_view);
|
||||
if ($run_query && !$named_query) {
|
||||
$submit->addCancelButton(
|
||||
'/search/edit/'.$saved_query->getQueryKey().'/',
|
||||
pht('Save Custom Query...'));
|
||||
}
|
||||
|
||||
$nav->appendChild($list);
|
||||
$form->appendChild($submit);
|
||||
$filter_view = id(new AphrontListFilterView())->appendChild($form);
|
||||
|
||||
if ($run_query && $named_query) {
|
||||
if ($named_query->getIsBuiltin()) {
|
||||
$description = pht(
|
||||
'Showing results for query "%s".',
|
||||
$named_query->getQueryName());
|
||||
} else {
|
||||
$description = pht(
|
||||
'Showing results for saved query "%s".',
|
||||
$named_query->getQueryName());
|
||||
}
|
||||
|
||||
$filter_view->setCollapsed(
|
||||
pht('Edit Query...'),
|
||||
pht('Hide Query'),
|
||||
$description,
|
||||
$this->getApplicationURI('query/advanced/?query='.$query_key));
|
||||
}
|
||||
|
||||
$nav->appendChild($filter_view);
|
||||
|
||||
if ($run_query) {
|
||||
$query = id(new PhabricatorPasteSearchEngine())
|
||||
->buildQueryFromSavedQuery($saved_query);
|
||||
|
||||
$pager = new AphrontCursorPagerView();
|
||||
$pager->readFromRequest($request);
|
||||
$pastes = $query->setViewer($request->getUser())
|
||||
->needContent(true)
|
||||
->executeWithCursorPager($pager);
|
||||
|
||||
$list = $this->buildPasteList($pastes);
|
||||
$list->setPager($pager);
|
||||
$list->setNoDataString(pht("No results found for this query."));
|
||||
|
||||
$nav->appendChild($list);
|
||||
}
|
||||
|
||||
$crumbs = $this
|
||||
->buildApplicationCrumbs($nav)
|
||||
|
|
|
@ -104,6 +104,17 @@ abstract class PhabricatorApplicationSearchEngine {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @task builtin
|
||||
*/
|
||||
public function getBuiltinQuery($query_key) {
|
||||
if (!$this->isBuiltinQuery($query_key)) {
|
||||
throw new Exception("'{$query_key}' is not a builtin!");
|
||||
}
|
||||
return idx($this->getBuiltinQueries(), $query_key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @task builtin
|
||||
*/
|
||||
|
|
|
@ -2,23 +2,110 @@
|
|||
|
||||
final class AphrontListFilterView extends AphrontView {
|
||||
|
||||
public function render() {
|
||||
$contents = $this->renderChildren();
|
||||
private $showAction;
|
||||
private $hideAction;
|
||||
private $showHideDescription;
|
||||
private $showHideHref;
|
||||
|
||||
if (!$contents) {
|
||||
public function setCollapsed($show, $hide, $description, $href) {
|
||||
$this->showAction = $show;
|
||||
$this->hideAction = $hide;
|
||||
$this->showHideDescription = $description;
|
||||
$this->showHideHref = $href;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$content = $this->renderChildren();
|
||||
if (!$content) {
|
||||
return null;
|
||||
}
|
||||
|
||||
require_celerity_resource('aphront-list-filter-view-css');
|
||||
return hsprintf(
|
||||
'<div class="aphront-filter-table-wrapper">'.
|
||||
'<table class="aphront-list-filter-view">'.
|
||||
'<tr>'.
|
||||
'<td class="aphront-list-filter-view-controls">%s</td>'.
|
||||
'</tr>'.
|
||||
'</table>'.
|
||||
'</div>',
|
||||
$contents);
|
||||
|
||||
$content = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'aphront-list-filter-view-content',
|
||||
),
|
||||
$content);
|
||||
|
||||
$classes = array();
|
||||
$classes[] = 'aphront-list-filter-view';
|
||||
if ($this->showAction !== null) {
|
||||
$classes[] = 'aphront-list-filter-view-collapsible';
|
||||
|
||||
Javelin::initBehavior('phabricator-reveal-content');
|
||||
|
||||
$hide_action_id = celerity_generate_unique_node_id();
|
||||
$show_action_id = celerity_generate_unique_node_id();
|
||||
$content_id = celerity_generate_unique_node_id();
|
||||
|
||||
$hide_action = javelin_tag(
|
||||
'a',
|
||||
array(
|
||||
'class' => '',
|
||||
'sigil' => 'reveal-content',
|
||||
'id' => $hide_action_id,
|
||||
'href' => $this->showHideHref,
|
||||
'meta' => array(
|
||||
'hideIDs' => array($hide_action_id),
|
||||
'showIDs' => array($content_id, $show_action_id),
|
||||
),
|
||||
),
|
||||
$this->showAction);
|
||||
|
||||
$content_description = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'aphront-list-filter-description',
|
||||
),
|
||||
$this->showHideDescription);
|
||||
|
||||
$show_action = javelin_tag(
|
||||
'a',
|
||||
array(
|
||||
'class' => '',
|
||||
'sigil' => 'reveal-content',
|
||||
'style' => 'display: none;',
|
||||
'href' => '#',
|
||||
'id' => $show_action_id,
|
||||
'meta' => array(
|
||||
'hideIDs' => array($content_id, $show_action_id),
|
||||
'showIDs' => array($hide_action_id),
|
||||
),
|
||||
),
|
||||
$this->hideAction);
|
||||
|
||||
$reveal_block = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'aphront-list-filter-reveal',
|
||||
),
|
||||
array(
|
||||
$content_description,
|
||||
$hide_action,
|
||||
$show_action,
|
||||
));
|
||||
|
||||
$content = array(
|
||||
$reveal_block,
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'id' => $content_id,
|
||||
'style' => 'display: none;',
|
||||
),
|
||||
$content),
|
||||
);
|
||||
}
|
||||
|
||||
return phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => implode(' ', $classes),
|
||||
),
|
||||
$content);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,47 +2,62 @@
|
|||
* @provides aphront-list-filter-view-css
|
||||
*/
|
||||
|
||||
.aphront-filter-table-wrapper {
|
||||
.aphront-list-filter-view {
|
||||
border-left: 1px solid #e7e7e7;
|
||||
border-right: 1px solid #e7e7e7;
|
||||
border-bottom: 1px solid #c0c5d1;
|
||||
background: #fff;
|
||||
|
||||
margin: 0 20px;
|
||||
}
|
||||
|
||||
.device-phone .aphront-filter-table-wrapper {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.aphront-list-filter-view {
|
||||
background: #fff;
|
||||
width: 100%;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
.aphront-list-filter-view-controls {
|
||||
width: 100%;
|
||||
.device-phone .aphront-list-filter-view {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.aphront-list-filter-view-controls .aphront-form-view {
|
||||
.aphront-list-filter-view-content .aphront-form-view {
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
padding: 12px 0 6px;
|
||||
}
|
||||
|
||||
.aphront-list-filter-view-controls .aphront-form-view .aphront-form-label {
|
||||
.aphront-list-filter-view-content .aphront-form-view .aphront-form-label {
|
||||
width: 12%;
|
||||
}
|
||||
|
||||
.aphront-list-filter-view-controls .aphront-form-view .aphront-form-input {
|
||||
.aphront-list-filter-view-content .aphront-form-view .aphront-form-input {
|
||||
width: 70%;
|
||||
margin-left: 13%;
|
||||
margin-right: 17%;
|
||||
}
|
||||
|
||||
.device-phone .aphront-list-filter-view-controls .aphront-form-view .aphront-form-input {
|
||||
.device-phone .aphront-list-filter-view-content .aphront-form-view
|
||||
.aphront-form-input {
|
||||
width: 98%;
|
||||
margin-left: 0%;
|
||||
margin-right: 0%;
|
||||
}
|
||||
|
||||
.aphront-list-filter-view-collapsible .aphront-list-filter-view-content {
|
||||
border-top: 1px solid #e7e7e7;
|
||||
}
|
||||
|
||||
.aphront-list-filter-reveal {
|
||||
margin-left: 13%;
|
||||
margin-right: 17%;
|
||||
padding: 4px;
|
||||
overflow: hidden;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.aphront-list-filter-reveal a {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.aphront-list-filter-description {
|
||||
margin-right: 20%;
|
||||
color: #666666;
|
||||
float: left;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue