Public Access
feat(library): add the merge duplicate dialog
This commit is contained in:
1 parent
01ae372b2d
commit
78ba0700c8
10 files changed
+355
-84
No files matched your search
@@ -1,7 +1,7 @@
|
||||
import {useEffect, useMemo, useState} from 'react';
|
||||
import {Link, useNavigate, useParams} from 'react-router-dom';
|
||||
import {useTranslation} from 'react-i18next';
|
||||
import {ArrowLeft, Clock, ExternalLink, Eye, EyeOff, Gamepad2, Image as ImageIcon, ImageOff, PanelTop, PencilLine, RotateCcw, ShieldOff, Timer, Trophy} from 'lucide-react';
|
||||
import {ArrowLeft, Clock, ExternalLink, Eye, EyeOff, Gamepad2, Image as ImageIcon, ImageOff, Merge, PanelTop, PencilLine, RotateCcw, ShieldOff, Timer, Trophy} from 'lucide-react';
|
||||
import {toast} from 'sonner';
|
||||
|
||||
import {Badge} from '@/components/ui/badge';
|
||||
@@ -16,6 +16,7 @@ import ManualGameCard from '../components/ManualGameCard.jsx';
|
||||
import CompletedHint from '../components/CompletedHint.jsx';
|
||||
import FinishedHint from '../components/FinishedHint.jsx';
|
||||
import GameCorrectionDialog from '../components/GameCorrectionDialog.jsx';
|
||||
import GameMergeDialog from '../components/GameMergeDialog.jsx';
|
||||
import PlayingHint from '../components/PlayingHint.jsx';
|
||||
import TimeToBeat from '../components/TimeToBeat.jsx';
|
||||
import {formatPlaytime} from '../utils/games.js';
|
||||
@@ -67,6 +68,7 @@ export default function GameDetail() {
|
||||
const [hiding, setHiding] = useState(false);
|
||||
const [error, setError] = useState(null);
|
||||
const [correcting, setCorrecting] = useState(false);
|
||||
const [merging, setMerging] = useState(false);
|
||||
const [reloads, setReloads] = useState(0);
|
||||
const auditor = canCorrect(useCurrentUser(true));
|
||||
|
||||
@@ -222,6 +224,11 @@ export default function GameDetail() {
|
||||
<PencilLine/>{t('CORRECTION.OPEN')}
|
||||
</Button>
|
||||
)}
|
||||
{auditor && (
|
||||
<Button variant="outline" size="sm" className="mt-3 ml-2" onClick={() => setMerging(true)}>
|
||||
<Merge/>{t('MERGE.OPEN')}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
{/* Store page, background and banner need Steam art, so a game off Steam has none of them.
|
||||
Hide is here too: only a Steam game can be hidden. */}
|
||||
@@ -355,6 +362,13 @@ export default function GameDetail() {
|
||||
<GameCorrectionDialog game={data} open={correcting} onOpenChange={setCorrecting}
|
||||
onChanged={() => setReloads((n) => n + 1)}/>
|
||||
)}
|
||||
{auditor && data && (
|
||||
<GameMergeDialog game={data} open={merging} onOpenChange={setMerging} onMerged={(merged) => {
|
||||
// A new key loads through the address; the same key needs a reload.
|
||||
if (merged === data.appid) setReloads((n) => n + 1);
|
||||
else navigate(`/library/${merged}`, {replace: true});
|
||||
}}/>
|
||||
)}
|
||||
</PageContainer>
|
||||
);
|
||||
}
|
||||
@@ -257,6 +257,15 @@ describe('GameDetail of a game added by hand', () => {
|
||||
expect(await screen.findByText('CORRECTION.TITLE')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('offers "merge duplicate" to an active auditor', async () => {
|
||||
loggedInAs({role: 'AUDITOR', activeRole: 'AUDITOR'});
|
||||
renderDetail();
|
||||
|
||||
fireEvent.click(await screen.findByRole('button', {name: 'MERGE.OPEN'}));
|
||||
|
||||
expect(await screen.findByText('MERGE.TITLE')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('offers nothing to a user or to an admin viewing as user', async () => {
|
||||
for (const me of [{role: 'USER', activeRole: 'USER'}, {role: 'PLATFORM_ADMIN', activeRole: 'USER'}]) {
|
||||
loggedInAs(me);
|
||||
@@ -267,6 +276,7 @@ describe('GameDetail of a game added by hand', () => {
|
||||
// Let the answer of /me reach the page before looking for the button.
|
||||
await act(async () => {});
|
||||
expect(screen.queryByRole('button', {name: 'CORRECTION.OPEN'})).toBeNull();
|
||||
expect(screen.queryByRole('button', {name: 'MERGE.OPEN'})).toBeNull();
|
||||
cleanup();
|
||||
}
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user