Fix resolved items not persisting in proof report UI after refresh

Thread resolvedItems from App → Campaigns → ProofDetailView → FeedbackReport
→ SubReviewCard so that issues previously marked as resolved are restored
from the database on page load instead of resetting to actionable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
michael 2026-02-16 07:39:34 -06:00
parent 3e548bc949
commit 941f84d7ed
3 changed files with 47 additions and 18 deletions

View file

@ -819,6 +819,7 @@ const App: React.FC = () => {
onFlagSubmit={handleFlagSubmit}
onResolveSubmit={handleResolveSubmit}
flaggedItems={flaggedItems}
resolvedItems={resolvedItems}
/>;
case 'WIP Reviewer':
return <WIPReviewer dropdownOptions={dropdownOptions} msalInstance={msalInstance} />;

View file

@ -1353,7 +1353,8 @@ const ProofDetailView: React.FC<{
onFlagSubmit: (flagData: Omit<FlaggedItem, 'id' | 'timestamp' | 'submitter' | 'submitAgency'>) => void;
onResolveSubmit: (resolveData: Omit<ResolvedItem, 'id' | 'timestamp' | 'submitter' | 'submitAgency'>) => void;
flaggedItems: FlaggedItem[];
}> = ({ campaignName, proof, onBack, onNewVersionUpload, isUploadingNewVersion, onFlagSubmit, onResolveSubmit, flaggedItems }) => {
resolvedItems: ResolvedItem[];
}> = ({ campaignName, proof, onBack, onNewVersionUpload, isUploadingNewVersion, onFlagSubmit, onResolveSubmit, flaggedItems, resolvedItems }) => {
const getInitialVersionIndex = () => {
if (proof.initialVersion && proof.versions) {
@ -1682,6 +1683,7 @@ const ProofDetailView: React.FC<{
onFlagSubmit={handleFlagSubmitWrapper}
onResolveSubmit={handleResolveSubmitWrapper}
flaggedItems={flaggedItems}
resolvedItems={resolvedItems}
proofName={proof.proofName}
version={selectedVersion.version}
/>
@ -1711,6 +1713,7 @@ interface CampaignsProps {
onFlagSubmit: (flagData: Omit<FlaggedItem, 'id' | 'timestamp' | 'submitter' | 'submitAgency'>) => void;
onResolveSubmit: (resolveData: Omit<ResolvedItem, 'id' | 'timestamp' | 'submitter' | 'submitAgency'>) => void;
flaggedItems: FlaggedItem[];
resolvedItems: ResolvedItem[];
}
export const Campaigns: React.FC<CampaignsProps> = ({
@ -1732,6 +1735,7 @@ export const Campaigns: React.FC<CampaignsProps> = ({
onFlagSubmit,
onResolveSubmit,
flaggedItems,
resolvedItems,
}) => {
const [isModalOpen, setIsModalOpen] = useState(false);
@ -1761,6 +1765,7 @@ export const Campaigns: React.FC<CampaignsProps> = ({
onFlagSubmit={onFlagSubmit}
onResolveSubmit={onResolveSubmit}
flaggedItems={flaggedItems}
resolvedItems={resolvedItems}
/>;
}

View file

@ -1,5 +1,5 @@
import React, { useState, useEffect } from 'react';
import type { AgentReview, SubReview, RagStatus, OverallStatus, FlaggedItem } from '../types';
import type { AgentReview, SubReview, RagStatus, OverallStatus, FlaggedItem, ResolvedItem } from '../types';
import { CheckCircleIcon, ExclamationTriangleIcon, InformationCircleIcon } from './icons/StatusIcons';
import { FlagIcon } from './icons/FlagIcon';
import { XIcon } from './icons/XIcon';
@ -273,7 +273,8 @@ const SubReviewCard: React.FC<{
onFlag: () => void;
onResolve: (issueText: string, reason: string) => void;
isFlagged?: boolean;
}> = ({ title, review, onFlag, onResolve, isFlagged }) => {
resolvedItems?: ResolvedItem[];
}> = ({ title, review, onFlag, onResolve, isFlagged, resolvedItems = [] }) => {
interface IssueState {
text: string;
status: 'actionable' | 'resolved';
@ -292,27 +293,43 @@ const SubReviewCard: React.FC<{
const [newCollapsed, setNewCollapsed] = useState(false);
useEffect(() => {
const findResolution = (text: string): ResolvedItem | undefined =>
resolvedItems.find(r => r.issue === text);
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
}));
const outstandingIssues: IssueState[] = (review.outstandingIssues || []).map(text => {
const match = findResolution(text);
return {
text,
status: match ? 'resolved' as const : 'actionable' as const,
reason: match?.resolution,
category: 'outstanding' as const
};
});
const newIssues: IssueState[] = (review.newIssues || []).map(text => {
const match = findResolution(text);
return {
text,
status: match ? 'resolved' as const : 'actionable' as const,
reason: match?.resolution,
category: 'new' as const
};
});
setIssues([...outstandingIssues, ...newIssues]);
} else {
// Original mode: use review.issues
setIssues(review.issues.map(text => ({ text, status: 'actionable', reason: undefined })));
setIssues(review.issues.map(text => {
const match = findResolution(text);
return {
text,
status: match ? 'resolved' as const : 'actionable' as const,
reason: match?.resolution
};
}));
}
setCurrentStatus(review.ragStatus);
}, [review]);
}, [review, resolvedItems]);
useEffect(() => {
if (review.ragStatus === 'Error') {
@ -793,15 +810,20 @@ export const FeedbackReport: React.FC<{
onFlagSubmit: (agentName: string, comments: string) => void;
onResolveSubmit: (agentName: string, issueText: string, reason: string) => void;
flaggedItems?: FlaggedItem[];
resolvedItems?: ResolvedItem[];
proofName?: string;
version?: number;
}> = ({ feedback, onFlagSubmit, onResolveSubmit, flaggedItems = [], proofName, version }) => {
}> = ({ feedback, onFlagSubmit, onResolveSubmit, flaggedItems = [], resolvedItems = [], proofName, version }) => {
const flaggedAgents = new Set(
flaggedItems
.filter(f => f.proofName === proofName && f.version === version)
.map(f => f.agentFlagged)
);
const filteredResolvedItems = resolvedItems.filter(
r => r.proofName === proofName && r.version === version
);
const [flagModalState, setFlagModalState] = useState<{ isOpen: boolean; agentName: string }>({
isOpen: false,
agentName: '',
@ -861,6 +883,7 @@ export const FeedbackReport: React.FC<{
onFlag={() => handleOpenFlagModal(title)}
onResolve={(issueText, reason) => onResolveSubmit(title, issueText, reason)}
isFlagged={flaggedAgents.has(title)}
resolvedItems={filteredResolvedItems.filter(r => r.agent === title)}
/>
))}
</div>