Conversation
…board-page PM-5370 campus leaderboard page
…board-page PM-5370 - Minor UI updates for campus leaderboard
What was broken
In the work app challenge editor, removing tags from a challenge did not
persist. Clearing the Tags field and saving showed "Challenge saved
successfully", but the removed tags were still present after the save and on
reload.
Root cause
transformFormDataToChallenge() passes the payload through removeEmptyValues(),
which drops empty arrays unless the key is listed in
ALLOW_EMPTY_ARRAY_PAYLOAD_KEYS. Only "groups" and "terms" were listed, so
clearing every tag produced tags: [] which was stripped from the PATCH body.
With no tags key in the request, the challenge API left the stored tags
untouched. Verified against api.topcoder-dev.com that PATCH
/v6/challenges/{id} with {"tags": []} does clear the tags, confirming the
defect is in the UI payload and not in the API.
What was changed
Added "tags" to ALLOW_EMPTY_ARRAY_PAYLOAD_KEYS in
src/apps/work/src/lib/utils/challenge-editor.utils.ts so an empty tags array
is sent to the API and clears the challenge tags, matching the existing
behavior for groups and terms.
Any added/updated tests
Added a unit test in challenge-editor.utils.spec.ts asserting that
transformFormDataToChallenge keeps an empty tags array in the API payload. The
test fails without the fix and passes with it.
…challenge What was broken For challenges in 'New' status, the Budget Approve/Reject buttons were not displayed for TM/Admin users immediately after saving the challenge. The buttons only appeared after a full page refresh. Root cause The budget approval actions in the Work Manager challenge editor are gated on `hasPersistedPrizeSets`, which was derived from the `challenge` prop. That prop comes from the page's SWR challenge fetch, which is not revalidated after a save, so it stays on the pre-save snapshot. Challenges are created in 'New' status before the Prizes & Billing section is even rendered, so a 'New' challenge never has persisted prize sets. Entering prizes and saving persists them (and moves the challenge to Draft), but the stale prop still reported no persisted prizes, so the approval actions stayed hidden until a refresh refetched the challenge. What was changed - ChallengeEditorForm now tracks the persisted prize sets in local state, seeded from the `challenge` prop, kept in sync when that prop changes, and advanced with the prize sets returned by challenge-api after a successful save. The approval-action gate reads that state, so the Approve/Reject buttons render as soon as the save response confirms the prizes were stored. - Extracted the prize-set check into a documented `hasPrizeSetWithPrizes` helper. Added/updated tests - Added `shows budget approval actions after saving a new challenge without persisted prizes` to ChallengeEditorForm.spec.tsx, which saves a 'New' challenge whose fetched snapshot has no prize sets and asserts the Approve/Reject Budget buttons appear once the form switches to read-only view mode (without the challenge prop being refetched). - Expanded the ChallengePrizesField test mock so specs can set a placement prize on the form.
What was broken The "Development Stats" win total on the member profile stats page did not match the sum of the wins shown on the Development subtrack cards. On prod, sdgun showed 321 wins while the cards summed to 329, and standlove showed 738 wins while the cards summed to 978. The total was correct on first paint and then changed to the wrong value a few seconds later, once the stats history request resolved. Root cause getTrackSummaryStats aggregates the parent track totals from stats history so that a challenge appearing under two subtracks is only counted once. A subtrack card falls back to the aggregate `wins` counter when its history rows carry no placement data (rating-only rows), but the parent total only counted history rows with `placement === 1`. Any subtrack that had history without placements was therefore treated as having zero wins in the total while its card still displayed the aggregate count, so those wins silently disappeared from the summary once stats history loaded. For sdgun, CONTENT_CREATION has a single rating-only history row and 8 aggregate wins, which is exactly the 329 - 321 = 8 difference. For standlove, ARCHITECTURE (68), DESIGN (147) and DEVELOPMENT (25) are all rating-only and account for the 978 - 738 = 240 difference. What was changed - src/apps/profiles/src/hooks/useFetchActiveTracks.tsx: added a `hasPlacementHistory` helper and split the history summaries into placement-bearing rows and rating-only rows. Placement-bearing rows keep the existing de-duplicated unique-history win count, while rating-only rows now contribute their aggregate wins to the parent total, the same way subtracks with no history at all already did. The `historyStatsWins` fallback is now computed from placement-bearing summaries only so those wins are not counted twice, and its `Math.max` is seeded with 0 to avoid `-Infinity`. - Challenge and submission totals are untouched; only the win aggregation changed. Any added/updated tests - src/apps/profiles/src/hooks/useFetchActiveTracks.spec.tsx: new `getTrackSummaryStats` suite with two cases, modeled on the sdgun payload: one asserting the Development total equals the sum of the subtrack card wins when a subtrack has rating-only history (fails with 77 vs 85 before this change), and one asserting aggregate wins are preserved when no subtrack history has placements. - Verified against the live prod payloads for both members reported in the ticket: Development totals now come out as 329 for sdgun and 978 for standlove, matching the sum of the subtrack cards in both cases, with challenge and submission totals unchanged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…board-page Make campus leaderboard profile name clickable
…s-tooltip Fixes for general statistics tooltip
What was broken Work Manager rendered the design Submission limit control with no option selected, so a saved Unlimited or Limited value was invisible on the challenge view page and after saving a draft, even though the value was stored in challenge metadata. Copilots could also still raise or lower the limit after members had uploaded submissions, and the Review application does not retroactively create scorecards for submissions that a later limit would have allowed. Root cause The radio selection and the count are display-only form fields that are not part of the persisted challenge payload. The editor resets the form when challenge data arrives and after each save, which drops both fields. The seeding effect only ran while those fields were undefined and its dependencies did not change when a reset cleared them, so the fields were never re-seeded and the radio group rendered with no selection. Nothing in the editor tied the control to existing submissions. What was changed The submission-limit selection and count are now re-seeded from the current challenge metadata whenever they do not match it, so the persisted limit stays visible after the challenge loads and after a draft save. The mode and count become read-only, with an explanatory hint, once the challenge has at least one contest or checkpoint submission. Challenge form data now carries numOfCheckpointSubmissions alongside numOfSubmissions so two-round design challenges lock on checkpoint uploads too, and FormRadioGroup accepts the optional hint already supported by FormFieldWrapper. Any added/updated tests Added MaximumSubmissionsField coverage for restoring the persisted limit after a form reset, replacing a stale selection with the persisted metadata, locking on a contest submission, locking on a checkpoint submission, and staying editable while no submission exists. Added a challenge-editor utils test that numOfCheckpointSubmissions is kept in form data.
What was broken In the Admin advanced review configuration for Design challenges, the Checkpoint Review, Review, and Approval "Member N" selectors were rendered with the red required asterisk, and closed-opportunity validation refused to save or launch until a member was picked for each of them. Those assignments are no longer something an admin has to make, because the selected copilot is assigned to those private phases automatically. Root cause PM-5755 made the editor assign the selected copilot to the Design Checkpoint Review, Review, and Approval reviewer rows during save, but the reviewer assignment exception was never widened past Screening and Checkpoint Screening. `isScreenerAssignmentOptional` therefore still reported those Design review phases as requiring an up-front member, which drove both the `required` flag on the member autocomplete and the closed-opportunity slot validation in the yup schema and the draft-save reviewer check. What was changed Renamed `isScreenerAssignmentOptional` to `isReviewerAssignmentOptional` and gave it an `isDesignChallenge` argument that also treats Checkpoint Review, Review, and Approval as deferrable, matching the phases the copilot is assigned to during save. HumanReviewTab passes that flag when the selected track is Design and the selected type is Challenge, so the advanced view no longer marks those member fields required. The challenge editor schema reads the same flag from a new resolver validation context supplied by ChallengeEditorForm, which also re-triggers reviewer validation when the track or type selection changes, and the draft-save reviewer check receives it through its existing options object. Every other track, challenge type, and reviewer phase keeps the previous required behavior. The ChallengeEditorPage README was updated to match. Any added/updated tests Added a reviewer.utils unit spec covering the screening exception, the new Design copilot phase exception, and the unchanged required cases for other tracks, AI reviewer rows, and unknown phases. Added schema coverage for accepting unassigned Design Review and Approval rows with the design validation context and for still rejecting them without it. Added a HumanReviewTab test asserting the Design Challenge Checkpoint Review, Review, and Approval member fields render as optional, and a ChallengeEditorForm test that launches a Design draft whose copilot-assigned review rows have no member. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…board-page PM-5370 - show placement for 2nd and 3rd place
PM-5758: show and lock the design submission limit in Work Manager
PM-5562: Count rating-only history subtrack wins in track totals
PM-5165: show budget approve/reject actions right after saving a New challenge
PM-5896: keep empty tags array in challenge update payload
PM-5913: Drop the required marker from Design review member fields
…board-page Fixes to campus leaderboard UI
…opilots PM-5954 - show actions in review tab for copilots & reviewers
What was broken The previous PM-5562 follow-up made Development totals include aggregate wins for subtracks whose history had no placement data. QA still found that the profile totals for pops and wleite showed 76 instead of 152 and 2 instead of 36. Root cause Legacy Marathon Match history is partial but contains placement fields. The shared subtrack summary therefore treated those incomplete rows as the source of truth and replaced 76 and 34 valid aggregate wins with zero placement wins. The prior fix only covered histories with no placement fields at all. What was changed Keep an explicit aggregate wins value authoritative for Marathon Match while retaining placement-derived wins for modern tracks. This preserves the earlier Development deduplication and rating-only history fixes. Any added/updated tests Added a regression case modeled on the pops payload, proving that 76 aggregate Marathon Match wins survive a partial placement history with no first-place rows. The existing placement-history and Development aggregation tests remain passing.
PM-4699 Add bubble skill statistics UI with mock data
PM-5562: Preserve aggregate Marathon Match wins
This reverts commit 7d71cb8.
Revert CodeCommit backup mirror
Integrate UI with skill statistics api
…board-page_fixes PM-5939 - campus leaderboard UI
PM-5964 Alignment issue in profile section
What was broken In Work Manager a copilot could select "Limited" for the design submission limit, leave the "Limit count" textbox empty, and still save or autosave the challenge. No error was shown, and the challenge was persisted with limit metadata that declares a limit but carries no number, which no downstream application can enforce. Root cause The submission-limit radio selection and the count are display-only form fields that are serialized into the legacy submissionLimit challenge metadata entry. Nothing in the challenge editor schema validated that entry, so an empty count produced no validation error, formState.isValid stayed true, and both manual save and autosave accepted the incomplete value. What was changed The parsing and serialization of the submissionLimit metadata contract moved into a shared submission-limit utility so the editor field and the validation schema read the same value. The challenge editor schema now rejects limit metadata that declares a limit without a count of at least 1, and reports the message on the visible submissionLimitCount field so the error renders under "Limit count" and in the save footer. Saving, autosaving, and launching are blocked until a count is entered. The rule only applies while the control is editable. The challenge editor publishes an isSubmissionLimitConfigurable flag on the existing yup validation context, which is true only for Design submission settings that have no uploaded contest or checkpoint submissions. That keeps non-Design challenges, and challenges whose limit is already locked by member submissions, saveable. The field revalidates itself after each mode or count change so the error tracks the value that would be saved. Any added/updated tests Added submission-limit utility tests for detecting a limited setting with a missing or zero count and for the contest/checkpoint submission check. Added challenge editor schema tests that a limited setting without a count is rejected on the submissionLimitCount path, that a zero count is rejected, that a valid count and an unlimited setting pass, and that the rule is skipped when the limit is not configurable. Added MaximumSubmissionsField tests that saving is blocked while the count is empty and succeeds once a count is entered. Five of the new tests fail against the unchanged source.
…ate-submissions PM-5727 - UI for duplicate submisisons in work app & review app
PM-5758: require a count when design submissions are limited
…bile-ui Campus leaderboard mobile UI Fixes
…bile-ui PM-5886 - campus leaderboard UI updates
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
https://topcoder.atlassian.net/browse/PM-5370
https://topcoder.atlassian.net/browse/PM-5896
https://topcoder.atlassian.net/browse/PM-5562
https://topcoder.atlassian.net/browse/PM-5913
https://topcoder.atlassian.net/browse/PM-5165
https://topcoder.atlassian.net/browse/PM-5939
https://topcoder.atlassian.net/browse/PM-5886