Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
cc9a480
PM-5015 - ai review only - hide human review when "Ai only" is selected
vas3a May 25, 2026
4526a05
dev deploy
vas3a May 25, 2026
0a4b552
build & deploy dev tags
vas3a May 25, 2026
7438506
Remove manual reviewers in ai-only mode
vas3a May 25, 2026
f266fd6
PM-5015 - disable review timeline
vas3a May 25, 2026
b3b0846
lint
vas3a May 25, 2026
2eb0cee
Merge branch 'dev' of github.com:topcoder-platform/platform-ui into P…
vas3a May 26, 2026
cc1394b
Merge branch 'dev' of github.com:topcoder-platform/platform-ui into P…
vas3a May 27, 2026
0885baf
Merge branch 'dev' of github.com:topcoder-platform/platform-ui into P…
vas3a May 28, 2026
aeaf0eb
Hide "ai screening" phase for AI-only challenges
vas3a May 28, 2026
f07fad9
PM-5102 activate validation
kkartunov May 28, 2026
6393a36
Merge pull request #1893 from topcoder-platform/system-admin-ai
kkartunov May 28, 2026
d883406
PM-5015 - Render winners & final score for AI-only challenges
vas3a May 28, 2026
6122d1a
Merge pull request #1892 from topcoder-platform/PM-5015_ai-only-review
vas3a May 29, 2026
4a410f1
Merge pull request #1895 from topcoder-platform/hotfix
kkartunov Jun 1, 2026
368efed
Merge pull request #1896 from topcoder-platform/PM-5015_ai-only-review
vas3a Jun 2, 2026
425f563
PM-5203 - allow manager to update ai score
vas3a Jun 2, 2026
f42a7a9
lint
vas3a Jun 2, 2026
5b5f4b0
lint
vas3a Jun 2, 2026
8323301
PM-5203 - manager score override
vas3a Jun 2, 2026
6d70d38
lint
vas3a Jun 2, 2026
bc0becd
PM-5203 - filter latest submissions
vas3a Jun 3, 2026
c974999
lint
vas3a Jun 3, 2026
f95d972
Improve UI for approval tab content
vas3a Jun 3, 2026
799d1f9
PM-5203 - approval UI
vas3a Jun 3, 2026
65ffbc1
lint
vas3a Jun 3, 2026
84f686e
PM-5203 - More UI improvements for AI approval
vas3a Jun 3, 2026
9196cb3
Final score for ai only challenges in work manager
vas3a Jun 4, 2026
7d29c22
Merge branch 'dev' of github.com:topcoder-platform/platform-ui into P…
vas3a Jun 4, 2026
a349c9f
updated AI reviews
Jun 4, 2026
bd062a1
Updated Reviews App for AI locked Submission
Jun 4, 2026
b591a40
Updated Reviews App for AI locked Submission
Jun 4, 2026
c0647ab
Final score in work manager submissions
vas3a Jun 4, 2026
1bba223
Merge pull request #1897 from topcoder-platform/PM-5035
Harshitchudasama Jun 4, 2026
005ceb5
Updated Reviews App
Jun 4, 2026
77ef440
Merge pull request #1898 from topcoder-platform/PM-5035
Harshitchudasama Jun 4, 2026
8d9bfe0
PM-5203 - Update UI for approval tab
vas3a Jun 4, 2026
45753a2
lint
vas3a Jun 4, 2026
70d1859
Merge branch 'dev' of github.com:topcoder-platform/platform-ui into P…
vas3a Jun 4, 2026
7ae5350
keep "override" label after re-run
vas3a Jun 4, 2026
836e68b
show error if manual reviewers aren't set
vas3a Jun 4, 2026
c0b3834
check initial score
vas3a Jun 4, 2026
a6f2f2a
lint
vas3a Jun 4, 2026
40eaae2
Merge pull request #1899 from topcoder-platform/PM-5203_approval-phas…
vas3a Jun 5, 2026
2086b96
Merge pull request #1908 from topcoder-platform/marathon-compiler-fixes
jmgasper Jun 7, 2026
906553e
Update message for no reviewer
vas3a Jun 8, 2026
6fd59b4
Allow inline score editing in ai scorecard view in approval phase
vas3a Jun 8, 2026
c1c86af
Remove "edit" in approval tab. this will happen in scorcard viewer
vas3a Jun 8, 2026
f34676e
Allow score edit only during approval
vas3a Jun 8, 2026
d4d2f4f
Use the richtext editor for manager comment
vas3a Jun 8, 2026
63d917b
lint
vas3a Jun 8, 2026
0979ddd
Merge pull request #1910 from topcoder-platform/PM-5203_approval-phas…
vas3a Jun 8, 2026
c8a812d
PM-5282: Preserve schedule phase ids on update
jmgasper Jun 9, 2026
5b1e481
Merge pull request #1911 from topcoder-platform/PM-5282
jmgasper Jun 9, 2026
6fa46f5
PM-5243: Add reviewer with next valid default phase
jmgasper Jun 9, 2026
d912181
Merge pull request #1912 from topcoder-platform/PM-5243
jmgasper Jun 9, 2026
a561abb
PM-5231: Add scorer validation upload UI
jmgasper Jun 9, 2026
356ec4d
Fix for hang in work app on 1 round design challenges (PM-5243)
jmgasper Jun 9, 2026
104440e
PM-5299: Preserve placement prizes when editing checkpoints
jmgasper Jun 9, 2026
12af967
Merge pull request #1917 from topcoder-platform/PM-5231
jmgasper Jun 9, 2026
114623e
Merge pull request #1918 from topcoder-platform/PM-5299
jmgasper Jun 9, 2026
947fcf1
Escalation notes: keep it consistent
vas3a Jun 9, 2026
7b992cc
PM-4300: use final MM scores for winners
jmgasper Jun 9, 2026
398220d
lint
vas3a Jun 9, 2026
3a14982
Merge pull request #1926 from topcoder-platform/PM-5203_approval-phas…
vas3a Jun 9, 2026
a175b11
edit scorecard label
vas3a Jun 9, 2026
497cc13
override label
vas3a Jun 9, 2026
62cbbef
Merge pull request #1927 from topcoder-platform/PM-5203_approval-phas…
vas3a Jun 9, 2026
b6c3158
remove debug code
vas3a Jun 9, 2026
2e0f155
Merge pull request #1928 from topcoder-platform/PM-5203_approval-phas…
vas3a Jun 9, 2026
c706d16
Fix overriden label, fix sideeffect in useefect
vas3a Jun 9, 2026
7c781d7
lint
vas3a Jun 9, 2026
3ce10a9
Merge pull request #1929 from topcoder-platform/PM-5203_approval-phas…
vas3a Jun 9, 2026
869ce8f
Fix sorting of multiple ai runs
vas3a Jun 9, 2026
c316537
lint
vas3a Jun 9, 2026
c2ae5bf
Merge pull request #1930 from topcoder-platform/fix-sorting-for-multi…
vas3a Jun 9, 2026
74e17da
Merge pull request #1924 from topcoder-platform/PM-4300
jmgasper Jun 9, 2026
c2490a5
Require manual reviewers
vas3a Jun 10, 2026
dc28399
Merge pull request #1935 from topcoder-platform/PM-5216_require-manua…
vas3a Jun 10, 2026
023c8c0
Removed talent-search app from platform-ui
Harshitchudasama Jun 11, 2026
3a51b86
Removed talent-search app from platform-ui
Harshitchudasama Jun 11, 2026
ab5906f
Clean up talent-search unused code and linting errors
Harshitchudasama Jun 11, 2026
97d40e8
Clean up talent-search unused code and linting errors
Harshitchudasama Jun 11, 2026
d80092b
Updates for running locally on Ubuntu without hitting file watch limi…
jmgasper Jun 11, 2026
40d7256
Lint fix
jmgasper Jun 12, 2026
5e9c72a
updated platform ui to remove talent-search
Harshitchudasama Jun 12, 2026
cdbdbaa
Merge pull request #1936 from topcoder-platform/PM-5120
Harshitchudasama Jun 12, 2026
160e60f
restore customer/talent-search
vas3a Jun 14, 2026
75f3071
PM-5073 - talent search update
vas3a Jun 14, 2026
4a8c028
lint fixes
vas3a Jun 14, 2026
5911dce
Merge pull request #1937 from topcoder-platform/PM-5073_talent-search
vas3a Jun 15, 2026
929f687
Add in talent page to reports portal
jmgasper Jun 16, 2026
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
4 changes: 4 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,8 @@ workflows:
ignore:
- master
- qa
tags:
only: /^dev-.*/

