Skip to content

Commit 1450018

Browse files
committed
Make sure all reviews render correctly on the 'Review' tab
1 parent da5d4f6 commit 1450018

File tree

6 files changed

+78
-231
lines changed

6 files changed

+78
-231
lines changed

src/apps/review/src/lib/components/ChallengeDetailsContent/ChallengeDetailsContent.tsx

Lines changed: 2 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -247,71 +247,9 @@ export const ChallengeDetailsContent: FC<Props> = (props: Props) => {
247247
),
248248
[challengeInfo?.phases],
249249
)
250-
const disallowedReviewSets = useMemo<{
251-
disallowedReviewIds: Set<string>
252-
disallowedReviewPhaseIds: Set<string>
253-
}>(
254-
() => {
255-
const reviewIds = new Set<string>()
256-
const phaseIds = new Set<string>()
257-
const addReviewId = (id?: string): void => {
258-
if (id) {
259-
reviewIds.add(id)
260-
}
261-
}
262-
263-
const addPhaseId = (id?: string): void => {
264-
if (id) {
265-
phaseIds.add(id)
266-
}
267-
}
268-
269-
props.screening.forEach(entry => {
270-
addReviewId(entry.reviewId)
271-
addPhaseId(entry.reviewPhaseId)
272-
})
273-
props.checkpoint.forEach(entry => {
274-
addReviewId(entry.reviewId)
275-
addPhaseId(entry.reviewPhaseId)
276-
})
277-
props.checkpointReview.forEach(entry => {
278-
addReviewId(entry.reviewId)
279-
addPhaseId(entry.reviewPhaseId)
280-
})
281-
282-
return {
283-
disallowedReviewIds: reviewIds,
284-
disallowedReviewPhaseIds: phaseIds,
285-
}
286-
},
287-
[props.screening, props.checkpoint, props.checkpointReview],
288-
)
289-
const {
290-
disallowedReviewIds,
291-
disallowedReviewPhaseIds,
292-
}: {
293-
disallowedReviewIds: Set<string>
294-
disallowedReviewPhaseIds: Set<string>
295-
} = disallowedReviewSets
296250
const passesReviewTabGuards: (submission: SubmissionInfo) => boolean = useMemo(
297-
() => (submission: SubmissionInfo): boolean => {
298-
if (!shouldIncludeInReviewPhase(submission)) {
299-
return false
300-
}
301-
302-
const reviewId = submission.review?.id
303-
if (reviewId && disallowedReviewIds.has(reviewId)) {
304-
return false
305-
}
306-
307-
const reviewPhaseId = submission.review?.phaseId
308-
if (reviewPhaseId && disallowedReviewPhaseIds.has(reviewPhaseId)) {
309-
return false
310-
}
311-
312-
return true
313-
},
314-
[disallowedReviewIds, disallowedReviewPhaseIds],
251+
() => (submission: SubmissionInfo): boolean => shouldIncludeInReviewPhase(submission),
252+
[],
315253
)
316254
const {
317255
reviews: reviewTabReviews,

src/apps/review/src/lib/components/TableReview/TableReview.tsx

Lines changed: 4 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import classNames from 'classnames'
1414
import { TableMobile } from '~/apps/admin/src/lib/components/common/TableMobile'
1515
import { IsRemovingType } from '~/apps/admin/src/lib/models'
1616
import { MobileTableColumn } from '~/apps/admin/src/lib/models/MobileTableColumn.model'
17-
import { getRatingColor } from '~/libs/core'
1817
import { handleError, useWindowSize, WindowSize } from '~/libs/shared'
1918
import { IconOutline, Table, TableColumn } from '~/libs/ui'
2019

@@ -225,24 +224,6 @@ export const TableReview: FC<TableReviewProps> = (props: TableReviewProps) => {
225224
[datas, latestSubmissions, restrictToLatest],
226225
)
227226

228-
if (process.env.NODE_ENV !== 'production') {
229-
try {
230-
console.debug('[TableReview] submissionsForAggregation', submissionsForAggregation.map(submission => ({
231-
id: submission.id,
232-
reviewResourceId: submission.review?.resourceId,
233-
reviewHandle: submission.review?.reviewerHandle,
234-
reviewId: submission.review?.id,
235-
reviews: submission.reviews?.map(review => ({
236-
resourceId: review.resourceId,
237-
reviewerHandle: review.reviewerHandle,
238-
score: review.score,
239-
})),
240-
})))
241-
} catch {
242-
// ignore logging issues
243-
}
244-
}
245-
246227
const aggregatedSubmissionRows = useMemo<AggregatedSubmissionReviews[]>(() => (
247228
aggregateSubmissionReviews({
248229
mappingReviewAppeal,
@@ -299,65 +280,10 @@ export const TableReview: FC<TableReviewProps> = (props: TableReviewProps) => {
299280
renderLabel?: () => JSX.Element
300281
}
301282
const reviewerColumnMetadata = useMemo<ReviewerColumnMetadata[]>(() => (
302-
Array.from({ length: maxReviewCount }, (unused, index) => {
303-
const reviewerDetails = aggregatedSubmissionRows
304-
.map(aggregated => aggregated.reviews?.[index])
305-
.filter((detail): detail is AggregatedReviewDetail => Boolean(detail))
306-
307-
const resolvedHandle = reviewerDetails
308-
.map(detail => detail.reviewerHandle?.trim()
309-
|| detail.reviewInfo?.reviewerHandle?.trim()
310-
|| undefined)
311-
.find((handle): handle is string => Boolean(handle))
312-
313-
if (!resolvedHandle) {
314-
return {
315-
label: `Reviewer ${index + 1}`,
316-
}
317-
}
318-
319-
const resolvedRating = reviewerDetails
320-
.map(detail => detail.reviewerMaxRating
321-
?? detail.reviewInfo?.reviewerMaxRating
322-
?? undefined)
323-
.find((rating): rating is number => (
324-
typeof rating === 'number'
325-
&& Number.isFinite(rating)
326-
))
327-
328-
const resolvedColor = reviewerDetails
329-
.map(detail => detail.reviewerHandleColor
330-
?? detail.reviewInfo?.reviewerHandleColor
331-
?? undefined)
332-
.find((color): color is string => Boolean(color))
333-
334-
const ratingDisplay = resolvedRating !== undefined
335-
? Math.round(resolvedRating)
336-
: undefined
337-
const baseLabel = ratingDisplay !== undefined
338-
? `${resolvedHandle} (${ratingDisplay})`
339-
: resolvedHandle
340-
341-
const renderLabel = (): JSX.Element => {
342-
const color = resolvedColor
343-
?? (resolvedRating !== undefined
344-
? getRatingColor(resolvedRating)
345-
: undefined)
346-
?? '#2a2a2a'
347-
348-
return (
349-
<span style={{ color }}>
350-
{baseLabel}
351-
</span>
352-
)
353-
}
354-
355-
return {
356-
label: baseLabel,
357-
renderLabel,
358-
}
359-
})
360-
), [aggregatedSubmissionRows, maxReviewCount])
283+
Array.from({ length: maxReviewCount }, (_unused, index) => ({
284+
label: `Reviewer ${index + 1}`,
285+
}))
286+
), [maxReviewCount])
361287

362288
const [isReopening, setIsReopening] = useState(false)
363289
const [pendingReopen, setPendingReopen] = useState<PendingReopenState | undefined>(undefined)

src/apps/review/src/lib/hooks/useFetchScreeningReview.ts

Lines changed: 10 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
SubmissionInfo,
2626
} from '../models'
2727
import { fetchChallengeReviews } from '../services'
28+
import { registerChallengeReviewKey } from '../utils/reviewCacheRegistry'
2829

2930
import { useFetchAppealQueue, useFetchAppealQueueProps } from './useFetchAppealQueue'
3031
import { useFetchChallengeSubmissions, useFetchChallengeSubmissionsProps } from './useFetchChallengeSubmissions'
@@ -1087,15 +1088,7 @@ export function useFetchScreeningReview(): useFetchScreeningReviewProps {
10871088
})
10881089
})
10891090

