Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14701926
D12509.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
25 KB
Referenced Files
None
Subscribers
None
D12509.diff
View Options
diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -7,9 +7,9 @@
*/
return array(
'names' => array(
- 'core.pkg.css' => 'a2a90172',
- 'core.pkg.js' => '8e62b4aa',
- 'darkconsole.pkg.js' => 'b0a3ba93',
+ 'core.pkg.css' => 'f7d01efc',
+ 'core.pkg.js' => 'a1f9db42',
+ 'darkconsole.pkg.js' => '8ab24e01',
'differential.pkg.css' => '3500921f',
'differential.pkg.js' => 'c0506961',
'diffusion.pkg.css' => '591664fa',
@@ -34,7 +34,7 @@
'rsrc/css/aphront/typeahead.css' => '0e403212',
'rsrc/css/application/almanac/almanac.css' => 'dbb9b3af',
'rsrc/css/application/auth/auth.css' => '1e655982',
- 'rsrc/css/application/base/main-menu-view.css' => 'c648b2f5',
+ 'rsrc/css/application/base/main-menu-view.css' => '31e66da9',
'rsrc/css/application/base/notification-menu.css' => '3c9d8aa1',
'rsrc/css/application/base/phabricator-application-launch-view.css' => '16ca323f',
'rsrc/css/application/base/standard-page-view.css' => 'd3e1abe9',
@@ -350,7 +350,7 @@
'rsrc/image/texture/table_header_hover.png' => '038ec3b9',
'rsrc/image/texture/table_header_tall.png' => 'd56b434f',
'rsrc/js/application/aphlict/Aphlict.js' => '30a6303c',
- 'rsrc/js/application/aphlict/behavior-aphlict-dropdown.js' => 'ee37f73a',
+ 'rsrc/js/application/aphlict/behavior-aphlict-dropdown.js' => '572566ae',
'rsrc/js/application/aphlict/behavior-aphlict-listen.js' => 'b1a59974',
'rsrc/js/application/aphlict/behavior-aphlict-status.js' => 'ea681761',
'rsrc/js/application/auth/behavior-persona-login.js' => '9414ff18',
@@ -460,7 +460,7 @@
'rsrc/js/core/behavior-autofocus.js' => '7319e029',
'rsrc/js/core/behavior-choose-control.js' => '6153c708',
'rsrc/js/core/behavior-crop.js' => 'fa0f4fc2',
- 'rsrc/js/core/behavior-dark-console.js' => 'b8df5663',
+ 'rsrc/js/core/behavior-dark-console.js' => '08883e8b',
'rsrc/js/core/behavior-device.js' => 'a205cf28',
'rsrc/js/core/behavior-drag-and-drop-textarea.js' => '6d49590e',
'rsrc/js/core/behavior-error-log.js' => '6882e80a',
@@ -486,7 +486,7 @@
'rsrc/js/core/behavior-reorder-applications.js' => '76b9fc3e',
'rsrc/js/core/behavior-reveal-content.js' => '60821bc7',
'rsrc/js/core/behavior-scrollbar.js' => '834a1173',
- 'rsrc/js/core/behavior-search-typeahead.js' => '724b1247',
+ 'rsrc/js/core/behavior-search-typeahead.js' => 'bc965352',
'rsrc/js/core/behavior-select-on-click.js' => '4e3e79a6',
'rsrc/js/core/behavior-toggle-class.js' => 'e566f52c',
'rsrc/js/core/behavior-tokenizer.js' => 'b3a4b884',
@@ -550,7 +550,7 @@
'inline-comment-summary-css' => 'eb5f8e8c',
'javelin-aphlict' => '30a6303c',
'javelin-behavior' => '61cbc29a',
- 'javelin-behavior-aphlict-dropdown' => 'ee37f73a',
+ 'javelin-behavior-aphlict-dropdown' => '572566ae',
'javelin-behavior-aphlict-listen' => 'b1a59974',
'javelin-behavior-aphlict-status' => 'ea681761',
'javelin-behavior-aphront-basic-tokenizer' => 'b3a4b884',
@@ -567,7 +567,7 @@
'javelin-behavior-conpherence-pontificate' => '21ba5861',
'javelin-behavior-conpherence-widget-pane' => '93568464',
'javelin-behavior-countdown-timer' => 'e4cc26b3',
- 'javelin-behavior-dark-console' => 'b8df5663',
+ 'javelin-behavior-dark-console' => '08883e8b',
'javelin-behavior-dashboard-async-panel' => '469c0d9e',
'javelin-behavior-dashboard-move-panels' => '82439934',
'javelin-behavior-dashboard-query-panel-select' => '453c5375',
@@ -628,7 +628,7 @@
'javelin-behavior-phabricator-oncopy' => '2926fff2',
'javelin-behavior-phabricator-remarkup-assist' => 'e32d14ab',
'javelin-behavior-phabricator-reveal-content' => '60821bc7',
- 'javelin-behavior-phabricator-search-typeahead' => '724b1247',
+ 'javelin-behavior-phabricator-search-typeahead' => 'bc965352',
'javelin-behavior-phabricator-show-older-transactions' => 'dbbf48b6',
'javelin-behavior-phabricator-tooltips' => '3ee3408b',
'javelin-behavior-phabricator-transaction-comment-form' => '9f7309fb',
@@ -737,7 +737,7 @@
'phabricator-hovercard-view-css' => '44394670',
'phabricator-keyboard-shortcut' => '1ae869f2',
'phabricator-keyboard-shortcut-manager' => 'c1700f6f',
- 'phabricator-main-menu-view' => 'c648b2f5',
+ 'phabricator-main-menu-view' => '31e66da9',
'phabricator-nav-view-css' => '7aeaf435',
'phabricator-notification' => '0c6946e7',
'phabricator-notification-css' => '9c279160',
@@ -869,6 +869,14 @@
'phabricator-shaped-request',
'conpherence-thread-manager',
),
+ '08883e8b' => array(
+ 'javelin-behavior',
+ 'javelin-stratcom',
+ 'javelin-util',
+ 'javelin-dom',
+ 'javelin-request',
+ 'phabricator-keyboard-shortcut',
+ ),
'0a3f3021' => array(
'javelin-behavior',
'javelin-stratcom',
@@ -1190,6 +1198,16 @@
'javelin-vector',
'javelin-dom',
),
+ '572566ae' => array(
+ 'javelin-behavior',
+ 'javelin-request',
+ 'javelin-stratcom',
+ 'javelin-vector',
+ 'javelin-dom',
+ 'javelin-uri',
+ 'javelin-behavior-device',
+ 'phabricator-title',
+ ),
58562350 => array(
'javelin-dom',
'javelin-util',
@@ -1349,16 +1367,6 @@
'javelin-vector',
'javelin-util',
),
- '724b1247' => array(
- 'javelin-behavior',
- 'javelin-typeahead-ondemand-source',
- 'javelin-typeahead',
- 'javelin-dom',
- 'javelin-uri',
- 'javelin-util',
- 'javelin-stratcom',
- 'phabricator-prefab',
- ),
'7319e029' => array(
'javelin-behavior',
'javelin-dom',
@@ -1719,14 +1727,6 @@
'javelin-dom',
'javelin-util',
),
- 'b8df5663' => array(
- 'javelin-behavior',
- 'javelin-stratcom',
- 'javelin-util',
- 'javelin-dom',
- 'javelin-request',
- 'phabricator-keyboard-shortcut',
- ),
'bba9eedf' => array(
'javelin-behavior',
'javelin-stratcom',
@@ -1739,6 +1739,16 @@
'javelin-mask',
'phabricator-drag-and-drop-file-upload',
),
+ 'bc965352' => array(
+ 'javelin-behavior',
+ 'javelin-typeahead-ondemand-source',
+ 'javelin-typeahead',
+ 'javelin-dom',
+ 'javelin-uri',
+ 'javelin-util',
+ 'javelin-stratcom',
+ 'phabricator-prefab',
+ ),
'bd4c8dca' => array(
'javelin-install',
'javelin-util',
@@ -1940,16 +1950,6 @@
'javelin-stratcom',
'javelin-vector',
),
- 'ee37f73a' => array(
- 'javelin-behavior',
- 'javelin-request',
- 'javelin-stratcom',
- 'javelin-vector',
- 'javelin-dom',
- 'javelin-uri',
- 'javelin-behavior-device',
- 'phabricator-title',
- ),
'efe49472' => array(
'javelin-install',
'javelin-util',
diff --git a/src/applications/base/PhabricatorApplication.php b/src/applications/base/PhabricatorApplication.php
--- a/src/applications/base/PhabricatorApplication.php
+++ b/src/applications/base/PhabricatorApplication.php
@@ -582,4 +582,8 @@
}
}
+ public function getApplicationSearchDocumentTypes() {
+ return array();
+ }
+
}
diff --git a/src/applications/differential/application/PhabricatorDifferentialApplication.php b/src/applications/differential/application/PhabricatorDifferentialApplication.php
--- a/src/applications/differential/application/PhabricatorDifferentialApplication.php
+++ b/src/applications/differential/application/PhabricatorDifferentialApplication.php
@@ -205,4 +205,10 @@
);
}
+ public function getApplicationSearchDocumentTypes() {
+ return array(
+ DifferentialRevisionPHIDType::TYPECONST,
+ );
+ }
+
}
diff --git a/src/applications/diffusion/application/PhabricatorDiffusionApplication.php b/src/applications/diffusion/application/PhabricatorDiffusionApplication.php
--- a/src/applications/diffusion/application/PhabricatorDiffusionApplication.php
+++ b/src/applications/diffusion/application/PhabricatorDiffusionApplication.php
@@ -161,4 +161,10 @@
);
}
+ public function getApplicationSearchDocumentTypes() {
+ return array(
+ PhabricatorRepositoryCommitPHIDType::TYPECONST,
+ );
+ }
+
}
diff --git a/src/applications/fund/application/PhabricatorFundApplication.php b/src/applications/fund/application/PhabricatorFundApplication.php
--- a/src/applications/fund/application/PhabricatorFundApplication.php
+++ b/src/applications/fund/application/PhabricatorFundApplication.php
@@ -62,4 +62,10 @@
);
}
+ public function getApplicationSearchDocumentTypes() {
+ return array(
+ FundInitiativePHIDType::TYPECONST,
+ );
+ }
+
}
diff --git a/src/applications/maniphest/application/PhabricatorManiphestApplication.php b/src/applications/maniphest/application/PhabricatorManiphestApplication.php
--- a/src/applications/maniphest/application/PhabricatorManiphestApplication.php
+++ b/src/applications/maniphest/application/PhabricatorManiphestApplication.php
@@ -158,4 +158,10 @@
);
}
+ public function getApplicationSearchDocumentTypes() {
+ return array(
+ ManiphestTaskPHIDType::TYPECONST,
+ );
+ }
+
}
diff --git a/src/applications/passphrase/application/PhabricatorPassphraseApplication.php b/src/applications/passphrase/application/PhabricatorPassphraseApplication.php
--- a/src/applications/passphrase/application/PhabricatorPassphraseApplication.php
+++ b/src/applications/passphrase/application/PhabricatorPassphraseApplication.php
@@ -57,4 +57,10 @@
);
}
+ public function getApplicationSearchDocumentTypes() {
+ return array(
+ PassphraseCredentialPHIDType::TYPECONST,
+ );
+ }
+
}
diff --git a/src/applications/people/application/PhabricatorPeopleApplication.php b/src/applications/people/application/PhabricatorPeopleApplication.php
--- a/src/applications/people/application/PhabricatorPeopleApplication.php
+++ b/src/applications/people/application/PhabricatorPeopleApplication.php
@@ -192,4 +192,10 @@
return $items;
}
+ public function getApplicationSearchDocumentTypes() {
+ return array(
+ PhabricatorPeopleUserPHIDType::TYPECONST,
+ );
+ }
+
}
diff --git a/src/applications/pholio/application/PhabricatorPholioApplication.php b/src/applications/pholio/application/PhabricatorPholioApplication.php
--- a/src/applications/pholio/application/PhabricatorPholioApplication.php
+++ b/src/applications/pholio/application/PhabricatorPholioApplication.php
@@ -90,4 +90,10 @@
);
}
+ public function getApplicationSearchDocumentTypes() {
+ return array(
+ PholioMockPHIDType::TYPECONST,
+ );
+ }
+
}
diff --git a/src/applications/phriction/application/PhabricatorPhrictionApplication.php b/src/applications/phriction/application/PhabricatorPhrictionApplication.php
--- a/src/applications/phriction/application/PhabricatorPhrictionApplication.php
+++ b/src/applications/phriction/application/PhabricatorPhrictionApplication.php
@@ -69,4 +69,10 @@
return 0.140;
}
+ public function getApplicationSearchDocumentTypes() {
+ return array(
+ PhrictionDocumentPHIDType::TYPECONST,
+ );
+ }
+
}
diff --git a/src/applications/ponder/application/PhabricatorPonderApplication.php b/src/applications/ponder/application/PhabricatorPonderApplication.php
--- a/src/applications/ponder/application/PhabricatorPonderApplication.php
+++ b/src/applications/ponder/application/PhabricatorPonderApplication.php
@@ -79,4 +79,10 @@
);
}
+ public function getApplicationSearchDocumentTypes() {
+ return array(
+ PonderQuestionPHIDType::TYPECONST,
+ );
+ }
+
}
diff --git a/src/applications/project/application/PhabricatorProjectApplication.php b/src/applications/project/application/PhabricatorProjectApplication.php
--- a/src/applications/project/application/PhabricatorProjectApplication.php
+++ b/src/applications/project/application/PhabricatorProjectApplication.php
@@ -133,4 +133,10 @@
);
}
+ public function getApplicationSearchDocumentTypes() {
+ return array(
+ PhabricatorProjectProjectPHIDType::TYPECONST,
+ );
+ }
+
}
diff --git a/src/applications/search/controller/PhabricatorSearchController.php b/src/applications/search/controller/PhabricatorSearchController.php
--- a/src/applications/search/controller/PhabricatorSearchController.php
+++ b/src/applications/search/controller/PhabricatorSearchController.php
@@ -3,6 +3,8 @@
final class PhabricatorSearchController
extends PhabricatorSearchBaseController {
+ const SCOPE_CURRENT_APPLICATION = 'application';
+
private $queryKey;
public function shouldAllowPublic() {
@@ -32,49 +34,65 @@
$engine = new PhabricatorSearchApplicationSearchEngine();
$engine->setViewer($viewer);
- // NOTE: This is a little weird. If we're coming from primary search, we
- // load the user's first search filter and overwrite the "query" part of
- // it, then send them to that result page. This is sort of odd, but lets
- // users choose a default query like "Open Tasks" in a reasonable way,
- // with only this piece of somewhat-sketchy code. See discussion in T4365.
-
+ // If we're coming from primary search, do some special handling to
+ // interpret the scope selector and query.
if ($request->getBool('search:primary')) {
+
+ // If there's no query, just take the user to advanced search.
if (!strlen($request->getStr('query'))) {
$advanced_uri = '/search/query/advanced/';
return id(new AphrontRedirectResponse())->setURI($advanced_uri);
}
- $named_queries = $engine->loadEnabledNamedQueries();
- if ($named_queries) {
- $named = head($named_queries);
-
- $query_key = $named->getQueryKey();
- $saved = null;
- if ($engine->isBuiltinQuery($query_key)) {
- $saved = $engine->buildSavedQueryFromBuiltin($query_key);
- } else {
- $saved = id(new PhabricatorSavedQueryQuery())
- ->setViewer($viewer)
- ->withQueryKeys(array($query_key))
- ->executeOne();
+ // First, load or construct a template for the search by examining
+ // the current search scope.
+ $scope = $request->getStr('search:scope');
+ $saved = null;
+
+ if ($scope == self::SCOPE_CURRENT_APPLICATION) {
+ $application = id(new PhabricatorApplicationQuery())
+ ->setViewer($viewer)
+ ->withClasses(array($request->getStr('search:application')))
+ ->executeOne();
+ if ($application) {
+ $types = $application->getApplicationSearchDocumentTypes();
+ if ($types) {
+ $saved = id(new PhabricatorSavedQuery())
+ ->setEngineClassName(get_class($engine))
+ ->setParameter('types', $types);
+ }
}
+ }
- if ($saved) {
- $saved->setParameter('query', $request->getStr('query'));
- $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
- try {
- $saved->setID(null)->save();
- } catch (AphrontDuplicateKeyQueryException $ex) {
- // Ignore, this is just a repeated search.
- }
- unset($unguarded);
-
- $results_uri = $engine->getQueryResultsPageURI(
- $saved->getQueryKey()).'#R';
+ if (!$saved && !$engine->isBuiltinQuery($scope)) {
+ $saved = id(new PhabricatorSavedQueryQuery())
+ ->setViewer($viewer)
+ ->withQueryKeys(array($scope))
+ ->executeOne();
+ }
- return id(new AphrontRedirectResponse())->setURI($results_uri);
+ if (!$saved) {
+ if (!$engine->isBuiltinQuery($scope)) {
+ $scope = 'all';
}
+ $saved = $engine->buildSavedQueryFromBuiltin($scope);
}
+
+ // Add the user's query, then save this as a new saved query and send
+ // the user to the results page.
+ $saved->setParameter('query', $request->getStr('query'));
+
+ $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
+ try {
+ $saved->setID(null)->save();
+ } catch (AphrontDuplicateKeyQueryException $ex) {
+ // Ignore, this is just a repeated search.
+ }
+ unset($unguarded);
+
+ $query_key = $saved->getQueryKey();
+ $results_uri = $engine->getQueryResultsPageURI($query_key).'#R';
+ return id(new AphrontRedirectResponse())->setURI($results_uri);
}
$controller = id(new PhabricatorApplicationSearchController())
diff --git a/src/applications/settings/storage/PhabricatorUserPreferences.php b/src/applications/settings/storage/PhabricatorUserPreferences.php
--- a/src/applications/settings/storage/PhabricatorUserPreferences.php
+++ b/src/applications/settings/storage/PhabricatorUserPreferences.php
@@ -19,6 +19,7 @@
const PREFERENCE_SEARCHBAR_JUMP = 'searchbar-jump';
const PREFERENCE_SEARCH_SHORTCUT = 'search-shortcut';
+ const PREFERENCE_SEARCH_SCOPE = 'search-scope';
const PREFERENCE_DIFFUSION_BLAME = 'diffusion-blame';
const PREFERENCE_DIFFUSION_COLOR = 'diffusion-color';
diff --git a/src/view/page/menu/PhabricatorMainMenuSearchView.php b/src/view/page/menu/PhabricatorMainMenuSearchView.php
--- a/src/view/page/menu/PhabricatorMainMenuSearchView.php
+++ b/src/view/page/menu/PhabricatorMainMenuSearchView.php
@@ -3,6 +3,16 @@
final class PhabricatorMainMenuSearchView extends AphrontView {
private $id;
+ private $application;
+
+ public function setApplication(PhabricatorApplication $application) {
+ $this->application = $application;
+ return $this;
+ }
+
+ public function getApplication() {
+ return $this->application;
+ }
public function getID() {
if (!$this->id) {
@@ -36,6 +46,7 @@
'');
$search_datasource = new PhabricatorSearchDatasource();
+ $scope_key = PhabricatorUserPreferences::PREFERENCE_SEARCH_SCOPE;
Javelin::initBehavior(
'phabricator-search-typeahead',
@@ -46,6 +57,7 @@
'src' => $search_datasource->getDatasourceURI(),
'limit' => 10,
'placeholder' => pht('Search'),
+ 'scopeUpdateURI' => '/settings/adjust/?key='.$scope_key,
));
$primary_input = phutil_tag(
@@ -63,6 +75,8 @@
),
pht('Search'));
+ $selector = $this->buildModeSelector();
+
$form = phabricator_form(
$user,
array(
@@ -78,6 +92,7 @@
'class' => 'phui-icon-view phui-font-fa fa-search',
),
$search_text),
+ $selector,
$primary_input,
$target,
)));
@@ -85,4 +100,124 @@
return $form;
}
+ private function buildModeSelector() {
+ $viewer = $this->getUser();
+
+ $items = array();
+ $items[] = array(
+ 'name' => pht('Search'),
+ );
+
+ $items[] = array(
+ 'icon' => 'fa-globe',
+ 'name' => pht('Search All Documents'),
+ 'value' => 'all',
+ );
+
+ $application_value = null;
+ $application_icon = 'fa-file-o';
+ $application = $this->getApplication();
+ if ($application) {
+ $application_value = get_class($application);
+ if ($application->getApplicationSearchDocumentTypes()) {
+ $application_icon = $application->getFontIcon();
+ }
+ }
+
+ $items[] = array(
+ 'icon' => $application_icon,
+ 'name' => pht('Search Current Application'),
+ 'value' => PhabricatorSearchController::SCOPE_CURRENT_APPLICATION,
+ );
+
+ $items[] = array(
+ 'name' => pht('Saved Queries'),
+ );
+
+
+ $engine = id(new PhabricatorSearchApplicationSearchEngine())
+ ->setViewer($viewer);
+ $engine_queries = $engine->loadEnabledNamedQueries();
+ $query_map = mpull($engine_queries, 'getQueryName', 'getQueryKey');
+ foreach ($query_map as $query_key => $query_name) {
+ if ($query_key == 'all') {
+ // Skip the builtin "All" query since it's redundant with the default
+ // setting.
+ continue;
+ }
+
+ $items[] = array(
+ 'icon' => 'fa-search',
+ 'name' => $query_name,
+ 'value' => $query_key,
+ );
+ }
+
+ $items[] = array(
+ 'name' => pht('More Options'),
+ );
+
+ $items[] = array(
+ 'icon' => 'fa-search-plus',
+ 'name' => pht('Advanced Search'),
+ 'href' => '/search/query/advanced/',
+ );
+
+ /* TODO: Write this.
+ $items[] = array(
+ 'icon' => 'fa-book',
+ 'name' => pht('User Guide: Search'),
+ 'href' => PhabricatorEnv::getDoclink('User Guide: Search'),
+ );
+ */
+
+ $scope_key = PhabricatorUserPreferences::PREFERENCE_SEARCH_SCOPE;
+ $current_value = $viewer->loadPreferences()->getPreference(
+ $scope_key,
+ 'all');
+
+ $current_icon = 'fa-globe';
+ foreach ($items as $item) {
+ if (idx($item, 'value') == $current_value) {
+ $current_icon = $item['icon'];
+ break;
+ }
+ }
+
+ $selector = id(new PHUIButtonView())
+ ->addClass('phabricator-main-menu-search-dropdown')
+ ->addSigil('global-search-dropdown')
+ ->setMetadata(
+ array(
+ 'items' => $items,
+ 'icon' => $current_icon,
+ 'value' => $current_value,
+ ))
+ ->setIcon(
+ id(new PHUIIconView())
+ ->addSigil('global-search-dropdown-icon')
+ ->setIconFont($current_icon))
+ ->setDropdown(true);
+
+ $input = javelin_tag(
+ 'input',
+ array(
+ 'type' => 'hidden',
+ 'sigil' => 'global-search-dropdown-input',
+ 'name' => 'search:scope',
+ 'value' => $current_value,
+ ));
+
+ $application_input = javelin_tag(
+ 'input',
+ array(
+ 'type' => 'hidden',
+ 'sigil' => 'global-search-dropdown-app',
+ 'name' => 'search:application',
+ 'value' => $application_value,
+ ));
+
+ return array($selector, $input, $application_input);
+ }
+
}
diff --git a/src/view/page/menu/PhabricatorMainMenuView.php b/src/view/page/menu/PhabricatorMainMenuView.php
--- a/src/view/page/menu/PhabricatorMainMenuView.php
+++ b/src/view/page/menu/PhabricatorMainMenuView.php
@@ -114,6 +114,16 @@
if ($show_search) {
$search = new PhabricatorMainMenuSearchView();
$search->setUser($user);
+
+ $application = null;
+ $controller = $this->getController();
+ if ($controller) {
+ $application = $controller->getCurrentApplication();
+ }
+ if ($application) {
+ $search->setApplication($application);
+ }
+
$result = $search;
$pref_shortcut = PhabricatorUserPreferences::PREFERENCE_SEARCH_SHORTCUT;
diff --git a/webroot/rsrc/css/application/base/main-menu-view.css b/webroot/rsrc/css/application/base/main-menu-view.css
--- a/webroot/rsrc/css/application/base/main-menu-view.css
+++ b/webroot/rsrc/css/application/base/main-menu-view.css
@@ -160,10 +160,9 @@
height: 28px;
line-height: 12px;
box-shadow: 0px 1px 1px rgba(128, 128, 128, 0.25);
- padding: 6px 30px 6px 6px;
+ padding: 6px 30px 6px 46px;
float: left;
width: 205px;
- left: 0;
}
.phabricator-main-menu.main-header-dark .phabricator-main-menu-search input {
@@ -207,6 +206,25 @@
border-radius: 0;
}
+.phabricator-main-menu-search button.phabricator-main-menu-search-dropdown {
+ position: absolute;
+ right: auto;
+ left: 0;
+ width: 40px;
+}
+
+.phabricator-main-menu-search button.phabricator-main-menu-search-dropdown
+ .phui-icon-view {
+ color: rgba(255,255,255,.8);
+}
+
+.phabricator-main-menu-search-dropdown .caret {
+ position: absolute;
+ right: 4px;
+ top: 3px;
+}
+
+
.phabricator-main-menu-search button:hover {
color: #fff;
}
diff --git a/webroot/rsrc/js/core/behavior-search-typeahead.js b/webroot/rsrc/js/core/behavior-search-typeahead.js
--- a/webroot/rsrc/js/core/behavior-search-typeahead.js
+++ b/webroot/rsrc/js/core/behavior-search-typeahead.js
@@ -143,4 +143,86 @@
typeahead.setPlaceholder('');
typeahead.updatePlaceHolder();
});
+
+ // TODO: Quicksand needs to update the application search input as we change
+ // applications; we should register a listener.
+ // TODO: Quicksand also needs to update the application search icon on the
+ // button itself and in the menu.
+
+ // Implement the scope selector menu for the global search.
+ JX.Stratcom.listen('click', 'global-search-dropdown', function(e) {
+ var data = e.getNodeData('global-search-dropdown');
+ var button = e.getNode('global-search-dropdown');
+ if (data.menu) {
+ return;
+ }
+
+ e.kill();
+
+ function updateValue(spec) {
+ if (data.value == spec.value) {
+ return;
+ }
+
+ // Swap out the icon.
+ var icon = JX.DOM.find(button, 'span', 'global-search-dropdown-icon');
+ JX.DOM.alterClass(icon, data.icon, false);
+ data.icon = spec.icon;
+ JX.DOM.alterClass(icon, data.icon, true);
+
+ // Update the value.
+ data.value = spec.value;
+
+ // Update the form input.
+ var frame = button.parentNode;
+ var input = JX.DOM.find(frame, 'input', 'global-search-dropdown-input');
+ input.value = data.value;
+
+ new JX.Request(config.scopeUpdateURI)
+ .setData({value: data.value})
+ .send();
+ }
+
+ var menu = new JX.PHUIXDropdownMenu(button)
+ .setAlign('left');
+ data.menu = menu;
+
+ menu.listen('open', function() {
+ var list = new JX.PHUIXActionListView();
+
+ for (var ii = 0; ii < data.items.length; ii++) {
+ var spec = data.items[ii];
+ var item = new JX.PHUIXActionView()
+ .setName(spec.name)
+ .setIcon(spec.icon);
+
+ if (spec.value) {
+ if (spec.value == data.value) {
+ item.setSelected(true);
+ }
+
+ var handler = function(spec, e) {
+ e.prevent();
+ menu.close();
+ updateValue(spec);
+ };
+
+ item.setHandler(JX.bind(null, handler, spec));
+ } else if (spec.href) {
+ item.setHref(spec.href);
+ item.setHandler(function() { menu.close(); });
+ } else {
+ item.setDisabled(true);
+ }
+
+ list.addItem(item);
+ }
+
+ menu.setContent(list.getNode());
+ });
+
+ menu.open();
+ });
+
+
});
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jan 16, 3:28 AM (19 h, 34 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6995900
Default Alt Text
D12509.diff (25 KB)
Attached To
Mode
D12509: Implement a scope selector for the global search
Attached
Detach File
Event Timeline
Log In to Comment