Skip to content

Commit 9bdad28

Browse files
authored
Merge pull request liam-hq#1161 from liam-hq/devin/1743768295-add-diff-display
Add diff display between original document and knowledge suggestion
2 parents 772ac04 + 34df73d commit 9bdad28

File tree

6 files changed

+156
-3
lines changed

6 files changed

+156
-3
lines changed

docs/packages-license.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33

44
## Summary
5-
* 1323 MIT
5+
* 1324 MIT
66
* 207 Apache 2.0
77
* 82 ISC
88
* 32 New BSD
@@ -5151,6 +5151,17 @@ LGPL-3.0-or-later permitted
51515151

51525152

51535153

5154+
<a name="@types/diff"></a>
5155+
### @types/diff v7.0.2
5156+
####
5157+
5158+
##### Paths
5159+
* /home/runner/work/liam/liam
5160+
5161+
<a href="http://opensource.org/licenses/mit-license">MIT</a> permitted
5162+
5163+
5164+
51545165
<a name="@types/escodegen"></a>
51555166
### @types/escodegen v0.0.6
51565167
####

frontend/apps/app/features/projects/pages/KnowledgeSuggestionDetailPage/KnowledgeSuggestionDetailPage.module.css

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,30 @@
157157
border-radius: 0.375rem;
158158
font-weight: 600;
159159
}
160+
161+
.diffContent {
162+
padding: 1.25rem;
163+
background-color: var(--color-background-code);
164+
border-radius: 0.5rem;
165+
overflow: auto;
166+
font-family: monospace;
167+
font-size: 0.875rem;
168+
line-height: 1.6;
169+
white-space: pre-wrap;
170+
word-break: break-word;
171+
border: 1px solid rgba(0, 0, 0, 0.1);
172+
}
173+
174+
.diffAdded {
175+
background-color: rgba(76, 175, 80, 0.2);
176+
color: #2e7d32;
177+
}
178+
179+
.diffRemoved {
180+
background-color: rgba(244, 67, 54, 0.2);
181+
color: #c62828;
182+
}
183+
184+
.diffUnchanged {
185+
color: var(--color-text-primary);
186+
}

frontend/apps/app/features/projects/pages/KnowledgeSuggestionDetailPage/KnowledgeSuggestionDetailPage.tsx

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { createClient } from '@/libs/db/server'
22
import { urlgen } from '@/utils/routes'
3+
import * as diffLib from 'diff'
34
import Link from 'next/link'
45
import { notFound } from 'next/navigation'
5-
import type { FC } from 'react'
6+
import type { FC, ReactNode } from 'react'
67
import { UserFeedbackClient } from '../../../../components/UserFeedbackClient'
78
import { approveKnowledgeSuggestion } from '../../actions/approveKnowledgeSuggestion'
9+
import { getOriginalDocumentContent } from '../../utils/getOriginalDocumentContent'
810
import styles from './KnowledgeSuggestionDetailPage.module.css'
911

1012
type Props = {
@@ -101,7 +103,20 @@ export const KnowledgeSuggestionDetailPage: FC<Props> = async ({
101103

102104
<div className={styles.contentSection}>
103105
<h2 className={styles.sectionTitle}>Content</h2>
104-
<pre className={styles.codeContent}>{suggestion.content}</pre>
106+
{suggestion.approvedAt ? (
107+
<pre className={styles.codeContent}>{suggestion.content}</pre>
108+
) : (
109+
<DiffDisplay
110+
originalContent={
111+
await getOriginalDocumentContent(
112+
projectId,
113+
suggestion.branchName,
114+
suggestion.path,
115+
)
116+
}
117+
newContent={suggestion.content}
118+
/>
119+
)}
105120
{/* Client-side user feedback component */}
106121
<div className={styles.feedbackSection}>
107122
<UserFeedbackClient traceId={suggestion.traceId} />
@@ -137,3 +152,53 @@ export const KnowledgeSuggestionDetailPage: FC<Props> = async ({
137152
</div>
138153
)
139154
}
155+
156+
interface DiffDisplayProps {
157+
originalContent: string | null
158+
newContent: string
159+
}
160+
161+
const DiffDisplay: FC<DiffDisplayProps> = ({ originalContent, newContent }) => {
162+
if (!originalContent) {
163+
return (
164+
<div className={styles.diffContent}>
165+
{newContent.split('\n').map((line) => (
166+
<div key={`added-${line}`} className={styles.diffAdded}>
167+
+ {line}
168+
</div>
169+
))}
170+
</div>
171+
)
172+
}
173+
174+
const diff = diffLib.diffTrimmedLines(originalContent, newContent)
175+
176+
return (
177+
<div className={styles.diffContent}>
178+
{diff.map((part, index) => {
179+
const className = part.added
180+
? styles.diffAdded
181+
: part.removed
182+
? styles.diffRemoved
183+
: styles.diffUnchanged
184+
185+
const prefix = part.added ? '+ ' : part.removed ? '- ' : ' '
186+
187+
return part.value.split('\n').map((line, lineIndex) => {
188+
if (lineIndex === part.value.split('\n').length - 1 && line === '') {
189+
return null
190+
}
191+
return (
192+
<div
193+
key={`${part.added ? 'added' : part.removed ? 'removed' : 'unchanged'}-${line}-${index}-${lineIndex}`}
194+
className={className}
195+
>
196+
{prefix}
197+
{line}
198+
</div>
199+
)
200+
})
201+
})}
202+
</div>
203+
)
204+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { getFileContent } from '@liam-hq/github'
2+
import { getProjectRepository } from '../../../app/(app)/app/projects/[projectId]/ref/[branchOrCommit]/docs/[...docFilePath]/getProjectRepository'
3+
4+
export async function getOriginalDocumentContent(
5+
projectId: string,
6+
branchOrCommit: string,
7+
docPath: string,
8+
): Promise<string | null> {
9+
try {
10+
const projectRepo = await getProjectRepository(projectId)
11+
if (!projectRepo) {
12+
console.error('Repository information not found')
13+
return null
14+
}
15+
16+
const { repository } = projectRepo
17+
const repositoryFullName = `${repository.owner}/${repository.name}`
18+
19+
const fileData = await getFileContent(
20+
repositoryFullName,
21+
docPath,
22+
branchOrCommit,
23+
repository.installationId,
24+
)
25+
26+
return fileData.content
27+
} catch (error) {
28+
console.error('Error fetching original document content:', error)
29+
return null
30+
}
31+
}

frontend/apps/app/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@
1818
"@sentry/nextjs": "8",
1919
"@trigger.dev/build": "3.3.17",
2020
"@trigger.dev/sdk": "3.3.17",
21+
"@types/diff": "7.0.2",
2122
"cheerio": "1.0.0",
2223
"clsx": "2.1.1",
2324
"date-fns": "4.1.0",
25+
"diff": "7.0.0",
2426
"dotenv": "16.4.7",
2527
"flags": "3.1.1",
2628
"langfuse": "3.37.1",

pnpm-lock.yaml

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)