- build-qa:
context: org-global
Expand All @@ -227,6 +229,8 @@ workflows:
only:
- dev
- hide_ba_details
tags:
only: /^dev-.*/

- deployQa:
context: org-global
Expand Down
57 changes: 56 additions & 1 deletion craco.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,59 @@ const CracoEnvPlugin = require('craco-plugin-env')
const BabelRcPlugin = require('@jackwilsdon/craco-use-babelrc');

const isProd = process.env.APPMODE === "production";
const nodeModulesWatchIgnore = '**/node_modules/**';
const watchPollInterval = 1000;

/**
* Appends the node_modules ignore pattern to an existing watch ignore config.
*
* @param {RegExp|string|Array<RegExp|string>|undefined} ignored - Existing ignore config from webpack or dev server watches.
* @returns {Array<RegExp|string>} Watch ignore config with node_modules excluded. Used by CRACO watch overrides.
* @throws This function does not throw.
*/
function withNodeModulesWatchIgnore(ignored) {
return [
...(Array.isArray(ignored) ? ignored : ignored ? [ignored] : []),
nodeModulesWatchIgnore,
];
}

/**
* Preserves CRA's dev-server static config while disabling public asset watches.
*
* @param {object} devServerConfig - CRA webpack-dev-server config passed through CRACO for yarn start.
* @returns {object} Dev-server config that serves public assets without consuming file watchers for them.
* @throws This function does not throw.
*/
function configureDevServer(devServerConfig) {
const staticConfig = devServerConfig.static || {};

return {
...devServerConfig,
static: {
...staticConfig,
watch: false,
},
};
}

