Skip to content

Commit

Permalink
Update One Box Code Snippets UI (#5753)
Browse files Browse the repository at this point in the history
closes:
https://linear.app/sourcegraph/issue/SRCH-1100/one-box-search-improvements-correct-issues-from-dog-fooding
closes:
https://linear.app/sourcegraph/issue/SRCH-1115/make-individual-search-results-in-one-box-collapsible

- Bring back the result hide functionality
- Include the ask Cody button at bottom of file
- Limit displayed results to 5, with show more button
- File path background should be opaque.

Designs:
https://www.figma.com/design/eR495BJclVpdGdXf4lhSsH/One-box?node-id=632-7402&node-type=canvas&t=gs8ttscPyqpA2YTj-0

Loom: https://www.loom.com/share/1c1d01bc6f734eee8ff0f54cae8adf96

## Test plan

- Enable Onebox and execute code search intent
- Make sure only first 5 results are shown and "show more" and "ask the
llm" button are shown at the bottom.
- Make sure the code snippets now have the dark bg same as the code
snippets returned in the Cody response.
- The file link does not have any border now. 
- Test the hide code snippet function by clicking on the caret left to
the file link.

## Changelog
  • Loading branch information
thenamankumar authored Oct 3, 2024
1 parent c24f9b3 commit 3c8d530
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 68 deletions.
1 change: 1 addition & 0 deletions vscode/webviews/chat/Transcript.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ const TranscriptInteraction: FC<TranscriptInteractionProps> = memo(props => {
isForFirstMessage={humanMessage.index === 0}
showSnippets={experimentalOneBoxEnabled && humanMessage.intent === 'search'}
defaultOpen={experimentalOneBoxEnabled && humanMessage.intent === 'search'}
reSubmitWithChatIntent={reSubmitWithChatIntent}
isContextLoading={isContextLoading}
/>
)}
Expand Down
79 changes: 56 additions & 23 deletions vscode/webviews/chat/cells/contextCell/ContextCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ import {
AccordionItem,
AccordionTrigger,
} from '../../../components/shadcn/ui/accordion'
import { Button } from '../../../components/shadcn/ui/button'
import { Tooltip, TooltipContent, TooltipTrigger } from '../../../components/shadcn/ui/tooltip'
import { SourcegraphLogo } from '../../../icons/SourcegraphLogo'
import { useTelemetryRecorder } from '../../../utils/telemetry'
import { useConfig } from '../../../utils/useConfig'
import { useExperimentalOneBox } from '../../../utils/useExperimentalOneBox'
import { CodyIcon } from '../../components/CodyIcon'
import { LoadingDots } from '../../components/LoadingDots'
import { Cell } from '../Cell'
import { NON_HUMAN_CELL_AVATAR_SIZE } from '../messageCell/assistant/AssistantMessageCell'
Expand All @@ -33,6 +35,7 @@ export const ContextCell: FunctionComponent<{
className?: string
defaultOpen?: boolean
showSnippets?: boolean
reSubmitWithChatIntent?: () => void

/** For use in storybooks only. */
__storybook__initialOpen?: boolean
Expand All @@ -45,6 +48,7 @@ export const ContextCell: FunctionComponent<{
className,
defaultOpen,
__storybook__initialOpen,
reSubmitWithChatIntent,
showSnippets = false,
isContextLoading,
}) => {
Expand Down Expand Up @@ -105,6 +109,9 @@ export const ContextCell: FunctionComponent<{
},
[telemetryRecorder, oneboxEnabled]
)

const [showAllResults, setShowAllResults] = useState(false)

return (
<div>
{(contextItemsToDisplay === undefined || contextItemsToDisplay.length !== 0) && (
Expand Down Expand Up @@ -176,29 +183,55 @@ export const ContextCell: FunctionComponent<{
</div>
)}
<ul className="tw-list-none tw-flex tw-flex-col tw-gap-2 tw-pt-2">
{contextItemsToDisplay?.map((item, i) => (
<li
// biome-ignore lint/suspicious/noArrayIndexKey: stable order
key={i}
data-testid="context-item"
>
<FileContextItem
item={item}
showSnippets={showSnippets}
/>
{internalDebugContext &&
item.metadata &&
item.metadata.length > 0 && (
<span
className={
styles.contextItemMetadata
}
>
{item.metadata.join(', ')}
</span>
)}
</li>
))}
{contextItemsToDisplay?.map((item, i) =>
!showSnippets || showAllResults || i < 5 ? (
<li
// biome-ignore lint/correctness/useJsxKeyInIterable:
// biome-ignore lint/suspicious/noArrayIndexKey: stable order
key={i}
data-testid="context-item"
>
<FileContextItem
item={item}
showSnippets={showSnippets}
/>
{internalDebugContext &&
item.metadata &&
item.metadata.length > 0 && (
<span
className={
styles.contextItemMetadata
}
>
{item.metadata.join(', ')}
</span>
)}
</li>
) : null
)}
{showSnippets &&
!showAllResults &&
contextItemsToDisplay &&
contextItemsToDisplay.length > 5 ? (
<div className="tw-flex tw-justify-between">
<Button
variant="link"
onClick={() => setShowAllResults(true)}
>
Show {contextItemsToDisplay.length - 5} more
results
</Button>
<Button
size="sm"
variant="outline"
className="tw-text-prmary tw-flex tw-gap-2 tw-items-center"
onClick={reSubmitWithChatIntent}
>
<CodyIcon className="tw-text-link" />
Ask the LLM
</Button>
</div>
) : null}
{!isForFirstMessage && (
<span
className={clsx(
Expand Down
19 changes: 9 additions & 10 deletions vscode/webviews/components/codeSnippet/CodeSnippet.module.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
:root {
--cody-chat-code-background: var(--vscode-textCodeBlock-background);
--cody-chat-code-header-background: var(--vscode-titleBar-inactiveBackground);
--cody-chat-code-background: var(--code-background);
--cody-chat-code-header-background: var(--vscode-editorGroupHeader-tabsBackground);
--cody-chat-code-subtle-background: var(--vscode-titleBar-inactiveBackground);
--cody-chat-code-border-color: var(--vscode-widget-border);
--cody-chat-code-text-muted: var(--vscode-input-placeholderForeground);
Expand All @@ -11,12 +11,9 @@

.result-container {
contain: paint;
border-radius: 4px;
border: solid 1px var(--cody-chat-code-border-color);

:global(.match-highlight) {
color: var(--cody-chat-code-text-highlighted);
background-color: var(--cody-chat-code-mark-background);
background-color: var(--cody-chat-code-mark-background) !important;
}

:global(.sr-only) {
Expand All @@ -37,14 +34,11 @@
display: flex;
align-items: center;
flex-wrap: wrap;

position: sticky;
top: 0;

/* Show on top of search result contents */
z-index: 1;

border-bottom: 1px solid var(--cody-chat-code-border-color);
background-color: var(--cody-chat-code-header-background);

&-title {
Expand All @@ -55,7 +49,13 @@
}

.result {
border-radius: 4px;
border: solid 1px var(--cody-chat-code-border-color);
background-color: var(--cody-chat-code-background);

code {
padding: 0 !important;
}
}

.search-result-match {
Expand Down Expand Up @@ -84,7 +84,6 @@
cursor: pointer;
&:hover {
text-decoration: none;
background-color: var(--cody-chat-code-subtle-background);
}
}

Expand Down
23 changes: 16 additions & 7 deletions vscode/webviews/components/codeSnippet/CodeSnippet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export const FileContentSearchResult: FC<PropsWithChildren<FileContentSearchResu
const expandedHighlightCount = countHighlightRanges(expandedGroups)
const collapsedHighlightCount = countHighlightRanges(collapsedGroups)
const hiddenMatchesCount = expandedHighlightCount - collapsedHighlightCount
const collapsible = !showAllMatches && expandedHighlightCount > collapsedHighlightCount
const expandable = !showAllMatches && expandedHighlightCount > collapsedHighlightCount

useEffect(() => setExpanded(allExpanded || defaultExpanded), [allExpanded, defaultExpanded])

Expand Down Expand Up @@ -147,8 +147,8 @@ export const FileContentSearchResult: FC<PropsWithChildren<FileContentSearchResu
})
}, [fetchHighlightedFileLineRanges, hasBeenVisible, unhighlightedGroups, result])

const toggle = useCallback((): void => {
if (collapsible) {
const toggleExpand = useCallback((): void => {
if (expandable) {
setExpanded(expanded => !expanded)
}

Expand All @@ -163,7 +163,9 @@ export const FileContentSearchResult: FC<PropsWithChildren<FileContentSearchResu
})
}, 0)
}
}, [collapsible, expanded])
}, [expandable, expanded])

const [hidden, setHidden] = useState(false)

const title = (
<RepoFileLink
Expand All @@ -178,6 +180,8 @@ export const FileContentSearchResult: FC<PropsWithChildren<FileContentSearchResu
: undefined
}
className={styles.titleInner}
collapsed={hidden}
onToggleCollapse={() => setHidden(current => !current)}
/>
)

Expand All @@ -191,6 +195,7 @@ export const FileContentSearchResult: FC<PropsWithChildren<FileContentSearchResu
className={className}
rankingDebug={result.debug}
repoLastFetched={result.repoLastFetched}
collapsed={hidden}
>
<VisibilitySensor
partialVisibility={true}
Expand All @@ -203,7 +208,7 @@ export const FileContentSearchResult: FC<PropsWithChildren<FileContentSearchResu
result={result}
grouped={expanded ? expandedGroups : collapsedGroups}
/>
{collapsible && (
{expandable && (
<button
type="button"
className={clsx(
Expand All @@ -212,7 +217,7 @@ export const FileContentSearchResult: FC<PropsWithChildren<FileContentSearchResu
styles.clickable,
{ [styles.toggleMatchesButtonExpanded]: expanded }
)}
onClick={toggle}
onClick={toggleExpand}
>
<span className={styles.toggleMatchesButtonText}>
{expanded
Expand Down Expand Up @@ -241,6 +246,7 @@ interface ResultContainerProps {
rankingDebug?: string
actions?: ReactElement | boolean
onResultClicked?: () => void
collapsed: boolean
}

const accessibleResultType: Record<SearchMatch['type'], string> = {
Expand All @@ -263,6 +269,7 @@ const ResultContainer: ForwardReferenceExoticComponent<
actions,
as: Component = 'div',
onResultClicked,
collapsed,
} = props

const formattedRepositoryStarCount = formatRepositoryStarCount(repoStars)
Expand Down Expand Up @@ -290,7 +297,9 @@ const ResultContainer: ForwardReferenceExoticComponent<
)}
</header>
{rankingDebug && <div>{rankingDebug}</div>}
{children && <div className={clsx(styles.result, resultClassName)}>{children}</div>}
{children && !collapsed && (
<div className={clsx(styles.result, resultClassName)}>{children}</div>
)}
</article>
</Component>
)
Expand Down
48 changes: 40 additions & 8 deletions vscode/webviews/components/codeSnippet/components/CodeExcerpt.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type FC, useLayoutEffect, useMemo, useState } from 'react'
import { type FC, useCallback, useLayoutEffect, useMemo, useState } from 'react'

import { clsx } from 'clsx'

Expand All @@ -19,6 +19,7 @@ interface Props {
plaintextLines: string[]
highlightedLines?: string[]
onCopy?: () => void
onLineClick?: (line: number) => void
}

interface HighlightRange {
Expand All @@ -44,22 +45,53 @@ interface HighlightRange {
* A code excerpt that displays syntax highlighting and match range highlighting.
*/
export const CodeExcerpt: FC<Props> = props => {
const { plaintextLines, highlightedLines, startLine, endLine, highlightRanges, className } = props
const {
plaintextLines,
highlightedLines,
startLine,
endLine,
highlightRanges,
className,
onLineClick,
} = props

const [tableContainerElement, setTableContainerElement] = useState<HTMLElement | null>(null)

const handleLineClick = useCallback(
(e: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>) => {
if (e.target instanceof HTMLElement && e.target.tagName === 'TD') {
const line = e.target.getAttribute('data-line')
if (line) {
onLineClick?.(Number.parseInt(line))
}
}
},
[onLineClick]
)

const table = useMemo(
() =>
highlightedLines ? (
// biome-ignore lint/security/noDangerouslySetInnerHtml:
<table dangerouslySetInnerHTML={{ __html: highlightedLines.join('') }} />
<table
// biome-ignore lint/security/noDangerouslySetInnerHtml:
dangerouslySetInnerHTML={{ __html: highlightedLines.join('') }}
onClick={handleLineClick}
onKeyDown={handleLineClick}
/>
) : (
<table>
<tbody>
{plaintextLines.map((line, i) => (
// biome-ignore lint/suspicious/noArrayIndexKey:
<tr key={startLine + i}>
<td className="line" data-line={startLine + i + 1} />
<tr
// biome-ignore lint/suspicious/noArrayIndexKey:
key={startLine + i}
>
<td
className="line hover:tw-underline tw-cursor-pointer"
data-line={startLine + i + 1}
onClick={handleLineClick}
onKeyDown={handleLineClick}
/>
<td className="code">
<span className="hl-text hl-plain">{line}</span>
</td>
Expand All @@ -68,7 +100,7 @@ export const CodeExcerpt: FC<Props> = props => {
</tbody>
</table>
),
[plaintextLines, highlightedLines, startLine]
[plaintextLines, highlightedLines, startLine, handleLineClick]
)

// Highlight the search matches
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
.chunk {
position: relative;
overflow-x: auto;
padding: 0.25rem 0.5rem;
background-color: var(--cody-chat-code-background);

&:first-child {
padding-top: 0.5rem;
}

&:last-child {
padding-bottom: 0.5rem;
}
background-color: var(--code-background);
}
Loading

0 comments on commit 3c8d530

Please sign in to comment.