mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-08 16:03:27 +00:00
fix(frontend): stop the template picker spinning on a hub with no projects
Opening the picker against a reachable hub that has published nothing pinned the renderer at full CPU and froze the tab. The effect arming the list called `setLoader` and `loadData`, which read `InfiniteList`'s reactive state as well as writing it, so the effect depended on what its own load changed and re-ran itself; a list that stays empty never settles that cycle. It now arms the loader once per workspace, untracked, and leaves the load to `setLoader`. The same empty list also claimed the hub was unreachable, since one `empty` snippet serves both. The loader records which happened, so a hub with nothing on it says so. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JirHCYVR6qg7Xqe4PcZ1KG
This commit is contained in:
co-authored by
Claude Opus 5
parent
ac6295722a
commit
3acff46383
@@ -1,4 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { untrack } from 'svelte'
|
||||
import { ArrowRight, ArrowUpRight, LayoutGrid, Star } from 'lucide-svelte'
|
||||
import InfiniteList from '$lib/components/InfiniteList.svelte'
|
||||
import {
|
||||
@@ -22,14 +23,32 @@
|
||||
// The hub serves its whole catalogue in one response, so paging happens here: the list
|
||||
// asks for a window and gets a slice of what `hubProjectCatalogue` already holds. Should
|
||||
// the hub ever paginate, only this loader changes.
|
||||
// `InfiniteList` shows its `empty` snippet for a list that came back empty and for one that
|
||||
// failed, so the loader records which happened: a reachable hub that has published nothing
|
||||
// is not a hub that could not be reached.
|
||||
let loadFailed = $state(false)
|
||||
|
||||
// Armed once per workspace, and inside `untrack`: `setLoader` loads immediately, and both
|
||||
// it and `loadData` read the list's own reactive state as well as writing it — called
|
||||
// tracked, this effect depends on what the load changes and re-runs itself. An empty
|
||||
// catalogue never settles that cycle, which spins the tab at full CPU.
|
||||
let loadedFor: string | undefined = undefined
|
||||
$effect(() => {
|
||||
const workspace = $workspaceStore
|
||||
if (!list || !workspace) return
|
||||
list.setLoader(async (page: number, perPage: number) => {
|
||||
const all = await hubProjectCatalogue(workspace)
|
||||
return all.slice((page - 1) * perPage, page * perPage)
|
||||
if (!list || !workspace || loadedFor === workspace) return
|
||||
loadedFor = workspace
|
||||
untrack(() => {
|
||||
list?.setLoader(async (page: number, perPage: number) => {
|
||||
try {
|
||||
const all = await hubProjectCatalogue(workspace)
|
||||
loadFailed = false
|
||||
return all.slice((page - 1) * perPage, page * perPage)
|
||||
} catch (error) {
|
||||
loadFailed = true
|
||||
throw error
|
||||
}
|
||||
})
|
||||
})
|
||||
list.loadData('refresh')
|
||||
})
|
||||
|
||||
let hubUrl = $state('https://hub.windmill.dev')
|
||||
@@ -120,7 +139,11 @@
|
||||
|
||||
{#snippet empty()}
|
||||
<p class="px-3 py-6 text-xs text-secondary">
|
||||
Could not reach the hub. You can still browse its projects in a new tab.
|
||||
{#if loadFailed}
|
||||
Could not reach the hub. You can still browse its projects in a new tab.
|
||||
{:else}
|
||||
This hub has no projects yet.
|
||||
{/if}
|
||||
</p>
|
||||
{/snippet}
|
||||
</InfiniteList>
|
||||
|
||||
Reference in New Issue
Block a user