/**
* Preserves CRA's webpack config while polling watch mode and ignoring node_modules.
*
* @param {object} webpackConfig - CRA webpack config passed through CRACO.
* @returns {object} Webpack config with polling enabled and node_modules excluded from watchOptions.
* @throws This function does not throw.
*/
function configureWebpack(webpackConfig) {
return {
...webpackConfig,
watchOptions: {
...webpackConfig.watchOptions,
ignored: withNodeModulesWatchIgnore(webpackConfig.watchOptions?.ignored),
poll: watchPollInterval,
},
};
}

function getModeName() {
const index = process.argv.indexOf('--mode');
Expand Down Expand Up @@ -33,6 +86,8 @@ module.exports = {
} },
],

devServer: configureDevServer,

webpack: {
alias: {
// aliases used in JS/TS
Expand All @@ -41,7 +96,6 @@ module.exports = {
'@learn': resolve('src/apps/learn/src'),
'@devCenter': resolve('src/apps/dev-center/src'),
'@gamificationAdmin': resolve('src/apps/gamification-admin/src'),
'@talentSearch': resolve('src/apps/talent-search/src'),
'@profiles': resolve('src/apps/profiles/src'),
'@wallet': resolve('src/apps/wallet/src'),
'@walletAdmin': resolve('src/apps/wallet-admin/src'),
Expand All @@ -51,5 +105,6 @@ module.exports = {
// aliases used in SCSS files
'@libs/ui/styles': resolve('src/libs/ui/lib/styles'),
},
configure: configureWebpack,
}
}
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"report:coverage": "nyc report --reporter=html",
"report:coverage:text": "nyc report --reporter=text",
"sb": "storybook dev -p 6006",
"sb:build": "storybook build -o build/storybook"
"sb:build": "storybook build -o build/storybook",
"deploy:dev": "BRANCH=$(git rev-parse --abbrev-ref HEAD) && TAG=\"dev-${BRANCH}\" && git tag -d \"$TAG\" 2>/dev/null; git push origin \":refs/tags/$TAG\" 2>/dev/null; git tag \"$TAG\" && git push origin \"$TAG\""
},
"dependencies": {
"@codemirror/autocomplete": "^6.20.1",
Expand Down Expand Up @@ -259,5 +260,6 @@
"volta": {
"node": "22.13.0",
"yarn": "1.22.22"
}
},
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
}
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,10 @@ export const AiReviewTemplatesPage: FC = () => {
open: false,
})
const [isToggling, setIsToggling] = useState(false)
const [disabledWorkflowsModal, setDisabledWorkflowsModal] = useState<{
open: boolean;
workflowNames: string[];
}>({ open: false, workflowNames: [] })

