Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
c5c0cf2
Topcoder admin app: move src/apps/gamification-admin -> src/apps/admin
suppermancool Jun 27, 2025
9889cd4
Topcoder Admin App - Add Terms Management Final fix
suppermancool Jul 10, 2025
0a0ed87
Topcoder Admin App - Add Terms Management: fix html editor in edit form
suppermancool Jul 10, 2025
e17ed99
admin app: remove unused plugin in html editor
suppermancool Jul 10, 2025
4388a14
Merge pull request #1133 from topcoder-platform/diazz-admin-code-3037…
jmgasper Aug 5, 2025
f83c0d4
[72HR] Topcoder Admin App - Add Non-MM Submission Management
suppermancool Aug 12, 2025
e95b61b
PM-1612 Update visible columns on copilot applications
himaniraghav3 Aug 14, 2025
2ef3b3e
Merge pull request #1126 from topcoder-platform/diazz-gamification-admin
jmgasper Aug 14, 2025
f22c4ca
feat: paginated copilot requests page
hentrymartin Aug 17, 2025
7d9056a
feat: paginated copilot requests page
hentrymartin Aug 17, 2025
b42bdc6
Merge pull request #1185 from topcoder-platform/PM-1612
himaniraghav3 Aug 18, 2025
56c237d
Merge pull request #1188 from topcoder-platform/pm-1650
hentrymartin Aug 18, 2025
f3f9a97
Limit other payment type field to 8 char
himaniraghav3 Aug 18, 2025
6f191d8
Merge pull request #1189 from topcoder-platform/PM-1616
himaniraghav3 Aug 19, 2025
89cd005
Merge branch 'feat/system-admin' into diazz-admin-code-30377611
suppermancool Aug 19, 2025
40057bb
Merge pull request #1191 from topcoder-platform/diazz-admin-code-3037…
jmgasper Aug 19, 2025
f2f20fc
PM-1616 Prevent undefined error
himaniraghav3 Aug 19, 2025
86eb547
Merge pull request #1192 from topcoder-platform/PM-1616
himaniraghav3 Aug 19, 2025
80c9371
Add max length to other payment types
himaniraghav3 Aug 19, 2025
c8503fc
Merge pull request #1193 from topcoder-platform/PM-1616
himaniraghav3 Aug 19, 2025
3377769
fix: sort from server side
hentrymartin Aug 19, 2025
fa22569
fix: project type column
hentrymartin Aug 19, 2025
3baf08a
fix: lint
hentrymartin Aug 19, 2025
b8e3be2
fix: column width of copilot requests table
hentrymartin Aug 19, 2025
750aafe
Merge pull request #1198 from topcoder-platform/pm-1650_1
kkartunov Aug 20, 2025
2db5f5e
fix: add white space below copilot request table
hentrymartin Aug 21, 2025
f1bcccd
fix: lint
hentrymartin Aug 21, 2025
685ed1b
Merge pull request #1204 from topcoder-platform/pm-1614
hentrymartin Aug 21, 2025
88833e8
Merge branch 'dev' into feat/system-admin
jmgasper Aug 22, 2025
c34a372
Merge pull request #1206 from topcoder-platform/feat/system-admin
jmgasper Aug 22, 2025
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
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
"@storybook/react": "7.6.10",
"@stripe/react-stripe-js": "1.13.0",
"@stripe/stripe-js": "1.41.0",
"@tinymce/tinymce-react": "^6.2.1",
"@types/codemirror": "5.60.15",
"amazon-s3-uri": "^0.1.1",
"apexcharts": "^3.36.0",
"axios": "^1.7.9",
"browser-cookies": "^1.2.0",
Expand All @@ -43,6 +46,7 @@
"draft-js-export-html": "^1.2.0",
"draft-js-markdown-shortcuts-plugin": "^0.3.0",
"draft-js-plugins-editor": "^2.0.3",
"easymde": "2.20.0",
"express": "^4.21.2",
"express-fileupload": "^1.4.0",
"express-interceptor": "^1.2.0",
Expand Down Expand Up @@ -101,6 +105,7 @@
"styled-components": "^5.3.6",
"swr": "^1.3.0",
"tc-auth-lib": "topcoder-platform/tc-auth-lib#1.0.27",
"tinymce": "^7.9.1",
"typescript": "^4.8.4",
"universal-navigation": "https://github.com/topcoder-platform/universal-navigation#9fc50d938be7182",
"uuid": "^11.1.0",
Expand Down
33 changes: 33 additions & 0 deletions src/apps/admin/src/admin-app.routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
permissionManagementRouteId,
platformRouteId,
rootRoute,
termsRouteId,
userManagementRouteId,
} from './config/routes.config'
import { platformSkillRouteId } from './platform/routes.config'
Expand Down Expand Up @@ -128,6 +129,22 @@ const BadgeListingPage: LazyLoadedComponent = lazyLoad(
const CreateBadgePage: LazyLoadedComponent = lazyLoad(
() => import('./platform/gamification-admin/src/pages/create-badge/CreateBadgePage'),
)
const TermsListPage: LazyLoadedComponent = lazyLoad(
() => import('./platform/terms/TermsListPage'),
'TermsListPage',
)
const TermsAddPage: LazyLoadedComponent = lazyLoad(
() => import('./platform/terms/TermsAddPage'),
'TermsAddPage',
)
const TermsEditPage: LazyLoadedComponent = lazyLoad(
() => import('./platform/terms/TermsEditPage'),
'TermsEditPage',
)
const TermsUsersPage: LazyLoadedComponent = lazyLoad(
() => import('./platform/terms/TermsUsersPage'),
'TermsUsersPage',
)

export const toolTitle: string = ToolTitle.admin

Expand Down Expand Up @@ -310,6 +327,22 @@ export const adminRoutes: ReadonlyArray<PlatformRoute> = [
element: <BadgeDetailPage />,
route: `${gamificationAdminRouteId}${baseDetailPath}/:id`,
},
{
element: <TermsListPage />,

Choose a reason for hiding this comment

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

Ensure that the TermsListPage component is correctly imported and defined in the project. This applies to all new components added in this diff.

route: termsRouteId,

Choose a reason for hiding this comment

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

The route termsRouteId should be checked to ensure it is correctly defined and imported in this file, as it is used multiple times in the new routes.

},
{
element: <TermsAddPage />,

Choose a reason for hiding this comment

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

Verify that the TermsAddPage component is correctly imported and defined. This applies to all new components added in this diff.

route: `${termsRouteId}/add`,
},
{
element: <TermsUsersPage />,

Choose a reason for hiding this comment

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

Ensure that the TermsUsersPage component is correctly imported and defined in the project. This applies to all new components added in this diff.

route: `${termsRouteId}/:id/users`,
},
{
element: <TermsEditPage />,

Choose a reason for hiding this comment

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

Verify that the TermsEditPage component is correctly imported and defined. This applies to all new components added in this diff.

route: `${termsRouteId}/:id/edit`,
},
],
element: <Platform />,
id: platformRouteId,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
/**
* Manage Submission Page.
*/
import { FC } from 'react'
import { FC, useMemo } from 'react'
import { useParams } from 'react-router-dom'
import classNames from 'classnames'

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

