From 5fbfe536cbe20c09548908bb25cfa9d21f00210a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tao=20Bojl=C3=A9n?= Date: Tue, 11 Aug 2026 22:42:04 +0100 Subject: [PATCH 1/2] Fix recent decision summary keys Co-authored-by: Amp Amp-Thread-ID: https://ampcode.com/threads/T-019fec69-19ab-77e8-b6f0-85af1ed67eed --- ...ManualReviewRecentDecisionSummary.test.tsx | 72 +++++++++++++++++++ .../mrt/ManualReviewRecentDecisionSummary.tsx | 14 ++-- 2 files changed, 79 insertions(+), 7 deletions(-) create mode 100644 client/src/webpages/dashboard/mrt/ManualReviewRecentDecisionSummary.test.tsx diff --git a/client/src/webpages/dashboard/mrt/ManualReviewRecentDecisionSummary.test.tsx b/client/src/webpages/dashboard/mrt/ManualReviewRecentDecisionSummary.test.tsx new file mode 100644 index 000000000..ec9fb7eec --- /dev/null +++ b/client/src/webpages/dashboard/mrt/ManualReviewRecentDecisionSummary.test.tsx @@ -0,0 +1,72 @@ +import { + GQLManualReviewDecisionType, + type GQLManualReviewDecision, +} from '@/graphql/generated'; +import { render } from '@testing-library/react'; +import { afterEach, expect, it, vi } from 'vitest'; + +import ManualReviewRecentDecisionSummary from './ManualReviewRecentDecisionSummary'; + +vi.mock('@/graphql/generated', async (importOriginal) => ({ + ...(await importOriginal()), + useGQLRecentDecisionsSummaryDataQuery: () => ({ + loading: false, + data: { + myOrg: { + users: [], + mrtQueues: [], + actions: [], + policies: [], + itemTypes: [], + }, + }, + }), +})); + +afterEach(() => { + vi.restoreAllMocks(); +}); + +it('renders populated decision lists without a missing-key warning', () => { + const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {}); + const selectedDecision = { + __typename: 'ManualReviewDecision', + id: 'decision-1', + jobId: 'job-1', + createdAt: '2026-08-11T12:00:00.000Z', + reviewerId: null, + queueId: 'queue-1', + decisionReason: null, + decisions: [ + { + __typename: 'IgnoreDecisionComponent', + type: GQLManualReviewDecisionType.Ignore, + }, + ], + relatedActions: [ + { + __typename: 'AcceptAppealDecisionComponent', + actionIds: [], + appealId: 'appeal-1', + type: GQLManualReviewDecisionType.AcceptAppeal, + }, + ], + } as GQLManualReviewDecision; + + render( + , + ); + + const missingKeyWarnings = consoleError.mock.calls.filter((call) => { + const warning = call.join(' '); + return ( + warning.includes( + 'Each child in a list should have a unique "key" prop', + ) && warning.includes('ManualReviewRecentDecisionSummary') + ); + }); + expect(missingKeyWarnings).toEqual([]); +}); diff --git a/client/src/webpages/dashboard/mrt/ManualReviewRecentDecisionSummary.tsx b/client/src/webpages/dashboard/mrt/ManualReviewRecentDecisionSummary.tsx index c0964bbd8..f79100f0b 100644 --- a/client/src/webpages/dashboard/mrt/ManualReviewRecentDecisionSummary.tsx +++ b/client/src/webpages/dashboard/mrt/ManualReviewRecentDecisionSummary.tsx @@ -5,7 +5,7 @@ import { } from '@/graphql/generated'; import { parseDatetimeToReadableStringInCurrentTimeZone } from '@/utils/time'; import { gql } from '@apollo/client'; -import { useCallback } from 'react'; +import { Fragment, useCallback } from 'react'; import CloseButton from '@/components/common/CloseButton'; import ComponentLoading from '@/components/common/ComponentLoading'; @@ -189,16 +189,16 @@ export default function ManualReviewRecentDecisionSummary(props: {
Primary Decision
- {selectedDecision.decisions.map((decision) => - actionPoliciesPair(decision), - )} + {selectedDecision.decisions.map((decision, index) => ( + {actionPoliciesPair(decision)} + ))}
{selectedDecision.relatedActions.length > 0 ? (
Related Actions
- {selectedDecision.relatedActions.map((action) => - actionPoliciesPair(action), - )} + {selectedDecision.relatedActions.map((action, index) => ( + {actionPoliciesPair(action)} + ))}
) : null}
From 4966e87ab15f6c007cd39aed9a8969585be57a07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tao=20Bojl=C3=A9n?= Date: Tue, 18 Aug 2026 14:03:39 +0100 Subject: [PATCH 2/2] Remove recent decision summary regression test Co-authored-by: Amp Amp-Thread-ID: https://ampcode.com/threads/T-019fec69-19ab-77e8-b6f0-85af1ed67eed --- ...ManualReviewRecentDecisionSummary.test.tsx | 72 ------------------- 1 file changed, 72 deletions(-) delete mode 100644 client/src/webpages/dashboard/mrt/ManualReviewRecentDecisionSummary.test.tsx diff --git a/client/src/webpages/dashboard/mrt/ManualReviewRecentDecisionSummary.test.tsx b/client/src/webpages/dashboard/mrt/ManualReviewRecentDecisionSummary.test.tsx deleted file mode 100644 index ec9fb7eec..000000000 --- a/client/src/webpages/dashboard/mrt/ManualReviewRecentDecisionSummary.test.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { - GQLManualReviewDecisionType, - type GQLManualReviewDecision, -} from '@/graphql/generated'; -import { render } from '@testing-library/react'; -import { afterEach, expect, it, vi } from 'vitest'; - -import ManualReviewRecentDecisionSummary from './ManualReviewRecentDecisionSummary'; - -vi.mock('@/graphql/generated', async (importOriginal) => ({ - ...(await importOriginal()), - useGQLRecentDecisionsSummaryDataQuery: () => ({ - loading: false, - data: { - myOrg: { - users: [], - mrtQueues: [], - actions: [], - policies: [], - itemTypes: [], - }, - }, - }), -})); - -afterEach(() => { - vi.restoreAllMocks(); -}); - -it('renders populated decision lists without a missing-key warning', () => { - const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {}); - const selectedDecision = { - __typename: 'ManualReviewDecision', - id: 'decision-1', - jobId: 'job-1', - createdAt: '2026-08-11T12:00:00.000Z', - reviewerId: null, - queueId: 'queue-1', - decisionReason: null, - decisions: [ - { - __typename: 'IgnoreDecisionComponent', - type: GQLManualReviewDecisionType.Ignore, - }, - ], - relatedActions: [ - { - __typename: 'AcceptAppealDecisionComponent', - actionIds: [], - appealId: 'appeal-1', - type: GQLManualReviewDecisionType.AcceptAppeal, - }, - ], - } as GQLManualReviewDecision; - - render( - , - ); - - const missingKeyWarnings = consoleError.mock.calls.filter((call) => { - const warning = call.join(' '); - return ( - warning.includes( - 'Each child in a list should have a unique "key" prop', - ) && warning.includes('ManualReviewRecentDecisionSummary') - ); - }); - expect(missingKeyWarnings).toEqual([]); -});