Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ const submissions: Submission[] = [
challengeId: 'challenge-1',
createdAt: '2026-07-01T10:00:00.000Z',
createdBy: 'member-1',
id: 'system-submission',
memberHandle: 'system-user',
id: 'alpha-system-submission',
memberHandle: 'alpha',
reviewSummation: [
{
metadata: {
Expand All @@ -146,8 +146,8 @@ const submissions: Submission[] = [
challengeId: 'challenge-1',
createdAt: '2026-07-01T11:00:00.000Z',
createdBy: 'member-2',
id: 'provisional-submission',
memberHandle: 'provisional-user',
id: 'bravo-provisional-submission',
memberHandle: 'bravo',
reviewSummation: [
{
metadata: {
Expand All @@ -161,8 +161,9 @@ const submissions: Submission[] = [
challengeId: 'challenge-1',
createdAt: '2026-07-01T12:00:00.000Z',
createdBy: 'member-3',
id: 'example-submission',
memberHandle: 'example-user',
id: 'charlie-example-submission',
legacySubmissionId: 'legacy-charlie-id',
memberHandle: 'charlie',
reviewSummation: [
{
metadata: {
Expand Down Expand Up @@ -199,6 +200,43 @@ describe('SubmissionsSection', () => {
mockFetchMembersByUserIds.mockResolvedValue([])
})

it('filters submissions by current or legacy submission ID', () => {
render(
<SubmissionsSection
challenge={baseChallenge}
challengeId='challenge-1'
/>,
)

fireEvent.change(screen.getByLabelText('Submission ID'), {
target: {
value: 'BRAVO',
},
})

expect(screen.getByText('bravo-provisional-submission'))
.toBeTruthy()
expect(screen.queryByText('alpha-system-submission'))
.toBeNull()
expect(screen.queryByText('charlie-example-submission'))
.toBeNull()
expect(screen.getByTestId('pagination-total').textContent)
.toBe('1')

fireEvent.change(screen.getByLabelText('Submission ID'), {
target: {
value: 'legacy-charlie',
},
})

expect(screen.getByText('charlie-example-submission'))
.toBeTruthy()
expect(screen.queryByText('alpha-system-submission'))
.toBeNull()
expect(screen.queryByText('bravo-provisional-submission'))
.toBeNull()
})

it('filters marathon submissions by test type', () => {
render(
<SubmissionsSection
Expand All @@ -213,11 +251,11 @@ describe('SubmissionsSection', () => {
},
})

expect(screen.getByText('system-submission'))
expect(screen.getByText('alpha-system-submission'))
.toBeTruthy()
expect(screen.queryByText('provisional-submission'))
expect(screen.queryByText('bravo-provisional-submission'))
.toBeNull()
expect(screen.queryByText('example-submission'))
expect(screen.queryByText('charlie-example-submission'))
.toBeNull()
expect(screen.getByTestId('pagination-total').textContent)
.toBe('1')
Expand All @@ -228,11 +266,11 @@ describe('SubmissionsSection', () => {
},
})

expect(screen.getByText('example-submission'))
expect(screen.getByText('charlie-example-submission'))
.toBeTruthy()
expect(screen.queryByText('system-submission'))
expect(screen.queryByText('alpha-system-submission'))
.toBeNull()
expect(screen.queryByText('provisional-submission'))
expect(screen.queryByText('bravo-provisional-submission'))
.toBeNull()
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ interface FilterState {
handle: string
minScore: string
startDate: string
submissionId: string
testType: string
}

Expand Down Expand Up @@ -332,6 +333,33 @@ function matchesFilterHandle(submission: Submission, handleFilter: string): bool
.includes(normalizedHandleFilter)
}

/**
* Checks whether a submission matches the submission ID filter.
* @param submission Submission row being evaluated.
* @param submissionIdFilter Case-insensitive partial submission ID entered by the user.
* @returns True when the filter is empty or matches the submission's current or legacy ID.
* Used by `matchesFilters` before the submissions table is sorted and paginated.
*/
function matchesFilterSubmissionId(
submission: Submission,
submissionIdFilter: string,
): boolean {
if (!submissionIdFilter) {
return true
}

const normalizedSubmissionIdFilter = normalizeValue(submissionIdFilter)
.toLowerCase()

return [
submission.id,
submission.legacySubmissionId,
]
.some(submissionId => normalizeValue(submissionId)
.toLowerCase()
.includes(normalizedSubmissionIdFilter))
}

/**
* Checks whether a submission matches the selected marathon test type.
* @param submission Submission row being evaluated.
Expand Down Expand Up @@ -372,6 +400,10 @@ function matchesFilters(
return false
}

if (!matchesFilterSubmissionId(submission, filters.submissionId)) {
return false
}

if (!matchesFilterDateRange(submission, filters.startDate, filters.endDate)) {
return false
}
Expand All @@ -398,6 +430,7 @@ export const SubmissionsSection: FC<SubmissionsSectionProps> = (
handle: '',
minScore: '',
startDate: '',
submissionId: '',
testType: '',
})
const [memberCache, setMemberCache] = useState<MemberCache>({})
Expand Down Expand Up @@ -682,6 +715,19 @@ export const SubmissionsSection: FC<SubmissionsSectionProps> = (
/>
</label>

<label className={styles.filterLabel} htmlFor='submission-id-filter'>
Submission ID
<input
className={styles.filterInput}
id='submission-id-filter'
name='submissionId'
onChange={handleFilterChange}
placeholder='Filter by submission ID'
type='text'
value={filters.submissionId}
/>
</label>

{isMarathonMatch
? (
<label className={styles.filterLabel} htmlFor='submission-test-type-filter'>
Expand Down
Loading