|
2 | 2 | import type { ComponentProps } from 'svelte'
|
3 | 3 | import { writable } from 'svelte/store'
|
4 | 4 |
|
| 5 | + import { getButtonClassName } from '@sourcegraph/wildcard' |
| 6 | +
|
| 7 | + import { goto } from '$app/navigation' |
5 | 8 | import { page } from '$app/stores'
|
6 | 9 | import { sizeToFit } from '$lib/dom'
|
| 10 | + import { registerHotkey } from '$lib/Hotkey' |
7 | 11 | import Icon from '$lib/Icon.svelte'
|
8 | 12 | import GlobalHeaderPortal from '$lib/navigation/GlobalHeaderPortal.svelte'
|
9 |
| - import CodeHostIcon from '$lib/search/CodeHostIcon.svelte' |
10 | 13 | import { createScopeSuggestions } from '$lib/search/codemirror/suggestions'
|
11 | 14 | import SearchInput from '$lib/search/input/SearchInput.svelte'
|
12 | 15 | import { queryStateStore } from '$lib/search/state'
|
|
15 | 18 | import { default as TabsHeader } from '$lib/TabsHeader.svelte'
|
16 | 19 | import { TELEMETRY_RECORDER } from '$lib/telemetry'
|
17 | 20 | import { DropdownMenu, MenuLink } from '$lib/wildcard'
|
18 |
| - import { getButtonClassName } from '$lib/wildcard/Button' |
19 | 21 |
|
20 | 22 | import type { LayoutData } from './$types'
|
21 | 23 | import { setRepositoryPageContext, type RepositoryPageContext } from './context'
|
| 24 | + import RepoMenu from './RepoMenu.svelte' |
22 | 25 |
|
23 | 26 | interface MenuEntry {
|
24 | 27 | /**
|
|
50 | 53 | { path: '/-/stats/contributors', icon: ILucideUsers, label: 'Contributors', visibility: 'user' },
|
51 | 54 | ]
|
52 | 55 | const menuEntries: MenuEntry[] = [
|
53 |
| - { path: '/-/compare', icon: ILucideHistory, label: 'Compare', visibility: 'user' }, |
| 56 | + { path: '/-/compare', icon: ILucideGitCompare, label: 'Compare', visibility: 'user' }, |
54 | 57 | { path: '/-/own', icon: ILucideUsers, label: 'Ownership', visibility: 'admin' },
|
55 | 58 | { path: '/-/embeddings', icon: ILucideSpline, label: 'Embeddings', visibility: 'admin' },
|
56 |
| - { path: '/-/code-graph', icon: ILucideBrainCircuit, label: 'Code graph data', visibility: 'admin' }, |
| 59 | + { path: '/-/code-graph', icon: ILucideCodesandbox, label: 'Code graph data', visibility: 'admin' }, |
57 | 60 | { path: '/-/batch-changes', icon: ISgBatchChanges, label: 'Batch changes', visibility: 'admin' },
|
58 | 61 | { path: '/-/settings', icon: ILucideSettings, label: 'Settings', visibility: 'admin' },
|
59 | 62 | ]
|
|
97 | 100 | }))
|
98 | 101 | $: selectedTab = tabs.findIndex(tab => isActive(tab.href, $page.url))
|
99 | 102 |
|
100 |
| - $: ({ repoName, displayRepoName, revision, resolvedRevision } = data) |
| 103 | + $: ({ repoName, revision } = data) |
101 | 104 | $: query = `repo:${repositoryInsertText({ repository: repoName })}${revision ? `@${revision}` : ''} `
|
102 | 105 | $: queryState = queryStateStore({ query }, $settings)
|
103 | 106 | function handleSearchSubmit(): void {
|
104 | 107 | TELEMETRY_RECORDER.recordEvent('search', 'submit', {
|
105 | 108 | metadata: { source: TELEMETRY_SEARCH_SOURCE_TYPE['repo'] },
|
106 | 109 | })
|
107 | 110 | }
|
| 111 | +
|
| 112 | + registerHotkey({ |
| 113 | + keys: { |
| 114 | + key: 'ctrl+backspace', |
| 115 | + mac: 'cmd+backspace', |
| 116 | + }, |
| 117 | + ignoreInputFields: false, |
| 118 | + handler: () => { |
| 119 | + goto(data.repoURL) |
| 120 | + }, |
| 121 | + }) |
108 | 122 | </script>
|
109 | 123 |
|
110 | 124 | <GlobalHeaderPortal>
|
|
126 | 140 | },
|
127 | 141 | }}
|
128 | 142 | >
|
129 |
| - <a href={data.repoURL}> |
130 |
| - <CodeHostIcon repository={repoName} codeHost={resolvedRevision?.repo?.externalRepository?.serviceType} /> |
131 |
| - <h1>{displayRepoName}</h1> |
132 |
| - </a> |
| 143 | + <RepoMenu |
| 144 | + repoName={data.repoName} |
| 145 | + displayRepoName={data.displayRepoName} |
| 146 | + repoURL={data.repoURL} |
| 147 | + externalURL={data.resolvedRevision?.repo?.externalURLs?.[0].url} |
| 148 | + externalServiceKind={data.resolvedRevision?.repo?.externalURLs?.[0].serviceKind ?? undefined} |
| 149 | + /> |
133 | 150 |
|
134 | 151 | <TabsHeader id="repoheader" {tabs} selected={selectedTab} />
|
135 | 152 |
|
|
145 | 162 | {#if entry.visibility === 'user' || (entry.visibility === 'admin' && data.user?.siteAdmin)}
|
146 | 163 | {@const href = data.repoURL + entry.path}
|
147 | 164 | <MenuLink {href}>
|
148 |
| - <span class="overflow-entry" class:active={isActive(href, $page.url)}> |
| 165 | + <div class="overflow-entry"> |
149 | 166 | {#if entry.icon}
|
150 | 167 | <Icon icon={entry.icon} inline aria-hidden />
|
151 | 168 | {/if}
|
152 | 169 | <span>{entry.label}</span>
|
153 |
| - </span> |
| 170 | + </div> |
154 | 171 | </MenuLink>
|
155 | 172 | {/if}
|
156 | 173 | {/each}
|
|
176 | 193 | overflow: hidden;
|
177 | 194 | border-bottom: 1px solid var(--border-color);
|
178 | 195 | background-color: var(--color-bg-1);
|
179 |
| -
|
180 |
| - a { |
181 |
| - all: unset; |
182 |
| -
|
183 |
| - display: flex; |
184 |
| - align-items: center; |
185 |
| - gap: 0.5rem; |
186 |
| - padding: 0 1rem; |
187 |
| - cursor: pointer; |
188 |
| - &:hover { |
189 |
| - background-color: var(--color-bg-2); |
190 |
| - } |
191 |
| -
|
192 |
| - h1 { |
193 |
| - display: contents; |
194 |
| - font-size: 1rem; |
195 |
| - white-space: nowrap; |
196 |
| - color: var(--text-title); |
197 |
| - font-weight: normal; |
198 |
| - } |
199 |
| - } |
200 |
| -
|
201 |
| - :global([data-dropdown-trigger]) { |
202 |
| - height: 100%; |
203 |
| - align-self: stretch; |
204 |
| - padding: 0.5rem; |
205 |
| - --icon-fill-color: var(--text-muted); |
206 |
| - } |
207 | 196 | }
|
208 | 197 |
|
209 | 198 | .overflow-entry {
|
210 |
| - width: 100%; |
211 |
| - display: inline-block; |
212 |
| - padding: 0 0.25rem; |
213 |
| - border-radius: var(--border-radius); |
| 199 | + display: flex; |
| 200 | + gap: 0.5rem; |
| 201 | + align-items: center; |
214 | 202 | }
|
215 | 203 | </style>
|
0 commit comments