the picker's register link opens the form
reported as "I click register a server and nothing happens", and nothing was broken. three controls on that screen carry the label. two are buttons that open the form; the one in the server picker — top left, where you look first — was a plain <Link> to the servers section. /offscale and /offscale/servers render the same view (useOffscaleSection defaults to servers when there is no param), so from either one the click navigated to something identical. the URL moved and nothing else did, and the only visible result was a second button with the same label further down the page. so the link now carries ?register=1 and ServersView consumes it. the flag is stripped with replace on the way in, which is not tidiness: left in the URL, closing the form and clicking the picker again would be a navigation to the URL already showing, and nothing would happen — the same bug, restored. ServersView.test.tsx pins all three: the form opens on arrival, the flag is consumed, and no flag means no form. removing the effect fails the first two.
This commit is contained in:
+20
-1
@@ -1,7 +1,8 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { useSearchParams } from 'react-router';
|
||||
import { Plus, Loader2, Server, Check, Activity, Pencil, Trash2 } from 'lucide-react';
|
||||
import type { OffscaleServer, OffscaleHealth } from './shared';
|
||||
import { MIN_OFFSCALE_VERSION } from './shared';
|
||||
import { MIN_OFFSCALE_VERSION, OFFSCALE_REGISTER_PARAM } from './shared';
|
||||
import { useOffscaleServers, useOffscaleHealth, offscaleErrorMessage } from './useOffscaleServers';
|
||||
import { Card, SectionHeader, Button, Dot, Badge, ErrorNote } from './Cards';
|
||||
import { ServerForm } from './ServerForm';
|
||||
@@ -136,11 +137,29 @@ export const ServersView = () => {
|
||||
const healthProbe = useOffscaleHealth();
|
||||
|
||||
const [formFor, setFormFor] = useState<'new' | OffscaleServer | null>(null);
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const [health, setHealth] = useState<Record<number, OffscaleHealth>>({});
|
||||
// Several probes are in flight at once now, so this is a set of ids rather than the one id it used to be.
|
||||
const [testingIds, setTestingIds] = useState<readonly number[]>([]);
|
||||
const [actionError, setActionError] = useState<string | null>(null);
|
||||
|
||||
/*
|
||||
The URL may ask for the form: the server picker links here with `?register=1` so its "Register a server"
|
||||
opens the thing rather than landing you on a page that offers the same thing again.
|
||||
|
||||
The flag is CONSUMED — read once, then stripped with `replace`. Leaving it in place would break the
|
||||
control a second time: close the form, click the picker again, and the URL would already say
|
||||
`?register=1`, so there would be no navigation and nothing would happen. Stripping it also means a
|
||||
reload does not reopen a form you dismissed.
|
||||
*/
|
||||
useEffect(() => {
|
||||
if (searchParams.get(OFFSCALE_REGISTER_PARAM) !== '1') return;
|
||||
setFormFor('new');
|
||||
const next = new URLSearchParams(searchParams);
|
||||
next.delete(OFFSCALE_REGISTER_PARAM);
|
||||
setSearchParams(next, { replace: true });
|
||||
}, [searchParams, setSearchParams]);
|
||||
|
||||
const test = async (id: number) => {
|
||||
setTestingIds((prev) => (prev.includes(id) ? prev : [...prev, id]));
|
||||
setActionError(null);
|
||||
|
||||
Reference in New Issue
Block a user