diff --git a/src/apps/review/src/lib/components/TableScorecards/TableScorecards.tsx b/src/apps/review/src/lib/components/TableScorecards/TableScorecards.tsx index 1cc770e81..6399efdc0 100644 --- a/src/apps/review/src/lib/components/TableScorecards/TableScorecards.tsx +++ b/src/apps/review/src/lib/components/TableScorecards/TableScorecards.tsx @@ -3,7 +3,7 @@ */ import { Dispatch, FC, SetStateAction, useMemo } from 'react' import { Link } from 'react-router-dom' -import { noop } from 'lodash' +import { bind, noop } from 'lodash' import classNames from 'classnames' import { MobileTableColumn } from '~/apps/admin/src/lib/models/MobileTableColumn.model' @@ -26,6 +26,7 @@ interface Props { totalPages: number page: number setPage: Dispatch> + onClone: (scorecard: Scorecard) => unknown } export const TableScorecards: FC = (props: Props) => { @@ -87,13 +88,13 @@ export const TableScorecards: FC = (props: Props) => { { className: classNames(styles.tableCell, styles.tableCellCenter), label: 'Action', - renderer: () => ( + renderer: (data: Scorecard) => (
Edit
-
+
Clone
diff --git a/src/apps/review/src/lib/services/scorecards.service.ts b/src/apps/review/src/lib/services/scorecards.service.ts index abe4b6770..f04745be2 100644 --- a/src/apps/review/src/lib/services/scorecards.service.ts +++ b/src/apps/review/src/lib/services/scorecards.service.ts @@ -1,8 +1,13 @@ /** * Scorecards service */ +import { xhrPostAsync } from '~/libs/core' +import { EnvironmentConfig } from '~/config' + import { MockScorecard } from '../../mock-datas' -import { adjustScorecardInfo, ScorecardInfo } from '../models' +import { adjustScorecardInfo, Scorecard, ScorecardInfo } from '../models' + +const baseUrl = `${EnvironmentConfig.API.V6}/review/scorecards` /** * Fetch scorecard @@ -10,3 +15,12 @@ import { adjustScorecardInfo, ScorecardInfo } from '../models' */ export const fetchScorecards = async (): Promise => Promise.resolve(adjustScorecardInfo(MockScorecard) as ScorecardInfo) + +/** + * Clone scorecard + * @param scorecard Scorecard to clone + * @returns resolves to the cloned scorecard info + */ +export const cloneScorecard = async (scorecard: Pick): Promise => ( + xhrPostAsync(`${baseUrl}/${scorecard.id}/clone`, {}) +) diff --git a/src/apps/review/src/pages/scorecards/ScorecardsListPage/ScorecardsListPage.tsx b/src/apps/review/src/pages/scorecards/ScorecardsListPage/ScorecardsListPage.tsx index eddd2fe52..e8144d6d0 100644 --- a/src/apps/review/src/pages/scorecards/ScorecardsListPage/ScorecardsListPage.tsx +++ b/src/apps/review/src/pages/scorecards/ScorecardsListPage/ScorecardsListPage.tsx @@ -1,14 +1,21 @@ +import { useNavigate } from 'react-router-dom' import { FC, useCallback, useMemo, useState } from 'react' +import { toast } from 'react-toastify' -import { PageTitle } from '~/libs/ui' +import { PageTitle, useConfirmationModal } from '~/libs/ui' import { TableLoading } from '~/apps/admin/src/lib' +import { Scorecard } from '../../../lib/models' +import { cloneScorecard } from '../../../lib/services' import { PageWrapper, ScorecardsFilter, TableNoRecord, TableScorecards } from '../../../lib' import { ScorecardsResponse, useFetchScorecards } from '../../../lib/hooks' import styles from './ScorecardsListPage.module.scss' export const ScorecardsListPage: FC<{}> = () => { + const navigate = useNavigate() + const confirmation = useConfirmationModal() + const [filters, setFilters] = useState({ category: '', name: '', @@ -43,6 +50,30 @@ export const ScorecardsListPage: FC<{}> = () => { setPage(1) }, []) + const handleScorecardClone = useCallback(async (scorecard: Scorecard) => { + if (!await confirmation.confirm({ + action: 'Clone', + content: `Are you sure you want to clone "${scorecard.name}" scorecard?`, + title: 'Clone Scorecard', + })) { + return + } + + try { + const cloned = await cloneScorecard({ id: scorecard.id }) + if (!cloned || !cloned.id) { + toast.error('Failed to clone scorecard!') + return + } + + toast.success('Scorecard cloned successfully!') + navigate(`${cloned.id}/details`) + } catch (error) { + toast.error('Failed to clone scorecard!') + console.error('Failed to clone scorecard:', error) + } + }, [navigate, confirmation]) + return ( = () => { ) : ( = () => { )} - + {confirmation.modal} )