Skip to content

Topcoder Admin App - Marathon Match Functionality #1092

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 4, 2025
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@
"tc-auth-lib": "topcoder-platform/tc-auth-lib#1.0.27",
"typescript": "^4.8.4",
"universal-navigation": "https://github.com/topcoder-platform/universal-navigation#9fc50d938be7182",
"uuid": "^9.0.0",
"uuid": "^11.1.0",
"yup": "^1.6.1"
},
"devDependencies": {
Expand Down
9 changes: 9 additions & 0 deletions src/apps/admin/src/admin-app.routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ const ManageResourcePage: LazyLoadedComponent = lazyLoad(
() => import('./challenge-management/ManageResourcePage'),
'ManageResourcePage',
)
const ManageSubmissionPage: LazyLoadedComponent = lazyLoad(
() => import('./challenge-management/ManageSubmissionPage'),
'ManageSubmissionPage',
)
const AddResourcePage: LazyLoadedComponent = lazyLoad(
() => import('./challenge-management/AddResourcePage'),
'AddResourcePage',
Expand Down Expand Up @@ -145,6 +149,11 @@ export const adminRoutes: ReadonlyArray<PlatformRoute> = [
id: 'add-resource',
route: ':challengeId/manage-resource/add',
},
{
element: <ManageSubmissionPage />,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The component <ManageSubmissionPage /> is added here, but ensure that it is imported correctly at the top of the file. If it's not imported, it will cause a runtime error.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@suppermancool - Can you double check t his please?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jmgasper this code is correct

id: 'manage-resource',
route: ':challengeId/manage-submission',
},
],
element: <ChallengeManagement />,
id: manageChallengeRouteId,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.container {
display: flex;
flex-direction: column;
}

.blockTableContainer {
position: relative;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/**
* Manage Submission Page.
*/
import { FC } from 'react'
import { useParams } from 'react-router-dom'
import classNames from 'classnames'

import { LinkButton } from '~/libs/ui'

import {
useManageBusEvent,
useManageBusEventProps,
useManageChallengeSubmissions,
useManageChallengeSubmissionsProps,
} from '../../lib/hooks'
import {
ActionLoading,
PageWrapper,
SubmissionTable,
TableLoading,
TableNoRecord,
} from '../../lib'

import styles from './ManageSubmissionPage.module.scss'

interface Props {
className?: string
}

export const ManageSubmissionPage: FC<Props> = (props: Props) => {
const { challengeId = '' }: { challengeId?: string } = useParams<{
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The destructuring of useParams could be simplified by directly using useParams<{ challengeId: string }>() without the need for an intermediate type annotation.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@suppermancool - Can you double check this please?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jmgasper, the intermediate type annotation is required by eslint without it the 'yarn lint' will fail

challengeId: string
}>()
const { isRunningTest, isRunningTestBool, doPostBusEvent }: useManageBusEventProps
= useManageBusEvent()

const {
isLoading,
submissions,
isRemovingSubmission,
isRemovingSubmissionBool,
isRemovingReviewSummations,
isRemovingReviewSummationsBool,
doRemoveSubmission,
doRemoveReviewSummations,
showSubmissionHistory,
setShowSubmissionHistory,
}: useManageChallengeSubmissionsProps
= useManageChallengeSubmissions(challengeId)

return (
<PageWrapper
pageTitle='Submission Management'
className={classNames(styles.container, props.className)}
headerActions={(
<LinkButton primary light to='./../..' size='lg'>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using a more descriptive path for the LinkButton to improve readability and maintainability. The current path './../..' is not immediately clear and could be replaced with a named route or a clearer path string.

Back
</LinkButton>
)}
>
{isLoading ? (
<TableLoading />
) : (
<>
{submissions.length === 0 ? (
<TableNoRecord />
) : (
<div className={styles.blockTableContainer}>
<SubmissionTable
datas={submissions}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prop datas should be renamed to data to follow standard naming conventions and improve readability.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@suppermancool - Can you fix please?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jmgasper done in the latest commit

isRemovingSubmission={isRemovingSubmission}
doRemoveSubmission={doRemoveSubmission}
isRemovingReviewSummations={
isRemovingReviewSummations
}
doRemoveReviewSummations={
doRemoveReviewSummations
}
isRunningTest={isRunningTest}
doPostBusEvent={doPostBusEvent}
showSubmissionHistory={showSubmissionHistory}
setShowSubmissionHistory={setShowSubmissionHistory}
/>

{(isRemovingSubmissionBool
|| isRunningTestBool
|| isRemovingReviewSummationsBool) && (
<ActionLoading />
)}
</div>
)}
</>
)}
</PageWrapper>
)
}

export default ManageSubmissionPage
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as ManageSubmissionPage } from './ManageSubmissionPage'
29 changes: 29 additions & 0 deletions src/apps/admin/src/config/busEvent.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* App config for bus event
*/
import { v4 as uuidv4 } from 'uuid'

import { RequestBusAPI } from '../lib/models'

/**
* Create data for bus event
* @param submissionId submission id
* @param testType test type
* @returns data for bus event
*/
export const CREATE_BUS_EVENT_DATA_SUBMISSION_MARATHON_MATCH = (
submissionId: string,
testType: string,
): RequestBusAPI => ({
'mime-type': 'application/json',
originator: 'MMFinalScoreProcessor',
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using a constant or configuration setting for the originator value 'MMFinalScoreProcessor' to avoid hardcoding it directly in the function. This can improve maintainability and make it easier to update if the originator changes in the future.

payload: {
id: uuidv4(),
resource: 'score',
submissionId,
testType,
},
timestamp: new Date()
.toISOString(),
topic: 'submission.notification.score',
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using a constant or configuration setting for the topic value 'submission.notification.score' to avoid hardcoding it directly in the function. This can improve maintainability and make it easier to update if the topic changes in the future.

})
12 changes: 12 additions & 0 deletions src/apps/admin/src/lib/components/ChallengeList/ChallengeList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
import { useEventCallback } from '../../hooks'
import { Challenge, ChallengeFilterCriteria, ChallengeType } from '../../models'
import { Paging } from '../../models/challenge-management/Pagination'
import { checkIsMM } from '../../utils'

import { MobileListView } from './MobileListView'
import styles from './ChallengeList.module.scss'
Expand Down Expand Up @@ -134,6 +135,7 @@ const Actions: FC<{
challenge: Challenge
currentFilters: ChallengeFilterCriteria
}> = props => {
const isMM = useMemo(() => checkIsMM(props.challenge), [props.challenge])
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider renaming the isMM variable to something more descriptive, such as isMarathonMatch, to improve code readability.

const [openDropdown, setOpenDropdown] = useState(false)
const navigate = useNavigate()
const goToManageUser = useEventCallback(() => {
Expand Down Expand Up @@ -208,6 +210,16 @@ const Actions: FC<{
>
Resources
</li>
{isMM && (
<li
onClick={function onClick() {
navigate(`${props.challenge.id}/manage-submission`)
setOpenDropdown(false)
}}
>
Submissions
</li>
)}
</ul>
</DropdownMenu>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@import '@libs/ui/styles/includes';

.container {
display: flex;
flex-direction: column;
padding-bottom: $sp-8;

@include ltelg {
padding-bottom: $sp-4;
}
}

.rowActions {
display: flex;
align-items: center;
}

.desktopTable {
td {
vertical-align: middle;
}
}
Loading