diff --git a/frontend/components/FeedbackReport.tsx b/frontend/components/FeedbackReport.tsx index 955a3a2..8ae18f8 100755 --- a/frontend/components/FeedbackReport.tsx +++ b/frontend/components/FeedbackReport.tsx @@ -241,9 +241,18 @@ const FlagIssueModal: React.FC<{ ); }; -const SubReviewCard: React.FC<{ - title: string; - review: SubReview; +// Helper function to detect revision mode (when revision data is present) +const hasRevisionData = (review: SubReview): boolean => { + return ( + (review.resolvedIssues && review.resolvedIssues.length > 0) || + (review.outstandingIssues && review.outstandingIssues.length > 0) || + (review.newIssues && review.newIssues.length > 0) + ); +}; + +const SubReviewCard: React.FC<{ + title: string; + review: SubReview; onFlag: () => void; onResolve: (issueText: string, reason: string) => void; }> = ({ title, review, onFlag, onResolve }) => { @@ -251,15 +260,39 @@ const SubReviewCard: React.FC<{ text: string; status: 'actionable' | 'resolved'; reason?: string; + category?: 'outstanding' | 'new'; // For revision mode } const [issues, setIssues] = useState([]); const [currentStatus, setCurrentStatus] = useState(review.ragStatus); const [isModalOpen, setIsModalOpen] = useState(false); const [activeIssueIndex, setActiveIssueIndex] = useState(null); - + + // Section collapse states for revision mode + const [resolvedCollapsed, setResolvedCollapsed] = useState(true); + const [outstandingCollapsed, setOutstandingCollapsed] = useState(false); + const [newCollapsed, setNewCollapsed] = useState(false); + useEffect(() => { - setIssues(review.issues.map(text => ({ text, status: 'actionable', reason: undefined }))); + if (hasRevisionData(review)) { + // Revision mode: populate from outstandingIssues and newIssues + const outstandingIssues: IssueState[] = (review.outstandingIssues || []).map(text => ({ + text, + status: 'actionable', + reason: undefined, + category: 'outstanding' as const + })); + const newIssues: IssueState[] = (review.newIssues || []).map(text => ({ + text, + status: 'actionable', + reason: undefined, + category: 'new' as const + })); + setIssues([...outstandingIssues, ...newIssues]); + } else { + // Original mode: use review.issues + setIssues(review.issues.map(text => ({ text, status: 'actionable', reason: undefined }))); + } setCurrentStatus(review.ragStatus); }, [review]); @@ -371,7 +404,211 @@ const SubReviewCard: React.FC<{ {formatFeedbackText(review.feedback)} - {currentStatus !== 'Error' && issues.length > 0 && ( + {/* Revision mode: Show categorized sections */} + {currentStatus !== 'Error' && hasRevisionData(review) && ( +
+ {/* Resolved Issues Section */} + {review.resolvedIssues && review.resolvedIssues.length > 0 && ( +
+ + {!resolvedCollapsed && ( +
    + {review.resolvedIssues.map((issueText, index) => ( +
  • + + + {issueText} + +
  • + ))} +
+ )} +
+ )} + + {/* Outstanding Issues Section */} + {issues.filter(i => i.category === 'outstanding').length > 0 && ( +
+ + {!outstandingCollapsed && ( +
    + {issues.filter(i => i.category === 'outstanding').map((issue, idx) => { + const actualIndex = issues.findIndex((i, index) => i === issue && index >= 0); + return ( +
  • + {issue.status === 'actionable' ? ( + + ) : ( + + )} +
    +
    + + {issue.text} + + {issue.status === 'actionable' ? ( + + ) : ( +
    + + +
    + Reason for resolution: + "{issue.reason}" +
    +
    + +
    + )} +
    +
    +
  • + ); + })} +
+ )} +
+ )} + + {/* New Issues Section */} + {issues.filter(i => i.category === 'new').length > 0 && ( +
+ + {!newCollapsed && ( +
    + {issues.filter(i => i.category === 'new').map((issue, idx) => { + const actualIndex = issues.findIndex((i, index) => i === issue && index >= 0); + return ( +
  • + {issue.status === 'actionable' ? ( + + ) : ( + + )} +
    +
    + + {issue.text} + + {issue.status === 'actionable' ? ( + + ) : ( +
    + + +
    + Reason for resolution: + "{issue.reason}" +
    +
    + +
    + )} +
    +
    +
  • + ); + })} +
+ )} +
+ )} + + {/* No issues state for revision mode */} + {issues.length === 0 && (!review.resolvedIssues || review.resolvedIssues.length === 0) && ( +
+ + No actionable issues found. +
+ )} +
+ )} + + {/* Original mode: Show single list (backward compatible) */} + {currentStatus !== 'Error' && !hasRevisionData(review) && issues.length > 0 && (
Actionable Issues
    @@ -418,7 +655,7 @@ const SubReviewCard: React.FC<{
)} - {currentStatus !== 'Error' && issues.length === 0 && ( + {currentStatus !== 'Error' && !hasRevisionData(review) && issues.length === 0 && (
No actionable issues found.