Skip to content

Commit ca933dc

Browse files
authored
Merge pull request #1284 from topcoder-platform/feat/v6
Better handling of TG Task URL only submissions
2 parents acfc2b4 + fa1273d commit ca933dc

File tree

10 files changed

+114
-53
lines changed

10 files changed

+114
-53
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ export const ChallengeDetailsContent: FC<Props> = (props: Props) => {
203203
if (typeof window !== 'undefined') {
204204
const openedWindow = window.open(targetUrl, '_blank', 'noopener,noreferrer')
205205
if (openedWindow === null) {
206-
toast.error('We could not open the submission URL. Check your pop-up blocker and try again.')
206+
window.location.assign(targetUrl)
207207
}
208208
} else {
209209
toast.error('Unable to open the submission URL from this environment.')

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,10 @@ export const TabContentSubmissions: FC<Props> = props => {
232232
}
233233

234234
const isRestrictedBase = isSubmissionDownloadRestrictedForMember(submission.memberId)
235-
const failedScan = submission.virusScan === false
235+
const normalizedVirusScan = submission.isFileSubmission === false
236+
? undefined
237+
: submission.virusScan
238+
const failedScan = normalizedVirusScan === false
236239
const isRestricted = isRestrictedBase || failedScan
237240
const tooltipMessage = failedScan
238241
? VIRUS_SCAN_FAILED_MESSAGE
@@ -320,6 +323,10 @@ export const TabContentSubmissions: FC<Props> = props => {
320323
label: 'Virus Scan',
321324
propertyName: 'virusScan',
322325
renderer: (submission: BackendSubmission) => {
326+
if (submission.isFileSubmission === false) {
327+
return <span>N/A</span>
328+
}
329+
323330
if (submission.virusScan === true) {
324331
return (
325332
<span className={styles.virusOkIcon} title='Scan passed' aria-label='Scan passed'>

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,9 @@ export const SubmissionHistoryModal: FC<SubmissionHistoryModalProps> = (props: S
174174
const renderHistoryRow = useCallback((submission: SubmissionInfo): JSX.Element => {
175175
const fallbackMeta = props.getSubmissionMeta?.(submission.id) ?? undefined
176176
const resolvedVirusScan = submission.virusScan ?? fallbackMeta?.virusScan
177-
const failedScan = resolvedVirusScan === false
177+
const isFileSubmission = submission.isFileSubmission ?? fallbackMeta?.isFileSubmission
178+
const normalizedVirusScan = isFileSubmission === false ? undefined : resolvedVirusScan
179+
const failedScan = normalizedVirusScan === false
178180
const restriction = props.getRestriction
179181
? props.getRestriction(submission)
180182
: { restricted: false }
@@ -234,11 +236,13 @@ export const SubmissionHistoryModal: FC<SubmissionHistoryModalProps> = (props: S
234236
{submittedDisplay}
235237
</td>
236238
<td className={styles.cellVirusScan}>
237-
{resolvedVirusScan === true ? (
239+
{isFileSubmission === false ? (
240+
<span>N/A</span>
241+
) : normalizedVirusScan === true ? (
238242
<span className={styles.virusOkIcon} title='Scan passed' aria-label='Scan passed'>
239243
<IconOutline.CheckCircleIcon />
240244
</span>
241-
) : resolvedVirusScan === false ? (
245+
) : normalizedVirusScan === false ? (
242246
<span className={styles.virusWarnIcon} title='Scan failed' aria-label='Scan failed'>
243247
<IconOutline.ExclamationIcon />
244248
</span>

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,10 @@ export const TableCheckpointSubmissions: FC<Props> = (props: Props) => {
171171
propertyName: 'submissionId',
172172
renderer: (data: Screening) => {
173173
const isRestrictedBase = isSubmissionDownloadRestrictedForMember(data.memberId)
174-
const failedScan = data.virusScan === false
174+
const normalizedVirusScan = data.isFileSubmission === false
175+
? undefined
176+
: data.virusScan
177+
const failedScan = normalizedVirusScan === false
175178
const isRestrictedForRow = isRestrictedBase || failedScan
176179
const tooltipMessage = failedScan
177180
? 'Submission failed virus scan'

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

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,7 @@ export const TableIterativeReview: FC<Props> = (props: Props) => {
662662
columnId: 'submission-id',
663663
label: 'Submission ID',
664664
propertyName: 'id',
665+
// eslint-disable-next-line complexity -- Renderer must account for multiple submission restriction states.
665666
renderer: (data: SubmissionInfo) => {
666667
const isOwnedSubmission = data.memberId
667668
? ownedMemberIds.has(data.memberId)
@@ -675,7 +676,10 @@ export const TableIterativeReview: FC<Props> = (props: Props) => {
675676
const memberRestrictionMessage = getRestrictionMessageForMember(
676677
data.memberId,
677678
)
678-
const failedScan = (data as SubmissionInfo).virusScan === false
679+
const normalizedVirusScan = data.isFileSubmission === false
680+
? undefined
681+
: data.virusScan
682+
const failedScan = normalizedVirusScan === false
679683
const isButtonDisabled = Boolean(
680684
isDownloading[data.id]
681685
|| isRestrictedForMember
@@ -685,14 +689,6 @@ export const TableIterativeReview: FC<Props> = (props: Props) => {
685689
const downloadButton = (
686690
<button
687691
onClick={function onClick() {
688-
if (
689-
isRestrictedForMember
690-
|| failedScan
691-
|| isOwnershipRestricted
692-
) {
693-
return
694-
}
695-
696692
downloadSubmission(data.id)
697693
}}
698694
className={styles.textBlue}
@@ -708,27 +704,19 @@ export const TableIterativeReview: FC<Props> = (props: Props) => {
708704
): Promise<void> {
709705
event.stopPropagation()
710706
event.preventDefault()
711-
712-
if (!data.id) {
713-
return
714-
}
715-
716707
await copyTextToClipboard(data.id)
717708
toast.success('Submission ID copied to clipboard', {
718709
toastId: `challenge-submission-id-copy-${data.id}`,
719710
})
720711
}
721712

722-
let tooltipContent: string | undefined
723-
if (failedScan) {
724-
tooltipContent = 'Submission failed virus scan'
725-
} else if (isRestrictedForMember) {
726-
tooltipContent = memberRestrictionMessage ?? restrictionMessage
727-
} else if (isOwnershipRestricted) {
728-
tooltipContent = DOWNLOAD_OWN_SUBMISSION_TOOLTIP
729-
} else if (isSubmissionDownloadRestricted && restrictionMessage) {
730-
tooltipContent = restrictionMessage
731-
}
713+
const tooltipContent = failedScan
714+
? 'Submission failed virus scan'
715+
: isRestrictedForMember
716+
? memberRestrictionMessage ?? restrictionMessage
717+
: isOwnershipRestricted
718+
? DOWNLOAD_OWN_SUBMISSION_TOOLTIP
719+
: (isSubmissionDownloadRestricted && restrictionMessage) || undefined
732720

733721
const downloadControl = isOwnershipRestricted ? (
734722
<span className={styles.textBlue}>

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,10 @@ const createSubmissionColumn = (config: SubmissionColumnConfig): TableColumn<Scr
125125
propertyName: 'submissionId',
126126
renderer: (data: Screening) => {
127127
const isRestrictedBase = config.isSubmissionDownloadRestrictedForMember(data.memberId)
128-
const failedScan = data.virusScan === false
128+
const normalizedVirusScan = data.isFileSubmission === false
129+
? undefined
130+
: data.virusScan
131+
const failedScan = normalizedVirusScan === false
129132
const isRestrictedForRow = isRestrictedBase || failedScan
130133
const tooltipMessage = failedScan
131134
? 'Submission failed virus scan'
@@ -231,6 +234,10 @@ const createVirusScanColumn = (): TableColumn<Screening> => ({
231234
label: 'Virus Scan',
232235
propertyName: 'virusScan',
233236
renderer: (data: Screening) => {
237+
if (data.isFileSubmission === false) {
238+
return <span>N/A</span>
239+
}
240+
234241
if (data.virusScan === true) {
235242
return (
236243
<span className={styles.virusOkIcon} title='Scan passed' aria-label='Scan passed'>
@@ -765,6 +772,7 @@ export const TableSubmissionScreening: FC<Props> = (props: Props) => {
765772
map.set(submissionId, {
766773
...existing,
767774
id: existing?.id ?? submissionId,
775+
isFileSubmission: screening.isFileSubmission ?? existing?.isFileSubmission,
768776
isLatest: screening.isLatest ?? existing?.isLatest,
769777
memberId: screening.memberId ?? existing?.memberId ?? '',
770778
submittedDate: createdAt,

src/apps/review/src/lib/components/common/TableColumnRenderers.tsx

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import styles from './TableColumnRenderers.module.scss'
3838
/**
3939
* Renders the submission ID cell with download controls and copy-to-clipboard actions.
4040
*/
41+
// eslint-disable-next-line complexity -- Handles multiple restriction scenarios for submission downloads.
4142
export function renderSubmissionIdCell(
4243
submission: SubmissionRow,
4344
config: DownloadButtonConfig,
@@ -62,7 +63,10 @@ export function renderSubmissionIdCell(
6263
const isOwnershipRestricted = shouldRestrictSubmitterToOwnSubmission && !isOwnedSubmission
6364
const isRestrictedForMember = isSubmissionDownloadRestrictedForMember(submission.memberId)
6465
const memberRestrictionMessage = getRestrictionMessageForMember(submission.memberId)
65-
const failedScan = submission.virusScan === false
66+
const normalizedVirusScan = submission.isFileSubmission === false
67+
? undefined
68+
: submission.virusScan
69+
const failedScan = normalizedVirusScan === false
6670
const isButtonDisabled = Boolean(
6771
isDownloading[submission.id]
6872
|| isRestrictedForMember
@@ -72,10 +76,6 @@ export function renderSubmissionIdCell(
7276
const downloadButton = (
7377
<button
7478
onClick={function onClick() {
75-
if (isRestrictedForMember || failedScan || isOwnershipRestricted) {
76-
return
77-
}
78-
7979
downloadSubmission(submission.id)
8080
}}
8181
className={classNames(styles.textBlue, styles.linkButton)}
@@ -91,29 +91,21 @@ export function renderSubmissionIdCell(
9191
): Promise<void> {
9292
event.stopPropagation()
9393
event.preventDefault()
94-
95-
if (!submission.id) {
96-
return
97-
}
98-
9994
await copyTextToClipboard(submission.id)
10095
toast.success('Submission ID copied to clipboard', {
10196
toastId: `challenge-submission-id-copy-${submission.id}`,
10297
})
10398
}
10499

105-
let tooltipContent: string | undefined
106-
if (failedScan) {
107-
tooltipContent = virusScanFailedMessage
108-
} else if (isRestrictedForMember) {
109-
tooltipContent = memberRestrictionMessage
110-
?? restrictionMessage
111-
?? downloadOwnSubmissionTooltip
112-
} else if (isOwnershipRestricted) {
113-
tooltipContent = downloadOwnSubmissionTooltip
114-
} else if (isSubmissionDownloadRestricted && restrictionMessage) {
115-
tooltipContent = restrictionMessage
116-
}
100+
const tooltipContent = failedScan
101+
? virusScanFailedMessage
102+
: isRestrictedForMember
103+
? memberRestrictionMessage
104+
?? restrictionMessage
105+
?? downloadOwnSubmissionTooltip
106+
: isOwnershipRestricted
107+
? downloadOwnSubmissionTooltip
108+
: (isSubmissionDownloadRestricted && restrictionMessage) || undefined
117109

118110
const downloadControl = isOwnershipRestricted ? (
119111
<span className={styles.textBlue}>

src/apps/review/src/lib/models/Screening.model.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ export interface Screening {
5757
* Submission type (e.g. CONTEST_SUBMISSION, CHECKPOINT_SUBMISSION).
5858
*/
5959
type?: string
60+
/**
61+
* Flag indicating whether the submission includes an uploaded file.
62+
*/
63+
isFileSubmission?: boolean
6064
/**
6165
* The phase name of the associated review (e.g., 'Screening', 'Review').
6266
* Used for defensive filtering to ensure phase data isolation.
@@ -96,6 +100,7 @@ export function convertBackendSubmissionToScreening(
96100
challengeId: data.challengeId,
97101
createdAt,
98102
createdAtString,
103+
isFileSubmission: data.isFileSubmission,
99104
isLatest: data.isLatest,
100105
memberId: data.memberId,
101106
result,
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDMuiy2OYMuuVyy
3+
Zudim1AFxDQOCXoab+R/qvhjMbHXBxgvKjqsDv/h9viO1yeamRdLgg1c2otjcHLB
4+
wcZfW73CWH3Ezqqju4EoTLM6ww0JMESKWRS3Fc9yuoOCnEr7xYo8FgtqOw7gPaDw
5+
tCXz7I270zSPOatjAszu3Z2fuGHbxYz2xlvllsjDlkUXyAHbyi2ZHY3sJms2BBbQ
6+
MCYFgUFK8Ea8zfhViWFWkbaW+pUyJKtgUnsZjBf72YqnHQ2srphuqIGht0aNv1Ip
7+
FbZ1ZdkhlLiudaB9hOwl70D/CY8A0qw9NiOOv/PaGkea5wa1HUuzrEqskO6ze8yG
8+
y+DwpcCdAgMBAAECggEBAJ0bfjZ1GkOgAg/yQjz8vUM/l0byZN6m4W5L0QOmXjiK
9+
fDetq4rgk+NfeM19NSpBs4vBiOmp2O/9mkMwpkAFkjDzYcjHZFH0EaDQg3ZjurxD
10+
a0XUKL57oVAE6+kucaiWpoeHz0i9e6QAB2LQjJONBBOQeDQ1aF26B3SDY3PvtkFF
11+
D9Z3JGTYLNBf39+pIFHvkQMec0FG8Hs1ZUd9rW9zBLJB5nGSbD8EiKaLLGVG1ohQ
12+
Cek2GUMcPH8u5CO6rhOsxwEtv5SvGYajJbNrHiO+f/pMVf19Qx/agQAa8wVCcklo
13+
6eljC1y1sMWwigLSzwv2RK4drqN5s/2smpxZWPGj2iECgYEA9Df3DA94+GZB5fcC
14+
TJdnsAWjzlgQfbJkC1XFaYZwIvcjgmQpy/QySUUOyiOwuxqRoD2R5SeXp7UoKaPk
15+
v3sdeA9VTD7Ev8eefu3BzbUQ5dZIPlZUlkb21tKhhMlqfn40Xc5B/gwPSbNEym/l
16+
QYx0vIXg/TjCQxow4DtA4Qm36IkCgYEA1pqAcLv3IV8xtM2VaFQwtsk+7Kc/yRaQ
17+
VDjv68iNJmI47fdX5eeRtDWCkAKyolLKYKty5FuwwGDHLbNTVdJtX+2wLochQ2rC
18+
5Pu/UwEV82MEcLmHONK+ZRXVwlt5fbxhcQo6x24cOksRvNwGDTi3YOwreO/ZE8w7
19+
aW1RBBdiKnUCgYEAm+I9Js2ZgbSDy63nIcxiutBexo8ft5vuj+2nnLvbR/ZIDCqz
20+
IyQ0FOCnmA8/96311jp2rbaf7sSLZkje8fo7zS68W3aVT3SzjoFke1Ff/9TPODsS
21+
svmJBYZc4s1N1H/qHRZSuT4pY/mxpyXVSAnHWa569icMmJhXKkmoF/yED0ECgYEA
22+
tUJGHfIFKCC5YRcLjNUfWCPejBAvpe7y9NAqhSIdZkAsCYKSsVLIFEfmATDmJIh8
23+
+u2U2yA+yB513TnLt39GdnHSD1p/U+wGtVWVIcyW9724cGWjuvD1c3ff1otgsDy+
24+
qLWVNADiwrHJR5UnX196M9kGVt1uonQr8j4s4aHGfkkCgYBPrAMkdSFd2XZlHgvB
25+
KBsnJWMet8ZqtMkHdphkQaRIiwMhXiDJzqQBMZRu6N166HlKkQA3DIy8CWgAThCc
26+
ec/0dmAOaBvRG6WiPF6W79Yw7db8AvjeaFaaLFZh/9ICt8RJ4yBzaOhG7OlLURKW
27+
4phJAlDyYfZ5tbZu91yxlLRIkQ==
28+
-----END PRIVATE KEY-----

ssl-local/local.topcoder.com.pem

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIEajCCAtKgAwIBAgIQDXQVrgMqu2zr0wgZaSESSTANBgkqhkiG9w0BAQsFADCB
3+
lzEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMTYwNAYDVQQLDC1qbWdh
4+
c3BlckBqbWdhc3Blci13b3Jrc3RhdGlvbiAoSnVzdGluIEdhc3BlcikxPTA7BgNV
5+
BAMMNG1rY2VydCBqbWdhc3BlckBqbWdhc3Blci13b3Jrc3RhdGlvbiAoSnVzdGlu
6+
IEdhc3BlcikwHhcNMjUxMDMxMDMyOTE3WhcNMjgwMTMxMDMyOTE3WjBhMScwJQYD
7+
VQQKEx5ta2NlcnQgZGV2ZWxvcG1lbnQgY2VydGlmaWNhdGUxNjA0BgNVBAsMLWpt
8+
Z2FzcGVyQGptZ2FzcGVyLXdvcmtzdGF0aW9uIChKdXN0aW4gR2FzcGVyKTCCASIw
9+
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMy6LLY5gy65XLJm52KbUAXENA4J
10+
ehpv5H+q+GMxsdcHGC8qOqwO/+H2+I7XJ5qZF0uCDVzai2NwcsHBxl9bvcJYfcTO
11+
qqO7gShMszrDDQkwRIpZFLcVz3K6g4KcSvvFijwWC2o7DuA9oPC0JfPsjbvTNI85
12+
q2MCzO7dnZ+4YdvFjPbGW+WWyMOWRRfIAdvKLZkdjewmazYEFtAwJgWBQUrwRrzN
13+
+FWJYVaRtpb6lTIkq2BSexmMF/vZiqcdDayumG6ogaG3Ro2/UikVtnVl2SGUuK51
14+
oH2E7CXvQP8JjwDSrD02I46/89oaR5rnBrUdS7OsSqyQ7rN7zIbL4PClwJ0CAwEA
15+
AaNnMGUwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMB8GA1Ud
16+
IwQYMBaAFCCVQwZNwHdcVw9seUq6zOF51Vu6MB0GA1UdEQQWMBSCEmxvY2FsLnRv
17+
cGNvZGVyLmNvbTANBgkqhkiG9w0BAQsFAAOCAYEABmxMnJ1YZEY/dzwXqB1JlYBo
18+
OxBN3kY18KwRcDuawUmuopdfkIaNyCrLLsA+Ick9lMpiEHzYd854FhRWvktk9O+J
19+
ExuvyCkubKMsKKdpTPCdui6W5hHz562nOr9HCf/1PLtHTnwo9r1ZeT/rYvgGL9Fv
20+
tFK6Y/+u8kZruSJw1hro5SZEKmzsEFReDAzrsDES7kkX3tOesOXMgq4cNziP+LJ3
21+
sty9f1dyBYO8RBKWlQi4Bo1noM1IsZcoLucTpr2xuMvswp/EL+DOZfcQxmh5v6Q2
22+
2FbJBFaOeJPU06sL0II/1hHZzCQcspCiZ9axcE0Hqy8ATJFuCshLup8Dsllzojw/
23+
Tao0NjWvbufhhfCsM7jFtpYjtK3/93HEVnYxcE2aqd4pcAkT+pwT6XrbM50Pdv0d
24+
zHGzB08z2U4UoeipPK8An36rRZu1gP7XTwKxJNUYIFqKY+ZKR3hbXgiYlapvH5bD
25+
ZLoY9QoZGsWBimeHAoBx0vwF6d91uT8cffzH91wL
26+
-----END CERTIFICATE-----

0 commit comments

Comments
 (0)