Public Access
64 lines
2.5 KiB
React
64 lines
2.5 KiB
React
import {useEffect, useState} from 'react';
|
|
import {useTranslation} from 'react-i18next';
|
|
import {Info} from 'lucide-react';
|
|
|
|
import {Card, CardContent, CardHeader, CardTitle} from '@/components/ui/card';
|
|
import {commitUrl, fetchVersion, formatBuildTime, FRONTEND_VERSION, VERSION_SOURCES} from '../utils/version.js';
|
|
|
|
const SHORT_HASH = 7;
|
|
|
|
function VersionValue({repo, version}) {
|
|
const {t, i18n} = useTranslation();
|
|
if (version === undefined) return <span className="text-muted-foreground">…</span>;
|
|
if (version === null) return <span className="text-muted-foreground">{t('SETTINGS.VERSION_UNKNOWN')}</span>;
|
|
|
|
const url = commitUrl(repo, version.commit);
|
|
const builtAt = formatBuildTime(version.builtAt, i18n.language);
|
|
return (
|
|
<span className="flex min-w-0 items-center gap-2">
|
|
{url
|
|
? <a href={url} target="_blank" rel="noopener noreferrer"
|
|
className="font-mono text-primary hover:underline">{version.commit.slice(0, SHORT_HASH)}</a>
|
|
: <span className="font-mono">{version.commit}</span>}
|
|
{builtAt && <span className="truncate text-muted-foreground">· {builtAt}</span>}
|
|
</span>
|
|
);
|
|
}
|
|
|
|
/**
|
|
* A backend version is undefined while loading and null when it is unknown.
|
|
*/
|
|
export default function BuildVersionCard() {
|
|
const {t} = useTranslation();
|
|
const [versions, setVersions] = useState({Frontend: FRONTEND_VERSION});
|
|
|
|
useEffect(() => {
|
|
let cancelled = false;
|
|
VERSION_SOURCES.filter((source) => source.url).forEach(async (source) => {
|
|
const version = await fetchVersion(source.url());
|
|
if (!cancelled) setVersions((current) => ({...current, [source.name]: version}));
|
|
});
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}, []);
|
|
|
|
return (
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle className="flex items-center gap-2"><Info className="size-4 text-primary"/>{t('SETTINGS.VERSION')}</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<ul className="space-y-2 text-sm">
|
|
{VERSION_SOURCES.map(({name, repo}) => (
|
|
<li key={name} className="flex items-center justify-between gap-4">
|
|
<span>{name}</span>
|
|
<VersionValue repo={repo} version={versions[name]}/>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
}
|