app: the regions preview waits for the catalog

"View All Regions" stayed enabled while the catalog was pending or
failed, and the modal received a fresh `catalog || []` on every
render.  Its map effect depends on that array, and ManageMap
re-renders on every status poll, so an open preview tore its WebGL
map down and rebuilt it every three seconds, and a failed catalog was
previewed as zero regions over the error message.

The button is disabled until the catalog is an array, and the modal
is mounted only then, so it receives the state array itself.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Roland 2026-09-26 16:55:17 -06:00
parent 4d3e3c6bb2
commit deeb7c98c0
No known key found for this signature in database
GPG key ID: 1BA620CE6C9A4680
2 changed files with 35 additions and 3 deletions

View file

@ -411,6 +411,8 @@ function ManageMap() {
</>;
}
const catalogLoaded = Array.isArray(catalog);
/*
* A fragment, not a `PageContainer`. `MapRoute` already provides the page chrome -- a
* `wrolpi-stack` wrapper with its own top margin -- so a second one put this page a further
@ -433,11 +435,16 @@ function ManageMap() {
<div style={{display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '0.5em'}}>
<Header as='h3'>Map Subscriptions</Header>
<Button size='xs' icon='globe' onClick={() => setAllRegionsOpen(true)}>View All Regions</Button>
{/* A pending or failed catalog is not "zero regions": the preview waits for one. The
modal is mounted only then, so it receives the state array itself and its map is
not rebuilt by a fresh `[]` on every status tick. */}
<Button size='xs' icon='globe' disabled={!catalogLoaded} onClick={() => setAllRegionsOpen(true)}>
View All Regions
</Button>
</div>
<AllRegionsPreviewModal catalog={catalog || []} open={allRegionsOpen}
onClose={() => setAllRegionsOpen(false)}/>
{catalogLoaded && <AllRegionsPreviewModal catalog={catalog} open={allRegionsOpen}
onClose={() => setAllRegionsOpen(false)}/>}
{catalog === undefined
? <ErrorMessage>Could not fetch map subscriptions</ErrorMessage>

View file

@ -120,4 +120,29 @@ describe('the Manage tab subscriptions table', () => {
});
expect(screen.getByText(NO_RESULTS)).toBeInTheDocument();
});
// The "View All Regions" preview draws the catalog; a pending or failed catalog must not be
// previewed as zero regions.
test('pending: the regions preview is disabled', async () => {
api.fetchMapSubscriptions.mockReturnValue(pending());
renderAt('/map/manage');
await act(async () => {
});
expect(screen.getByRole('button', {name: 'View All Regions'})).toBeDisabled();
});
test('failed: the regions preview is disabled', async () => {
api.fetchMapSubscriptions.mockResolvedValue(undefined);
renderAt('/map/manage');
await act(async () => {
});
expect(screen.getByRole('button', {name: 'View All Regions'})).toBeDisabled();
});
test('loaded: the regions preview is enabled', async () => {
renderAt('/map/manage');
await act(async () => {
});
expect(screen.getByRole('button', {name: 'View All Regions'})).toBeEnabled();
});
});