feat: Improve GitHub issues view with validation indicators and Markdown support

- Added an `isValidating` prop to the `IssueRow` component to indicate ongoing validation for issues.
- Introduced a visual indicator for validation in progress, enhancing user feedback during analysis.
- Updated the `ValidationDialog` to render validation reasoning and suggested fixes using Markdown for better formatting and readability.
This commit is contained in:
Kacper
2025-12-23 22:49:37 +01:00
parent dd27c5c4fb
commit 65319f93b4
2 changed files with 21 additions and 7 deletions

View File

@@ -493,6 +493,7 @@ export function GitHubIssuesView() {
onOpenExternal={() => handleOpenInGitHub(issue.url)} onOpenExternal={() => handleOpenInGitHub(issue.url)}
formatDate={formatDate} formatDate={formatDate}
cachedValidation={cachedValidations.get(issue.number)} cachedValidation={cachedValidations.get(issue.number)}
isValidating={validatingIssues.has(issue.number)}
/> />
))} ))}
@@ -511,6 +512,7 @@ export function GitHubIssuesView() {
onOpenExternal={() => handleOpenInGitHub(issue.url)} onOpenExternal={() => handleOpenInGitHub(issue.url)}
formatDate={formatDate} formatDate={formatDate}
cachedValidation={cachedValidations.get(issue.number)} cachedValidation={cachedValidations.get(issue.number)}
isValidating={validatingIssues.has(issue.number)}
/> />
))} ))}
</> </>
@@ -776,6 +778,8 @@ interface IssueRowProps {
formatDate: (date: string) => string; formatDate: (date: string) => string;
/** Cached validation for this issue (if any) */ /** Cached validation for this issue (if any) */
cachedValidation?: StoredValidation | null; cachedValidation?: StoredValidation | null;
/** Whether validation is currently running for this issue */
isValidating?: boolean;
} }
function IssueRow({ function IssueRow({
@@ -785,6 +789,7 @@ function IssueRow({
onOpenExternal, onOpenExternal,
formatDate, formatDate,
cachedValidation, cachedValidation,
isValidating,
}: IssueRowProps) { }: IssueRowProps) {
// Check if validation is unviewed (exists, not stale, not viewed) // Check if validation is unviewed (exists, not stale, not viewed)
const hasUnviewedValidation = const hasUnviewedValidation =
@@ -852,8 +857,16 @@ function IssueRow({
</span> </span>
)} )}
{/* Validating indicator */}
{isValidating && (
<span className="inline-flex items-center gap-1 px-1.5 py-0.5 text-[10px] font-medium rounded-full bg-primary/10 text-primary border border-primary/20 animate-in fade-in duration-200">
<Loader2 className="h-3 w-3 animate-spin" />
Analyzing...
</span>
)}
{/* Unviewed validation indicator */} {/* Unviewed validation indicator */}
{hasUnviewedValidation && ( {!isValidating && hasUnviewedValidation && (
<span className="inline-flex items-center gap-1 px-1.5 py-0.5 text-[10px] font-medium rounded-full bg-amber-500/10 text-amber-500 border border-amber-500/20 animate-in fade-in duration-200"> <span className="inline-flex items-center gap-1 px-1.5 py-0.5 text-[10px] font-medium rounded-full bg-amber-500/10 text-amber-500 border border-amber-500/20 animate-in fade-in duration-200">
<Sparkles className="h-3 w-3" /> <Sparkles className="h-3 w-3" />
Analysis Ready Analysis Ready

View File

@@ -7,6 +7,7 @@ import {
DialogTitle, DialogTitle,
} from '@/components/ui/dialog'; } from '@/components/ui/dialog';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { Markdown } from '@/components/ui/markdown';
import { import {
CheckCircle2, CheckCircle2,
XCircle, XCircle,
@@ -162,9 +163,9 @@ export function ValidationDialog({
<Lightbulb className="h-4 w-4 text-muted-foreground" /> <Lightbulb className="h-4 w-4 text-muted-foreground" />
Analysis Analysis
</h4> </h4>
<p className="text-sm text-muted-foreground leading-relaxed whitespace-pre-wrap"> <div className="bg-muted/30 p-3 rounded-lg border border-border">
{validationResult.reasoning} <Markdown>{validationResult.reasoning}</Markdown>
</p> </div>
</div> </div>
{/* Related Files */} {/* Related Files */}
@@ -191,9 +192,9 @@ export function ValidationDialog({
{validationResult.suggestedFix && ( {validationResult.suggestedFix && (
<div className="space-y-2"> <div className="space-y-2">
<h4 className="text-sm font-medium">Suggested Approach</h4> <h4 className="text-sm font-medium">Suggested Approach</h4>
<p className="text-sm text-muted-foreground leading-relaxed whitespace-pre-wrap bg-muted/30 p-3 rounded-lg border border-border"> <div className="bg-muted/30 p-3 rounded-lg border border-border">
{validationResult.suggestedFix} <Markdown>{validationResult.suggestedFix}</Markdown>
</p> </div>
</div> </div>
)} )}