diff options
Diffstat (limited to 'src/features/tabs')
| -rw-r--r-- | src/features/tabs/ui.test.ts | 31 | ||||
| -rw-r--r-- | src/features/tabs/ui/TabList.svelte | 9 |
2 files changed, 39 insertions, 1 deletions
diff --git a/src/features/tabs/ui.test.ts b/src/features/tabs/ui.test.ts index 9af4cd1..4111c16 100644 --- a/src/features/tabs/ui.test.ts +++ b/src/features/tabs/ui.test.ts @@ -264,4 +264,35 @@ describe("TabList", () => { // Clicking the ID must NOT switch tabs (the badge stops propagation). expect(onSelect).not.toHaveBeenCalled(); }); + + it("shows a loading RING for a 'queued' tab and loading DOTS for an 'active' tab", () => { + render(TabList, { + props: { + tabs: sampleTabs, + activeConversationId: "c1", + statusFor: (id: string) => (id === "c1" ? "queued" : id === "c2" ? "active" : undefined), + onSelect: vi.fn(), + onClose: vi.fn(), + onNewDraft: vi.fn(), + }, + }); + + // c1 is queued → a ring (spinner), labeled "Queued". + const queuedRing = screen.getByLabelText("Queued"); + expect(queuedRing.className).toContain("loading-spinner"); + expect(queuedRing.closest('[role="tab"]')).toHaveTextContent("First"); + + const tabs = screen.getAllByRole("tab"); + expect(tabs).toHaveLength(3); + const activeTab = tabs[1]; + const idleTab = tabs[2]; + if (activeTab === undefined || idleTab === undefined) throw new Error("missing tabs"); + + // c2 is active → loading dots (NOT a spinner). + expect(activeTab.querySelector(".loading-dots")).not.toBeNull(); + expect(activeTab.querySelector(".loading-spinner")).toBeNull(); + + // c3 has no status → no spinner at all. + expect(idleTab.querySelector(".loading")).toBeNull(); + }); }); diff --git a/src/features/tabs/ui/TabList.svelte b/src/features/tabs/ui/TabList.svelte index b1190e4..76e1968 100644 --- a/src/features/tabs/ui/TabList.svelte +++ b/src/features/tabs/ui/TabList.svelte @@ -144,7 +144,14 @@ {tab.title} </span> {/if} - {#if statusFor?.(tab.conversationId) === "active"} + {#if statusFor?.(tab.conversationId) === "queued"} + <!-- Waiting for a concurrency slot — a ring (vs the dots of `active`). --> + <span + class="loading loading-spinner loading-xs shrink-0 text-primary" + aria-label="Queued" + title="Waiting for a concurrency slot" + ></span> + {:else if statusFor?.(tab.conversationId) === "active"} <span class="loading loading-dots loading-xs shrink-0 text-primary"></span> {/if} <button |
