From 3f6187feafeb165b66b146b5ec9b44af4199667b Mon Sep 17 00:00:00 2001 From: Harshit Chudasama Date: Mon, 20 Apr 2026 12:32:10 +0530 Subject: [PATCH 01/12] updated --- .../TalentSearchPage/TalentSearchPage.tsx | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/apps/customer-portal/src/pages/talent-search/TalentSearchPage/TalentSearchPage.tsx b/src/apps/customer-portal/src/pages/talent-search/TalentSearchPage/TalentSearchPage.tsx index c74c70939..cc4ff17fe 100644 --- a/src/apps/customer-portal/src/pages/talent-search/TalentSearchPage/TalentSearchPage.tsx +++ b/src/apps/customer-portal/src/pages/talent-search/TalentSearchPage/TalentSearchPage.tsx @@ -30,8 +30,7 @@ import styles from './TalentSearchPage.module.scss' export const TalentSearchPage: FC = () => { const skipNextAutoSearchRef = useRef(false) - const lastSearchedDescriptionRef = useRef('') - + const [lastSearchedDescription, setLastSearchedDescription] = useState('') const countryLookup: CountryLookup[] | undefined = useCountryLookup() const [jobDescription, setJobDescription] = useState('') const [isExtractingSkills, setIsExtractingSkills] = useState(false) @@ -135,6 +134,7 @@ export const TalentSearchPage: FC = () => { setIsLoadingMore(true) } else { setIsSearchingMembers(true) + setIsLoading(true) } setErrorMessage('') @@ -166,6 +166,7 @@ export const TalentSearchPage: FC = () => { setResults([]) setTotalResults(0) setCurrentPage(1) + setLastSearchedDescription('') } setErrorMessage('Failed to search matching members. Please try again.') @@ -174,6 +175,7 @@ export const TalentSearchPage: FC = () => { setIsLoadingMore(false) } else { setIsSearchingMembers(false) + setIsLoading(false) } } }, [onlyActive, onlyOpenToWork]) @@ -188,6 +190,7 @@ export const TalentSearchPage: FC = () => { setTotalResults(0) setCurrentPage(1) setErrorMessage('') + setLastSearchedDescription('') }, []) const handleAiSearch = useCallback(async (): Promise => { @@ -196,11 +199,8 @@ export const TalentSearchPage: FC = () => { return } - lastSearchedDescriptionRef.current = normalizedDescription // <-- add this - setErrorMessage('') setIsExtractingSkills(true) - setIsLoading(true) // <-- add this try { const extractedSkillsResult = await extractSkillsFromText(normalizedDescription) @@ -239,6 +239,7 @@ export const TalentSearchPage: FC = () => { setHasSearched(true) skipNextAutoSearchRef.current = true await runMemberSearch(extractedOptions, { page: 1 }) + setLastSearchedDescription(normalizedDescription) } catch { // Prevent stale auto-search when extraction fails and loading flips to false. skipNextAutoSearchRef.current = true @@ -246,7 +247,6 @@ export const TalentSearchPage: FC = () => { setHasSearched(true) } finally { setIsExtractingSkills(false) - setIsLoading(false) // <-- add this } }, [isExtractingSkills, jobDescription, runMemberSearch]) @@ -284,8 +284,8 @@ export const TalentSearchPage: FC = () => { const isSearchButtonDisabled = useMemo( () => isExtractingSkills || !jobDescription.trim() - || jobDescription.trim() === lastSearchedDescriptionRef.current, - [isExtractingSkills, jobDescription], + || jobDescription.trim() === lastSearchedDescription, + [isExtractingSkills, jobDescription, lastSearchedDescription], ) return ( { onClick={() => { setJobDescription('') setErrorMessage('') + setLastSearchedDescription('') }} > Clear From 213978287b7c2190137fbe75a0327163233ac529 Mon Sep 17 00:00:00 2001 From: Harshit Chudasama Date: Mon, 20 Apr 2026 12:59:14 +0530 Subject: [PATCH 02/12] updated --- .../TalentSearchPage/TalentSearchPage.tsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/apps/customer-portal/src/pages/talent-search/TalentSearchPage/TalentSearchPage.tsx b/src/apps/customer-portal/src/pages/talent-search/TalentSearchPage/TalentSearchPage.tsx index cc4ff17fe..2b710831c 100644 --- a/src/apps/customer-portal/src/pages/talent-search/TalentSearchPage/TalentSearchPage.tsx +++ b/src/apps/customer-portal/src/pages/talent-search/TalentSearchPage/TalentSearchPage.tsx @@ -107,7 +107,7 @@ export const TalentSearchPage: FC = () => { page?: number recentlyActive?: boolean }, - ): Promise => { + ): Promise => { const append = overrides?.append === true const openToWork = overrides?.openToWork ?? onlyOpenToWork const page = overrides?.page ?? 1 @@ -161,6 +161,7 @@ export const TalentSearchPage: FC = () => { }) setTotalResults(Number(response?.total || 0)) setCurrentPage(Number(response?.page || page)) + return true } catch { if (!append) { setResults([]) @@ -170,6 +171,7 @@ export const TalentSearchPage: FC = () => { } setErrorMessage('Failed to search matching members. Please try again.') + return false } finally { if (append) { setIsLoadingMore(false) @@ -238,8 +240,10 @@ export const TalentSearchPage: FC = () => { setHasSearched(true) skipNextAutoSearchRef.current = true - await runMemberSearch(extractedOptions, { page: 1 }) - setLastSearchedDescription(normalizedDescription) + const searchSucceeded = await runMemberSearch(extractedOptions, { page: 1 }) + if (searchSucceeded) { + setLastSearchedDescription(normalizedDescription) + } } catch { // Prevent stale auto-search when extraction fails and loading flips to false. skipNextAutoSearchRef.current = true @@ -356,6 +360,9 @@ export const TalentSearchPage: FC = () => { const value = (event.target.value || []) as InputMultiselectOption[] setSelectedSkills(value) setHasSearched(value.length > 0) + if (value.length === 0) { + setLastSearchedDescription('') + } }} /> From d941684dcc852122194827a8fe4a1b454af7c8eb Mon Sep 17 00:00:00 2001 From: himaniraghav3 Date: Tue, 5 May 2026 12:58:09 +0530 Subject: [PATCH 03/12] Add pagination to BA view --- .../src/pages/reports/ReportsPage.module.scss | 38 ++++++++ .../reports/src/pages/reports/ReportsPage.tsx | 93 ++++++++++++++----- 2 files changed, 108 insertions(+), 23 deletions(-) diff --git a/src/apps/reports/src/pages/reports/ReportsPage.module.scss b/src/apps/reports/src/pages/reports/ReportsPage.module.scss index e282cf8d2..ee92d61d1 100644 --- a/src/apps/reports/src/pages/reports/ReportsPage.module.scss +++ b/src/apps/reports/src/pages/reports/ReportsPage.module.scss @@ -217,6 +217,12 @@ margin-top: 24px; } +.paymentsResults { + display: flex; + flex-direction: column; + gap: 12px; +} + .paymentsSectionTitle { font-weight: 600; margin-bottom: 8px; @@ -228,6 +234,38 @@ border-radius: 6px; } +.paymentsPagination { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + flex-wrap: wrap; +} + +.perPageControl { + display: flex; + align-items: center; + gap: 8px; +} + +.perPageControl label { + color: #565a5f; + font-size: 13px; +} + +.perPageControl select { + min-width: 72px; + padding: 5px 8px; + border: 1px solid #d7d9dd; + border-radius: 6px; + background: #fff; +} + +.paginationMeta { + color: #565a5f; + font-size: 13px; +} + .paymentsTable { width: 100%; border-collapse: collapse; diff --git a/src/apps/reports/src/pages/reports/ReportsPage.tsx b/src/apps/reports/src/pages/reports/ReportsPage.tsx index 861372464..06cebb99c 100644 --- a/src/apps/reports/src/pages/reports/ReportsPage.tsx +++ b/src/apps/reports/src/pages/reports/ReportsPage.tsx @@ -11,6 +11,7 @@ import { PageTitle, Tooltip, } from '~/libs/ui' +import { Pagination } from '~/apps/admin/src/lib' import { bulkMemberLookupRouteId } from '../../config/routes.config' import { handleError } from '../../lib/utils' @@ -127,12 +128,30 @@ const PAYMENT_TABLE_COLUMNS: { key: keyof SfdcBillingAccountPaymentRow; label: s { key: 'winnerFirstName', label: 'Winner first name' }, { key: 'winnerLastName', label: 'Winner last name' }, ] +const PAYMENT_ROWS_PER_PAGE_OPTIONS = [10, 25, 50] const BillingAccountReportResults = ( props: { data: BillingAccountsViewData }, ): JSX.Element => { const billingAccount: BillingAccountsViewData['billingAccount'] = props.data.billingAccount const payments: BillingAccountsViewData['payments'] = props.data.payments + const [currentPage, setCurrentPage] = useState(1) + const [rowsPerPage, setRowsPerPage] = useState(PAYMENT_ROWS_PER_PAGE_OPTIONS[0]) + const total = payments.length + const totalPages = Math.max(1, Math.ceil(total / rowsPerPage)) + const currentSliceStart = (currentPage - 1) * rowsPerPage + const paginatedPayments = payments.slice(currentSliceStart, currentSliceStart + rowsPerPage) + const showingStart = total === 0 ? 0 : ((currentPage - 1) * rowsPerPage) + 1 + const showingEnd = Math.min(currentPage * rowsPerPage, total) + + useEffect(() => { + setCurrentPage(1) + }, [payments]) + + function handleRowsPerPageChange(event: ChangeEvent): void { + setRowsPerPage(Number(event.target.value)) + setCurrentPage(1) + } return (
@@ -199,32 +218,56 @@ const BillingAccountReportResults = (
Payments
- {payments.length === 0 ? ( + {total === 0 ? (
No payments matched the selected filters.
) : ( -
- - - - {PAYMENT_TABLE_COLUMNS.map(col => ( - - ))} - - - - {payments.map(row => ( - +
+
+
{col.label}
+ + {PAYMENT_TABLE_COLUMNS.map(col => ( - + ))} - ))} - -
- {col.key === 'paymentDate' - ? formatPaymentDate(String(row[col.key])) - : formatReportCell(row[col.key])} - {col.label}
+ + + {paginatedPayments.map(row => ( + + {PAYMENT_TABLE_COLUMNS.map(col => ( + + {col.key === 'paymentDate' + ? formatPaymentDate(String(row[col.key])) + : formatReportCell(row[col.key])} + + ))} + + ))} + + +
+
+
+ + +
+
+ {`Showing ${showingStart}-${showingEnd} of ${total} payments`} +
+ +
)}
@@ -425,7 +468,6 @@ const ReportsPageContent: FC = props => { BillingAccountsViewData | undefined >(undefined) const [isBillingAccountViewLoading, setIsBillingAccountViewLoading] = useState(false) - useEffect(() => { let isMounted = true setIsLoading(true) @@ -648,6 +690,11 @@ const ReportsPageContent: FC = props => { setBillingAccountViewData(undefined) }, []) + const handleBillingAccountViewClick = useCallback(() => { + handleBillingAccountView() + .catch(handleError) + }, [handleBillingAccountView]) + const isDownloading = downloadingFormat !== undefined const isBusy = isDownloading || isBillingAccountViewLoading @@ -692,7 +739,7 @@ const ReportsPageContent: FC = props => { From 0da1e39edce3d93c8adf3a586e5676b8e8d48e41 Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Tue, 5 May 2026 10:29:34 +0300 Subject: [PATCH 04/12] PM-4684 - save all data on budget approval --- .../components/ChallengeEditorForm.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/apps/work/src/pages/challenges/ChallengeEditorPage/components/ChallengeEditorForm.tsx b/src/apps/work/src/pages/challenges/ChallengeEditorPage/components/ChallengeEditorForm.tsx index 2d6b0d9b6..416f017c4 100644 --- a/src/apps/work/src/pages/challenges/ChallengeEditorPage/components/ChallengeEditorForm.tsx +++ b/src/apps/work/src/pages/challenges/ChallengeEditorPage/components/ChallengeEditorForm.tsx @@ -2973,9 +2973,14 @@ export const ChallengeEditorForm: FC = ( approvalStatus: nextApprovalStatus, } const savedChallenge = await patchChallenge(currentChallengeId, payload) + const savedChallengeFormData = transformChallengeToFormData(savedChallenge) + const currentFormData = getValues() const mergedFormData = { - ...getValues(), - ...transformChallengeToFormData(savedChallenge), + ...savedChallengeFormData, + ...currentFormData, + approvalApprovedBy: savedChallengeFormData.approvalApprovedBy, + approvalRejectionReason: savedChallengeFormData.approvalRejectionReason, + approvalStatus: savedChallengeFormData.approvalStatus, } reset(mergedFormData) From b58fd2e7b10a0123b3a1eda045538b1a11f1554e Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Tue, 5 May 2026 12:00:03 +0300 Subject: [PATCH 05/12] PM-4684 - improve UX for approve budget --- .../ConfirmationModal/ConfirmationModal.tsx | 3 + .../ChallengeEditorForm.module.scss | 2 + .../components/ChallengeEditorForm.tsx | 115 +++++++++++++----- 3 files changed, 90 insertions(+), 30 deletions(-) diff --git a/src/apps/work/src/lib/components/ConfirmationModal/ConfirmationModal.tsx b/src/apps/work/src/lib/components/ConfirmationModal/ConfirmationModal.tsx index 5a98df2d9..47242d4d5 100644 --- a/src/apps/work/src/lib/components/ConfirmationModal/ConfirmationModal.tsx +++ b/src/apps/work/src/lib/components/ConfirmationModal/ConfirmationModal.tsx @@ -1,6 +1,7 @@ import { FC, MouseEvent, + ReactNode, useCallback, } from 'react' @@ -10,6 +11,7 @@ import styles from './ConfirmationModal.module.scss' export interface ConfirmationModalProps { cancelText?: string + children?: ReactNode confirmButtonDanger?: boolean confirmDisabled?: boolean confirmText?: string @@ -48,6 +50,7 @@ export const ConfirmationModal: FC = (

{props.message}

+ {props.children}