Page MenuHomePhabricator

D12509.diff
No OneTemporary

D12509.diff

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

Mime Type
text/plain
Expires
Fri, May 10, 3:27 AM (1 w, 6 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6281467
Default Alt Text
D12509.diff (25 KB)

Event Timeline