feat(admin): show when system status last refreshed
This commit is contained in:
@@ -371,6 +371,7 @@ describe('AdminSystemPage', () => {
|
||||
mockedApi.get.mockRejectedValue({ response: { status: 403 } });
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Refresh' }));
|
||||
await waitFor(() => expect(screen.queryByText('Production')).not.toBeInTheDocument());
|
||||
expect(screen.queryByText('Last successful status refresh:')).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole('button', { name: 'Retry' })).not.toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: 'Run probe now' })).toBeDisabled();
|
||||
fireEvent.click(screen.getByRole('tab', { name: 'Settings' }));
|
||||
@@ -381,11 +382,20 @@ describe('AdminSystemPage', () => {
|
||||
it('keeps the last diagnostic values under a qualified refresh error', async () => {
|
||||
render(<I18nProvider><AdminSystemPage /></I18nProvider>);
|
||||
await screen.findByText('Production');
|
||||
const readTime = screen.getByText('Last successful status refresh:').parentElement?.querySelector('time');
|
||||
const original = readTime?.dateTime;
|
||||
expect(original).toMatch(/^\d{4}-\d{2}-\d{2}T.*Z$/);
|
||||
const get = mockedApi.get.getMockImplementation()!;
|
||||
mockedApi.get.mockImplementation((url: string, config?: any) => url === '/admin/system' ? Promise.reject({ response: { status: 503, data: 'Temporary failure' } }) : get(url, config));
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Refresh' }));
|
||||
expect(await screen.findByText('System status could not be refreshed. Previously loaded values remain.')).toBeVisible();
|
||||
expect(screen.getByText('Production')).toBeVisible();
|
||||
expect(readTime).toBeInTheDocument();
|
||||
expect(readTime?.dateTime).toBe(original);
|
||||
mockedApi.get.mockImplementation(get);
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Retry' }));
|
||||
await waitFor(() => expect(readTime?.dateTime).not.toBe(original));
|
||||
expect(screen.queryByRole('button', { name: 'Retry' })).not.toBeInTheDocument();
|
||||
expect(mockedApi.post).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
||||
@@ -2285,6 +2285,7 @@ export const translations = {
|
||||
adminSystemTestEmailSent: "Test email sent.",
|
||||
adminSystemProbeCompleted: "AI probe completed.",
|
||||
adminSystemRefreshFailed: "System status could not be refreshed. Previously loaded values remain.",
|
||||
adminSystemStatusReceivedAt: "Last successful status refresh",
|
||||
adminSystemTestEmailFailed: "Failed to send test email.",
|
||||
adminSystemDefaultTestMessage: "This is a test email from the Jobbjakt system panel.",
|
||||
adminSystemEmailSaveFailed: "Failed to save email settings.",
|
||||
@@ -5510,6 +5511,7 @@ export const translations = {
|
||||
adminSystemTestEmailSent: "Test-e-posten er sendt.",
|
||||
adminSystemProbeCompleted: "KI-kontrollen er fullført.",
|
||||
adminSystemRefreshFailed: "Kunne ikke oppdatere systemstatus. Tidligere innlastede verdier beholdes.",
|
||||
adminSystemStatusReceivedAt: "Siste vellykkede statusoppdatering",
|
||||
adminSystemTestEmailFailed: "Kunne ikke sende test-e-post.",
|
||||
adminSystemDefaultTestMessage: "Dette er en test-e-post fra systempanelet i Jobbjakt.",
|
||||
adminSystemEmailSaveFailed: "Kunne ikke lagre e-postinnstillingene.",
|
||||
|
||||
@@ -225,7 +225,8 @@ const actionErrorKeys: Record<ActionKind, TranslationKey> = { save: "adminSystem
|
||||
export default function AdminSystemPage() {
|
||||
const { language, t } = useI18n();
|
||||
const [tab, setTab] = useState(0);
|
||||
const [status, setStatus] = useState<SystemStatus | null>(null);
|
||||
const [statusSnapshot, setStatusSnapshot] = useState<{ data: SystemStatus; receivedAt: string } | null>(null);
|
||||
const status = statusSnapshot?.data;
|
||||
const [emailSettings, setEmailSettings] = useState<EditableEmailSettings | null>(null);
|
||||
const [benchmarkStatus, setBenchmarkStatus] = useState<CvBenchmarkStatus | null>(null);
|
||||
const [maintenanceJobs, setMaintenanceJobs] = useState<MaintenanceJob[]>([]);
|
||||
@@ -268,7 +269,7 @@ export default function AdminSystemPage() {
|
||||
try {
|
||||
const response = await api.get(readPaths[part], { signal: abort.signal });
|
||||
if (!active() || abort.signal.aborted || denied.current) return;
|
||||
if (part === "status") setStatus(response.data);
|
||||
if (part === "status") setStatusSnapshot({ data: response.data, receivedAt: new Date().toISOString() });
|
||||
if (part === "email" && revision === draftRevision.current && revision === savedRevision.current) setEmailSettings(response.data);
|
||||
if (part === "benchmark") setBenchmarkStatus(response.data ?? null);
|
||||
if (part === "maintenance") setMaintenanceJobs(response.data ?? []);
|
||||
@@ -278,7 +279,7 @@ export default function AdminSystemPage() {
|
||||
const responseStatus = (cause as { response?: { status?: number } })?.response?.status;
|
||||
if (responseStatus === 401 || responseStatus === 403) {
|
||||
denied.current = true; setAccessDenied(true);
|
||||
setStatus(null); setEmailSettings(null); setBenchmarkStatus(null); setMaintenanceJobs([]);
|
||||
setStatusSnapshot(null); setEmailSettings(null); setBenchmarkStatus(null); setMaintenanceJobs([]);
|
||||
setSmtpPassword(""); setClearPassword(false);
|
||||
}
|
||||
setReadErrors(errors => ({ ...errors, [part]: cause }));
|
||||
@@ -450,6 +451,7 @@ export default function AdminSystemPage() {
|
||||
<Box role="tabpanel" id={`${navigationId}-panel-0`} aria-labelledby={`${navigationId}-tab-0`} hidden={tab !== 0} sx={{ minWidth: 0 }}>
|
||||
<Stack spacing={1}>{readNotice("benchmark")}{readNotice("maintenance")}</Stack>
|
||||
{status ? <Stack spacing={2}>
|
||||
<DetailRow label={t("adminSystemStatusReceivedAt")} value={<time dateTime={statusSnapshot.receivedAt}>{formatDate(statusSnapshot.receivedAt, language === "nb" ? "nb-NO" : "en")}</time>} />
|
||||
<Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", md: "repeat(4, 1fr)" }, gap: 2 }}>
|
||||
<SummaryCard
|
||||
title={t("adminSystemEnvironment")}
|
||||
|
||||
Reference in New Issue
Block a user