1090-
const resolvedReviewerIds = Array.from(fallbackResults)
1091-
1092-
debugLog('reviewerIds', {
1093-
challengeId,
1094-
reviewerCount: resolvedReviewerIds.length,
1095-
reviewerIds: resolvedReviewerIds,
1096-
})
1097-
1098-
return resolvedReviewerIds
1091+
return Array.from(fallbackResults)
10991092

11001093
}, [
11011094
challengeReviewers,
@@ -1135,6 +1128,14 @@ export function useFetchScreeningReview(): useFetchScreeningReviewProps {
11351128
},
11361129
)
11371130

1131+
useEffect(() => {
1132+
if (!challengeId) {
1133+
return
1134+
}
1135+
1136+
registerChallengeReviewKey(challengeId, `reviewBaseUrl/reviews/${challengeId}/${reviewerKey}`)
1137+
}, [challengeId, reviewerKey])
1138+
11381139
const challengeReviews = useMemo(
11391140
() => challengeReviewsData,
11401141
[challengeReviewsData],
@@ -1326,23 +1327,6 @@ export function useFetchScreeningReview(): useFetchScreeningReviewProps {
13261327
[challengeReviews, reviewerIds],
13271328
)
13281329

1329-
const reviewAssignmentSummary = useMemo(
1330-
() => Object.entries(reviewAssignmentsBySubmission)
1331-
.map(
1332-
([submissionId, reviewerMapping]) => ({
1333-
reviewerIds: Object.keys(reviewerMapping),
1334-
submissionId,
1335-
}),
1336-
),
1337-
[reviewAssignmentsBySubmission],
1338-
)
1339-
1340-
debugLog('reviewAssignments', {
1341-
assignments: reviewAssignmentSummary,
1342-
challengeId,
1343-
submissionCount: reviewAssignmentSummary.length,
1344-
})
1345-
13461330
// get screening data from challenge submissions
13471331
const screening = useMemo(
13481332
() => {
@@ -2185,19 +2169,6 @@ export function useFetchScreeningReview(): useFetchScreeningReviewProps {
21852169
reviewForResource = emptyReview
21862170
}
21872171

2188-
debugLog('reviewEntry', {
2189-
challengeId,
2190-
finalScore: reviewForResource?.finalScore,
2191-
origin: assignmentReview
2192-
? (matchingReview ? 'assignment+existing' : 'assignment')
2193-
: (matchingReview ? 'existing' : 'empty'),
2194-
reviewerHandle: reviewForResource?.reviewerHandle,
2195-
reviewerId,
2196-
reviewId: reviewForResource?.id,
2197-
status: reviewForResource?.status,
2198-
submissionId: challengeSubmission.id,
2199-
})
2200-
22012172
validReviews.push({
22022173
...challengeSubmission,
22032174
review: [reviewForResource],
@@ -2211,15 +2182,6 @@ export function useFetchScreeningReview(): useFetchScreeningReviewProps {
22112182
return validReviews.map(item => {
22122183
const result = convertBackendSubmissionToSubmissionInfo(item)
22132184

2214-
debugLog('reviewSubmissionInfo', {
2215-
challengeId,
2216-
submissionId: result.id,
2217-
reviewerId: result.review?.resourceId,
2218-
reviewerHandle: result.review?.reviewerHandle,
2219-
reviewId: result.review?.id,
2220-
finalScore: result.review?.finalScore,
2221-
})
2222-
22232185
return {
22242186
...result,
22252187
userInfo: resourceMemberIdMapping[result.memberId],

src/apps/review/src/lib/utils/aggregateSubmissionReviews.ts

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -139,19 +139,6 @@ export function aggregateSubmissionReviews({
139139
? find(submission.reviews, reviewResult => reviewResult.resourceId === resourceId)
140140
: undefined
141141
if (!reviewId) {
142-
if (process.env.NODE_ENV !== 'production') {
143-
try {
144-
console.debug('[aggregateSubmissionReviews] skipped review without id', {
145-
resourceId,
146-
reviewInfo,
147-
reviewResult: matchingReviewResult,
148-
submissionId: submission.id,
149-
})
150-
} catch {
151-
// ignore logging failures
152-
}
153-
}
154-
155142
return
156143
}
157144

@@ -400,24 +387,6 @@ export function aggregateSubmissionReviews({
400387
})
401388
})
402389

403-
if (process.env.NODE_ENV !== 'production') {
404-
try {
405-
console.debug('[aggregateSubmissionReviews] summaries', aggregatedRows.map(row => ({
406-
reviews: row.reviews.map(review => ({
407-
finalScore: review.finalScore
408-
?? review.reviewInfo?.finalScore,
409-
resourceId: review.resourceId,
410-
reviewerHandle: review.reviewerHandle
411-
?? review.reviewInfo?.reviewerHandle,
412-
reviewId: review.reviewId ?? review.reviewInfo?.id,
413-
})),
414-
submissionId: row.id,
415-
})))
416-
} catch {
417-
// ignore logging errors
418-
}
419-
}
420-
421390
return aggregatedRows
422391
}
423392
/* eslint-enable complexity */
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* Registry tracking SWR cache keys that contain challenge-review data.
3+
*
4+
* The registry lets utility functions invalidate every relevant cache entry
5+
* after mutations (for example, when reopening a review) without needing
6+
* component-specific context.
7+
*/
8+
9+
const challengeReviewKeyRegistry = new Map<string, Set<string>>()
10+
11+
/**
12+
* Record a cache key that should be revalidated when review data changes.
13+
*/
14+
export const registerChallengeReviewKey = (challengeId: string | undefined, cacheKey: string | undefined): void => {
15+
if (!challengeId || !cacheKey) {
16+
return
17+
}
18+
19+
const normalizedKey = cacheKey.trim()
20+
if (!normalizedKey.length) {
21+
return
22+
}
23+
24+
const registryEntry = challengeReviewKeyRegistry.get(challengeId)
25+
if (registryEntry) {
26+
registryEntry.add(normalizedKey)
27+
return
28+
}
29+
30+
challengeReviewKeyRegistry.set(challengeId, new Set<string>([normalizedKey]))
31+
}
32+
33+
/**
34+
* Retrieve all registered cache keys for the provided challenge.
35+
*/
36+
export const getChallengeReviewKeys = (challengeId: string | undefined): string[] => {
37+
if (!challengeId) {
38+
return []
39+
}
40+
41+
const entry = challengeReviewKeyRegistry.get(challengeId)
42+
return entry ? Array.from(entry) : []
43+
}

0 commit comments

Comments
 (0)