const trackOptions: InputSelectOption[] = useMemo(() => {
const seen = new Set<string>()
Expand Down Expand Up @@ -309,13 +313,30 @@ export const AiReviewTemplatesPage: FC = () => {
}, [deleteModal.template, filter, loadTemplates])

const handleToggleClick = useCallback((template: AiReviewTemplate) => {
// When trying to activate a disabled template, check for disabled workflows
if (template.disabled) {
const disabledWorkflows = (template.workflows || [])
.filter(item => item.workflow.disabled)
.map(item => item.workflow.name)

if (disabledWorkflows.length > 0) {
setDisabledWorkflowsModal({ open: true, workflowNames: disabledWorkflows })

return
}
}

setToggleModal({ open: true, template })
}, [])

const handleCloseToggleModal = useCallback(() => {
setToggleModal({ open: false })
}, [])

const handleCloseDisabledWorkflowsModal = useCallback(() => {
setDisabledWorkflowsModal({ open: false, workflowNames: [] })
}, [])

const handleConfirmToggle = useCallback(async () => {
if (!toggleModal.template) return
setIsToggling(true)
Expand Down Expand Up @@ -465,6 +486,32 @@ export const AiReviewTemplatesPage: FC = () => {
?
</p>
</ConfirmModal>

<BaseModal
title='Cannot Activate Template'
open={disabledWorkflowsModal.open}
onClose={handleCloseDisabledWorkflowsModal}
buttons={(
<Button
primary
size='lg'
label='OK'
onClick={handleCloseDisabledWorkflowsModal}
/>
)}
>
<p>
This template cannot be activated because the following workflow(s) are disabled:
</p>
<ul>
{disabledWorkflowsModal.workflowNames.map(name => (
<li key={name}><strong>{name}</strong></li>
))}
</ul>
<p>
Please enable these workflows first before activating this template.
</p>
</BaseModal>
</PageWrapper>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import { EnvironmentConfig } from '~/config'
import { UserSkill, xhrGetAsync } from '~/libs/core'

export type CompletedProfile = {
countryCode?: string
countryName?: string
city?: string
firstName?: string
handle: string
lastName?: string
photoURL?: string
skillCount?: number
userId?: number | string
isOpenToWork?: boolean | null
openToWork?: {
availability?: string
preferredRoles?: string[]
} | null
}

export type CompletedProfilesResponse = {
data: CompletedProfile[]
page: number
perPage: number
total: number
totalPages: number
}

export const DEFAULT_PAGE_SIZE = 50

function normalizeToList(raw: any): any[] {
if (Array.isArray(raw)) {
return raw
}

if (Array.isArray(raw?.data)) {
return raw.data
}

if (Array.isArray(raw?.result?.content)) {
return raw.result.content
}

if (Array.isArray(raw?.result)) {
return raw.result
}

return []
}

function normalizeCompletedProfilesResponse(
raw: any,
fallbackPage: number,
fallbackPerPage: number,
): CompletedProfilesResponse {
if (raw && Array.isArray(raw.data)) {
const total: number = Number(raw.total ?? raw.data.length)
const perPage: number = Number(raw.perPage ?? fallbackPerPage)
const page: number = Number(raw.page ?? fallbackPage)
const safePerPage = Number.isFinite(perPage) ? Math.max(perPage, 1) : fallbackPerPage
const safeTotal = Number.isFinite(total) ? Math.max(total, 0) : raw.data.length

return {
data: raw.data,
page: Number.isFinite(page) ? Math.max(page, 1) : fallbackPage,
perPage: safePerPage,
total: safeTotal,
totalPages: Number.isFinite(raw.totalPages)
? Math.max(Number(raw.totalPages), 1)
: Math.max(Math.ceil(safeTotal / safePerPage), 1),
}
}

const rows = normalizeToList(raw)
const total = Number(raw?.total ?? rows.length)
const safeTotal = Number.isFinite(total) ? Math.max(total, 0) : rows.length

return {
data: rows,
page: fallbackPage,
perPage: fallbackPerPage,
total: safeTotal,
totalPages: Math.max(Math.ceil(safeTotal / fallbackPerPage), 1),
}
}

export type OpenToWorkFilter = 'all' | 'yes' | 'no'

export async function fetchCompletedProfiles(
countryCode: string | undefined,
page: number,
perPage: number,
openToWorkFilter?: OpenToWorkFilter,
skillIds?: string[],
): Promise<CompletedProfilesResponse> {
const queryParams = new URLSearchParams({
page: String(page),
perPage: String(perPage),
})

if (countryCode) {
queryParams.set('countryCode', countryCode)
}

if (openToWorkFilter === 'yes') {
queryParams.set('openToWork', 'true')
}

if (openToWorkFilter === 'no') {
queryParams.set('openToWork', 'false')
}

if (Array.isArray(skillIds) && skillIds.length > 0) {
skillIds.forEach(id => {
if (id) {
queryParams.append('skillId', String(id))
}
})
}

const response = await xhrGetAsync<any>(
`${EnvironmentConfig.REPORTS_API}/topcoder/completed-profiles?${queryParams.toString()}`,
)

return normalizeCompletedProfilesResponse(response, page, perPage)
}

export async function fetchMemberSkillsData(userId: string | number | undefined): Promise<UserSkill[]> {
if (!userId) {
return []
}

const baseUrl = `${EnvironmentConfig.API.V5}/standardized-skills`
const url = `${baseUrl}/user-skills/${userId}?disablePagination=true`

try {
return await xhrGetAsync<UserSkill[]>(url)
} catch {
// If skills API fails, return empty array to not block the page
return []
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export type MemberSearchPayload = {
limit: number
openToWork?: boolean
page: number
preferredRoles?: string[]
profileComplete?: boolean
recentlyActive?: boolean
sortBy?: 'handle' | 'matchIndex'
Expand Down
Loading
Loading