From fef186c1cb553ce3424b2e2251529569a5aa7c3a Mon Sep 17 00:00:00 2001 From: Oier Bravo Urtasun Date: Mon, 18 May 2026 13:54:26 +0200 Subject: [PATCH] feat(fase-16): integrate Spinner at the 5 loading sites + E2E coverage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fase 16.2 + 16.3 — replace the bare `m.loading()` text at every pre-existing async-loading site with ` + `. Text is kept (visual fallback + tooltip / SR redundancy). No new loading semantics — only existing flags get a visual indicator. Sites: - (app)/+layout.svelte: auth splash gets `size="lg"` centred under the loading label. - (app)/search/+page.svelte: inline `size="sm"` next to the search-in-flight copy. - (app)/notes/archive/+page.svelte: inline `size="sm"` next to the archive-load copy. - lib/components/CreateCollectiveModal.svelte: inline `size="sm"` inside the disabled Save button while the create RPC is in flight. - (app)/collective/manage/+page.svelte: three sites — members-list load, invitation-generate button, and add-common-item Save button. E2E (tests/e2e/spinner.test.ts): - SP-E-01 throttles search_in_collective RPC by 500ms and asserts the spinner is visible in the loading paragraph. - SP-E-02 throttles set_item_frequency_weight RPC and asserts the spinner is scoped inside the Save button. - SP-E-03 seeds an expired `sb-192-auth-token` so GoTrue is forced to call /auth/v1/token, then hangs that endpoint indefinitely and asserts the splash spinner is visible. Storage key derivation matches Supabase's `sb-${hostname.split('.')[0]}-auth-token` default; we populate both the LAN-IP variant and a loopback fallback for resilience. Co-Authored-By: Claude Opus 4.7 --- .../components/CreateCollectiveModal.svelte | 10 +- apps/web/src/routes/(app)/+layout.svelte | 6 +- .../(app)/collective/manage/+page.svelte | 24 ++- .../routes/(app)/notes/archive/+page.svelte | 6 +- apps/web/src/routes/(app)/search/+page.svelte | 6 +- apps/web/tests/e2e/spinner.test.ts | 149 ++++++++++++++++++ 6 files changed, 190 insertions(+), 11 deletions(-) create mode 100644 apps/web/tests/e2e/spinner.test.ts diff --git a/apps/web/src/lib/components/CreateCollectiveModal.svelte b/apps/web/src/lib/components/CreateCollectiveModal.svelte index 26ebf68..6c4d9ae 100644 --- a/apps/web/src/lib/components/CreateCollectiveModal.svelte +++ b/apps/web/src/lib/components/CreateCollectiveModal.svelte @@ -2,6 +2,7 @@ import { goto } from '$app/navigation'; import { getSupabase } from '$lib/supabase'; import { currentCollective, userCollectives } from '$lib/stores/collective'; + import Spinner from './Spinner.svelte'; import * as m from '$lib/paraglide/messages'; let { onClose }: { onClose: () => void } = $props(); @@ -102,11 +103,16 @@ type="submit" data-testid="create-collective-modal-submit" disabled={!name.trim() || creating} - class="rounded-lg bg-slate-900 px-4 py-1.5 text-sm font-semibold text-white + class="inline-flex items-center gap-2 rounded-lg bg-slate-900 px-4 py-1.5 text-sm font-semibold text-white transition-opacity hover:opacity-90 disabled:opacity-50 dark:bg-slate-50 dark:text-slate-900" > - {creating ? m.loading() : m.create_collective_modal_button()} + {#if creating} + + {m.loading()} + {:else} + {m.create_collective_modal_button()} + {/if} diff --git a/apps/web/src/routes/(app)/+layout.svelte b/apps/web/src/routes/(app)/+layout.svelte index 1cfce8a..bfa220f 100644 --- a/apps/web/src/routes/(app)/+layout.svelte +++ b/apps/web/src/routes/(app)/+layout.svelte @@ -17,6 +17,7 @@ import BottomTabBar from '$lib/components/layout/BottomTabBar.svelte'; import MobileDrawer from '$lib/components/layout/MobileDrawer.svelte'; import UndoToast from '$lib/components/UndoToast.svelte'; + import Spinner from '$lib/components/Spinner.svelte'; import * as m from '$lib/paraglide/messages'; let { children }: { children: Snippet } = $props(); @@ -149,8 +150,9 @@ {#if $authLoading} -
- {m.loading()} +
+ + {m.loading()}
{:else if $isAuthenticated}