import {
useDownloadSubmission,
useDownloadSubmissionProps,
useFetchChallenge,
useFetchChallengeProps,
useManageAVScan,
useManageAVScanProps,
useManageBusEvent,
useManageBusEventProps,
useManageChallengeSubmissions,
Expand All @@ -20,6 +26,7 @@ import {
TableLoading,
TableNoRecord,
} from '../../lib'
import { checkIsMM } from '../../lib/utils'

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

Expand All @@ -35,7 +42,13 @@ export const ManageSubmissionPage: FC<Props> = (props: Props) => {
= useManageBusEvent()

const {
isLoading,
isLoading: isLoadingChallenge,
challengeInfo,
}: useFetchChallengeProps = useFetchChallenge(challengeId)
const isMM = useMemo(() => checkIsMM(challengeInfo), [challengeInfo])

Choose a reason for hiding this comment

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

The useMemo hook is used here to memoize the result of checkIsMM(challengeInfo). Ensure that checkIsMM is a pure function, as impure functions can lead to unexpected behavior when used with useMemo.


const {
isLoading: isLoadingSubmission,
submissions,
isRemovingSubmission,
isRemovingSubmissionBool,
Expand All @@ -48,6 +61,19 @@ export const ManageSubmissionPage: FC<Props> = (props: Props) => {
}: useManageChallengeSubmissionsProps
= useManageChallengeSubmissions(challengeId)

const {
isLoading: isDownloadingSubmission,
isLoadingBool: isDownloadingSubmissionBool,

Choose a reason for hiding this comment

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

The variable isLoadingBool seems redundant if isLoading is already serving the purpose of indicating loading state. Consider removing isLoadingBool if it is not necessary.

downloadSubmission,
}: useDownloadSubmissionProps = useDownloadSubmission()
const {
isLoading: isDoingAvScan,
isLoadingBool: isDoingAvScanBool,

Choose a reason for hiding this comment

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

Similar to the previous comment, isLoadingBool for AV scan might be redundant if isLoading already indicates the loading state. Evaluate if both are needed.

doPostBusEvent: doPostBusEventAvScan,
}: useManageAVScanProps = useManageAVScan()

const isLoading = isLoadingSubmission || isLoadingChallenge

Choose a reason for hiding this comment

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

Consider renaming isLoading to something more descriptive, such as isPageLoading, to clarify that it represents the loading state of the entire page, combining multiple loading states.


return (
<PageWrapper
pageTitle='Submission Management'
Expand All @@ -67,6 +93,10 @@ export const ManageSubmissionPage: FC<Props> = (props: Props) => {
) : (
<div className={styles.blockTableContainer}>
<SubmissionTable
isDoingAvScan={isDoingAvScan}

Choose a reason for hiding this comment

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

Consider renaming isDoingAvScan to isPerformingAvScan for clarity and consistency with other boolean variable names.

doPostBusEventAvScan={doPostBusEventAvScan}

Choose a reason for hiding this comment

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

The function name doPostBusEventAvScan could be more descriptive. Consider renaming it to something like triggerAvScanBusEvent to better convey its purpose.

isDownloading={isDownloadingSubmission}

Choose a reason for hiding this comment

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

Consider renaming isDownloadingSubmission to isSubmissionDownloading for consistency with other boolean variable names.

downloadSubmission={downloadSubmission}

Choose a reason for hiding this comment

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

The function name downloadSubmission could be more descriptive. Consider renaming it to initiateSubmissionDownload to better convey its purpose.

data={submissions}
isRemovingSubmission={isRemovingSubmission}
doRemoveSubmission={doRemoveSubmission}
Expand All @@ -80,9 +110,12 @@ export const ManageSubmissionPage: FC<Props> = (props: Props) => {
doPostBusEvent={doPostBusEvent}
showSubmissionHistory={showSubmissionHistory}
setShowSubmissionHistory={setShowSubmissionHistory}
isMM={isMM}

Choose a reason for hiding this comment

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

The addition of the isMM prop to the SubmissionManagement component should be verified to ensure it is necessary and correctly implemented. Check if this prop is used within the component and if its addition aligns with the intended functionality changes.

/>

{(isRemovingSubmissionBool
{(isDoingAvScanBool

Choose a reason for hiding this comment

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

The condition for displaying ActionLoading has been modified. Ensure that the new condition isDoingAvScanBool and isDownloadingSubmissionBool are correctly defined and initialized elsewhere in the code. Verify that these changes do not introduce any unintended side effects.

|| isDownloadingSubmissionBool
|| isRemovingSubmissionBool
|| isRunningTestBool
|| isRemovingReviewSummationsBool) && (
<ActionLoading />
Expand Down
24 changes: 22 additions & 2 deletions src/apps/admin/src/config/busEvent.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
*/
import { v4 as uuidv4 } from 'uuid'

import { RequestBusAPI } from '../lib/models'
import {
RequestBusAPI,
RequestBusAPIAVScan,
RequestBusAPIAVScanPayload,
} from '../lib/models'

/**
* Create data for bus event
* Create data for data submission marathon match bus event

Choose a reason for hiding this comment

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

The comment should accurately reflect the function's purpose. Consider updating the comment to specify that it creates data for a 'data submission marathon match bus event'.

* @param submissionId submission id
* @param testType test type
* @returns data for bus event
Expand All @@ -27,3 +31,19 @@ export const CREATE_BUS_EVENT_DATA_SUBMISSION_MARATHON_MATCH = (
.toISOString(),
topic: 'submission.notification.score',
})

/**
* Create data for av rescan bus event
* @param payload av rescan payload
* @returns data for bus event
*/
export const CREATE_BUS_EVENT_AV_RESCAN = (
payload: RequestBusAPIAVScanPayload,
): RequestBusAPIAVScan => ({
'mime-type': 'application/json',

Choose a reason for hiding this comment

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

Consider using consistent casing for the 'mime-type' key. In other parts of the code, it might be 'mimeType' or 'MIMEType', so ensure consistency across the codebase.

originator: 'submission-processor',
payload,
timestamp: new Date()
.toISOString(),
topic: 'avscan.action.scan',
})
1 change: 1 addition & 0 deletions src/apps/admin/src/config/routes.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ export const userManagementRouteId = 'user-management'
export const billingAccountRouteId = 'billing-account'
export const permissionManagementRouteId = 'permission-management'
export const gamificationAdminRouteId = 'gamification-admin'
export const termsRouteId = 'terms'
export const platformRouteId = 'platform'
20 changes: 8 additions & 12 deletions src/apps/admin/src/lib/components/ChallengeList/ChallengeList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ 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 @@ -135,7 +134,6 @@ const Actions: FC<{
challenge: Challenge
currentFilters: ChallengeFilterCriteria
}> = props => {
const isMM = useMemo(() => checkIsMM(props.challenge), [props.challenge])
const [openDropdown, setOpenDropdown] = useState(false)
const navigate = useNavigate()
const goToManageUser = useEventCallback(() => {
Expand Down Expand Up @@ -202,16 +200,14 @@ const Actions: FC<{
>
Users
</li>
{isMM && (
<li
onClick={function onClick() {
navigate(`${props.challenge.id}/manage-submission`)
setOpenDropdown(false)
}}
>
Submissions
</li>
)}
<li
onClick={function onClick() {
navigate(`${props.challenge.id}/manage-submission`)

Choose a reason for hiding this comment

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

The removal of the isMM condition means that the 'Submissions' option will always be displayed, regardless of whether isMM is true or false. Ensure this change aligns with the intended functionality, as it alters the visibility logic for the 'Submissions' menu item.

setOpenDropdown(false)
}}
>
Submissions
</li>
</ul>
</DropdownMenu>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
.container {
display: flex;
flex-direction: column;
gap: 20px;
position: relative;
}

.blockForm {
display: flex;
flex-direction: column;
gap: 20px;
position: relative;
}

.actionButtons {
display: flex;
justify-content: flex-end;
gap: 6px;
}

.dialogLoadingSpinnerContainer {
position: absolute;
width: 64px;
display: flex;
align-items: center;
justify-content: center;
bottom: 0;
height: 64px;
left: 0;

.spinner {
background: none;
}
}
Loading