diff --git a/web/htdocs/assets/css/codesearch.css b/web/htdocs/assets/css/codesearch.css index e70a6dc0..fb219254 100644 --- a/web/htdocs/assets/css/codesearch.css +++ b/web/htdocs/assets/css/codesearch.css @@ -279,15 +279,61 @@ a:hover { } .search-options { - width: 250px; - max-width: 250px; + width: 280px; + max-width: 280px; margin: 0; font-size: 12px; - line-height: 20px; + display: flex; + flex-direction: column; + gap: 3px; } .search-option { white-space: nowrap; + line-height: 24px; +} + +.search-option input[type="radio"], +.search-option input[type="checkbox"] { + appearance: none; + width: 14px; + height: 14px; + border: 1.5px solid var(--color-border-subtle); + background: var(--color-background); + vertical-align: middle; + margin: 0 2px 0 0; + cursor: pointer; + transition: border-color 150ms, background 150ms; +} + +.search-option input[type="radio"] { + border-radius: 50%; +} + +.search-option input[type="checkbox"] { + border-radius: 3px; +} + +.search-option input[type="radio"]:checked { + border-color: var(--color-foreground-accent); + background: var(--color-foreground-accent); + box-shadow: inset 0 0 0 2.5px var(--color-background); +} + +.search-option input[type="checkbox"]:checked { + border-color: var(--color-foreground-accent); + background: var(--color-foreground-accent); + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 14 14' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M3.5 7.5L6 10L10.5 4.5' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); +} + +.search-option input[type="radio"]:hover, +.search-option input[type="checkbox"]:hover { + border-color: var(--color-foreground-accent); +} + +.search-option label { + cursor: pointer; + margin-right: 6px; } #regex-error { @@ -913,3 +959,28 @@ div.example { .token.bold { font-weight: bold; } + +/* Repo preset buttons */ +.repo-presets { + display: flex; + flex-wrap: wrap; + gap: 5px; + margin-top: 2px; + padding-left: 2px; +} + +.repo-preset-btn { + background: var(--color-background-subtle); + border: 1px solid var(--color-border-default); + border-radius: 4px; + color: var(--color-foreground-muted); + cursor: pointer; + font-size: 11px; + padding: 3px 10px; + transition: background 150ms, color 150ms; +} + +.repo-preset-btn:hover { + background: var(--color-background-hover); + color: var(--color-foreground); +} diff --git a/web/src/codesearch/codesearch_ui.js b/web/src/codesearch/codesearch_ui.js index fbd533a6..2294aad6 100644 --- a/web/src/codesearch/codesearch_ui.js +++ b/web/src/codesearch/codesearch_ui.js @@ -515,12 +515,14 @@ var SearchState = Backbone.Model.extend({ return '/search'; var base = '/search'; + if (current.repo && current.repo.length) { + q.repo = current.repo; + } if (current.q !== "") { q.q = current.q; q.fold_case = current.fold_case; q.regex = current.regex; q.context = this.get('context'); - q.repo = current.repo; } if (current.backend) { @@ -910,6 +912,7 @@ var CodesearchUI = function() { setTimeout(function() { RepoSelector.init(); CodesearchUI.update_repo_options(); + CodesearchUI.render_repo_presets(); CodesearchUI.init_query(); }, 0); @@ -1108,6 +1111,21 @@ var CodesearchUI = function() { search_done: function(search, time, search_type, why) { CodesearchUI.state.handle_done(search, time, search_type, why); }, + render_repo_presets: function() { + var presets = CodesearchUI.repoPresets; + if (!presets || !presets.length) return; + + var container = $('
'); + presets.forEach(function(preset) { + var btn = $('').text(preset.name); + btn.on('click', function() { + RepoSelector.updateSelected(preset.repos); + CodesearchUI.newsearch(); + }); + container.append(btn); + }); + $('#repos').closest('.search-option').append(container); + }, repo_urls: {} }; }(); @@ -1117,6 +1135,26 @@ var ivr = {}; initData.internal_view_repos.forEach(function(name) { ivr[name] = true; }); CodesearchUI.internalViewRepos = ivr; CodesearchUI.defaultSearchRepos = initData.default_search_repos; + +// Repo presets: each entry adds a button that selects a predefined set of repos. +// Edit this array to add/remove/rename presets. +CodesearchUI.repoPresets = [ + {name: 'SDKs', repos: [ + 'getsentry/sentry-cocoa', 'getsentry/sentry-python', 'getsentry/sentry-ruby', + 'getsentry/sentry-rust', 'getsentry/sentry-dotnet', 'getsentry/sentry-java', + 'getsentry/sentry-javascript', 'getsentry/sentry-go', 'getsentry/sentry-php', + 'getsentry/sentry-native', 'getsentry/sentry-react-native', 'getsentry/sentry-dart', + 'getsentry/sentry-unity', 'getsentry/sentry-elixir', 'getsentry/sentry-laravel', + ]}, + {name: 'Fullstack', repos: [ + 'getsentry/sentry', 'getsentry/relay', 'getsentry/snuba', + 'getsentry/arroyo', 'getsentry/symbolicator', 'getsentry/objectstore', + ]}, + {name: 'Tools', repos: [ + 'getsentry/sentry-cli', 'getsentry/sentry-mcp', 'getsentry/craft', + 'getsentry/self-hosted', + ]}, +]; CodesearchUI.linkConfigs = (initData.link_configs || []).map(function(link_config) { if (link_config.whitelist_pattern) { link_config.whitelist_pattern = new RegExp(link_config.whitelist_pattern); diff --git a/web/src/codesearch/repo_selector.js b/web/src/codesearch/repo_selector.js index 1b41d310..fa08765d 100644 --- a/web/src/codesearch/repo_selector.js +++ b/web/src/codesearch/repo_selector.js @@ -60,7 +60,7 @@ function updateOptions(newOptions) { var parts = newOptions[i].split('/'); var group = parts.slice(0, parts.length - 1).join('/') + '/'; var option = parts[parts.length - 1]; - var value = group + option; + var value = group === '/' ? option : group + option; if (group !== '/' && group !== currentGroup) { if (currentGroup !== null && currentGroup !== '/') {