0.1.38 gateway
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
import { useState } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { api } from '../api/client';
|
||||
import { useAction } from '../lib/hooks';
|
||||
import { useGateway } from '../lib/gateway';
|
||||
import { useToast } from '../lib/toast';
|
||||
import { num, when } from '../lib/format';
|
||||
import { Banner, Button, Card, Confirm, Loading, PageHead, Tiles } from '../components/ui';
|
||||
|
||||
export function RecommendationsPage() {
|
||||
const { status, error, loading, reload } = useGateway();
|
||||
const { wrap } = useToast();
|
||||
const { busy, run } = useAction();
|
||||
const [confirming, setConfirming] = useState(false);
|
||||
|
||||
const forYou = status?.forYou;
|
||||
const running = Boolean(status?.forYouRunning);
|
||||
|
||||
const act = (action: string, key: string, message: string) =>
|
||||
run(key, async () => {
|
||||
await wrap(() => api.post('/admin/api/for-you', { action }), message);
|
||||
setConfirming(false);
|
||||
await reload();
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHead title="For You" intro="The prepared pools personalised rows are drawn from." />
|
||||
<Banner message={error} />
|
||||
|
||||
{loading ? (
|
||||
<Loading rows={2} />
|
||||
) : (
|
||||
<>
|
||||
<Tiles
|
||||
tiles={[
|
||||
{ label: 'Tracearr sessions', value: num(forYou?.tracearrSessions ?? 0), icon: 'play', tone: 'info' },
|
||||
{ label: 'user profiles', value: num(forYou?.profiles ?? 0), icon: 'people', tone: 'note' },
|
||||
{ label: 'ranked candidates', value: num(forYou?.candidates ?? 0), icon: 'sparkle', tone: 'note' },
|
||||
{ label: 'last full import', value: when(forYou?.lastFullImport), small: true, icon: 'clock' },
|
||||
]}
|
||||
/>
|
||||
|
||||
<Card
|
||||
title="Pool maintenance"
|
||||
intro="Prepared pools refresh in the background; these are the manual versions of the same work. A rebuild is safe at any time — televisions read the last finished pool until a new one lands."
|
||||
icon="sparkle"
|
||||
tone="note"
|
||||
footer={
|
||||
<span className="hint">
|
||||
{running ? 'For You maintenance running…' : 'Prepared pools normally refresh in the background.'}
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<div className="row">
|
||||
<Button
|
||||
variant="primary"
|
||||
icon="download"
|
||||
disabled={running}
|
||||
busy={busy === 'import'}
|
||||
onClick={() => void act('incremental-import', 'import', 'Import started.')}
|
||||
>
|
||||
Import recent sessions
|
||||
</Button>
|
||||
<Button icon="database" disabled={running} onClick={() => setConfirming(true)}>
|
||||
Full Tracearr backfill
|
||||
</Button>
|
||||
<Button
|
||||
icon="sync"
|
||||
disabled={running}
|
||||
busy={busy === 'rebuild'}
|
||||
onClick={() => void act('rebuild-all', 'rebuild', 'Rebuild started.')}
|
||||
>
|
||||
Rebuild all pools
|
||||
</Button>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card
|
||||
title="Reading a person's scores"
|
||||
intro="The inspector re-runs the shared weighted scorer over one person's prepared pool, after Emby permission and parental-control filtering, and shows every component and evidence reason behind the order."
|
||||
icon="search"
|
||||
tone="info"
|
||||
actions={<Link to="/admin/inspector">Open the inspector</Link>}
|
||||
>
|
||||
<></>
|
||||
</Card>
|
||||
</>
|
||||
)}
|
||||
|
||||
{confirming ? (
|
||||
<Confirm
|
||||
title="Backfill all Tracearr history?"
|
||||
body="Every session is re-read and every active user's pool is rebuilt. It is safe at any time — televisions keep reading the last finished pool — but on a long history it takes a while."
|
||||
confirmLabel="Backfill"
|
||||
busy={busy === 'full'}
|
||||
onConfirm={() => void act('full-import', 'full', 'Backfill started.')}
|
||||
onCancel={() => setConfirming(false)}
|
||||
/>
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user