Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.

Jdb/poc-inline-insights #39394

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions client/extension-api-types/src/textDocument.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,17 @@ export interface TextDocumentDecoration
/** The range that the decoration applies to. */
range: Range
}

export interface InsightDecoration
extends Pick<sourcegraph.TextDocumentDecoration, Exclude<keyof sourcegraph.TextDocumentDecoration, 'range'>> {
/** The range that the decoration applies to. */
range: Range

/** The raw html to render in line. */
content: JSX.Element

/** The JSX Element to render in the popover */
popover: JSX.Element

trigger?: 'hover' | 'click'
}
10 changes: 6 additions & 4 deletions client/shared/src/api/extension/api/decorations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
} from 'sourcegraph'

import { hasProperty } from '@sourcegraph/common'
import { TextDocumentDecoration } from '@sourcegraph/extension-api-types'
import { InsightDecoration, TextDocumentDecoration } from '@sourcegraph/extension-api-types'

// LINE AND COLUMN DECORATIONS

Expand Down Expand Up @@ -46,15 +46,17 @@ export function decorationAttachmentStyleForTheme(
return { ...base, ...overrides }
}

export type DecorationMapByLine = ReadonlyMap<number, TextDocumentDecoration[]>
export type DecorationMapByLine = ReadonlyMap<number, TextDocumentDecoration[] | InsightDecoration[]>

/**
* @returns Map from 1-based line number to non-empty array of TextDocumentDecoration for that line
*
* @todo this does not handle decorations that span multiple lines
*/
export const groupDecorationsByLine = (decorations: TextDocumentDecoration[] | null): DecorationMapByLine => {
const grouped = new Map<number, TextDocumentDecoration[]>()
export const groupDecorationsByLine = (
decorations: (TextDocumentDecoration | InsightDecoration)[] | null
): DecorationMapByLine => {
const grouped = new Map<number, (TextDocumentDecoration | InsightDecoration)[]>()
for (const decoration of decorations || []) {
const lineNumber = decoration.range.start.line + 1
const decorationsForLine = grouped.get(lineNumber)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.insight-decoration-content {
background-color: var(--primary-4);
padding: 1px 3px;
cursor: pointer;
}
11 changes: 11 additions & 0 deletions client/web/src/insights/components/InsightDecorationContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { forwardRef, PropsWithChildren } from 'react'

import styles from './InsightDecorationContent.module.scss'

export const InsightDecorationContent = forwardRef<HTMLSpanElement, PropsWithChildren<{}>>(({ children }, ref) => (
<span ref={ref} className={styles.insightDecorationContent}>
{children}
</span>
))

InsightDecorationContent.displayName = 'InsightDecorationContent'
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
.insight-decoration-popover {
background-color: var(--color-bg-1);
padding: 12px;
border-radius: 4px;
border: solid 1px var(--border-color);
box-shadow: var(--dropdown-shadow);
}

.insight-decoration-line-ref {
color: var(--text-muted);
font-size: 0.625rem;
font-weight: 400;
}

.insight-decoration-link {
font-size: 0.75rem;
font-weight: 400;
cursor: pointer;
}

.insight-decoration-row {
padding-left: 16px;
margin-left: 4px;
border-left: solid 2px var(--border-color-2);
}

.insight-decoration-section {
margin-bottom: 8px;
}
48 changes: 48 additions & 0 deletions client/web/src/insights/components/InsightDecorationPopover.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { FC } from 'react'

import classNames from 'classnames'
import OpenInNewIcon from 'mdi-react/OpenInNewIcon'

import { Link } from '@sourcegraph/wildcard'

import styles from './InsightDecorationPopover.module.scss'

interface TokenInsight {
id: string
name: string
url: string
}

interface Token {
token: string
insights: TokenInsight[]
}

interface InsightDecorationPopoverProps {
tokens: Token[]
}

export const InsightDecorationPopover: FC<InsightDecorationPopoverProps> = ({ tokens }) => (
<div className={styles.insightDecorationPopover}>
{tokens.map(token => (
<div key={token.token} className={styles.insightDecorationSection}>
<div>
<span>{'{}'}</span>
<small className="ml-2">
<strong>{token.token}</strong>
</small>
</div>
<div className={classNames(styles.insightDecorationRow, styles.insightDecorationLineRef)}>
Insights referencing this line ({token.insights.length})
</div>
{token.insights.map(insight => (
<div key={insight.id} className={classNames(styles.insightDecorationRow)}>
<Link to={insight.url} className={styles.insightDecorationLink}>
{insight.name} <OpenInNewIcon size={12} />
</Link>
</div>
))}
</div>
))}
</div>
)
37 changes: 37 additions & 0 deletions client/web/src/insights/hooks/useCodeInsightsData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { QueryResult } from '@apollo/client'

import { gql, useQuery } from '@sourcegraph/http-client'

import { GetRelatedInsightsInlineResult } from '../../graphql-operations'

const RELATED_INSIGHTS_INLINE_QUERY = gql`
query GetRelatedInsightsInline($input: RelatedInsightsInput!) {
relatedInsightsInline(input: $input) {
viewId
title
lineNumbers
text
}
}
`

interface UseCodeInsightsDataInput {
file: string
revision: string
repo: string
}

export const useCodeInsightsData = ({
file,
revision,
repo,
}: UseCodeInsightsDataInput): QueryResult<GetRelatedInsightsInlineResult> =>
useQuery(RELATED_INSIGHTS_INLINE_QUERY, {
variables: {
input: {
file,
revision,
repo,
},
},
})
Loading