diff --git a/backend/Testing/Browser/Page/BasePage.cs b/backend/Testing/Browser/Page/BasePage.cs index 0eec14d9c..ce167b5f7 100644 --- a/backend/Testing/Browser/Page/BasePage.cs +++ b/backend/Testing/Browser/Page/BasePage.cs @@ -36,11 +36,11 @@ public async Task WaitFor() { if (Url is not null) { - await Page.WaitForURLAsync(Url, new() { WaitUntil = WaitUntilState.NetworkIdle }); + await Page.WaitForURLAsync(Url, new() { WaitUntil = WaitUntilState.Load }); } else { - await Page.WaitForLoadStateAsync(LoadState.NetworkIdle); + await Page.WaitForLoadStateAsync(LoadState.Load); } await Task.WhenAll(TestLocators.Select(l => l.WaitForAsync())); return (T)this; diff --git a/frontend/src/lib/app.postcss b/frontend/src/lib/app.postcss index 3c3df868a..903448514 100644 --- a/frontend/src/lib/app.postcss +++ b/frontend/src/lib/app.postcss @@ -124,3 +124,30 @@ table tr:nth-last-child(-n + 2) .dropdown { transition: background-color 0.5s; } } + +.hydrating { + .input, + input, + button { + visibility: hidden; + } + + form { + & > * { + visibility: hidden; + } + + position: relative; + + &::before { + content: ''; + @apply loading loading-ring bg-primary; + @apply h-32 max-h-full w-auto; + + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + } + } +} diff --git a/frontend/src/routes/+layout.svelte b/frontend/src/routes/+layout.svelte index 75bd9b4bc..eff79487b 100644 --- a/frontend/src/routes/+layout.svelte +++ b/frontend/src/routes/+layout.svelte @@ -11,6 +11,7 @@ import { Duration } from '$lib/util/time'; import { browser } from '$app/environment'; import t from '$lib/i18n'; + import { onMount } from 'svelte'; export let data: LayoutData; const { page, updated } = getStores(); @@ -22,6 +23,9 @@ notifyWarning($t('notifications.update_detected'), Duration.Long); } } + + let hydrating = true; + onMount(() => hydrating = false); @@ -34,7 +38,7 @@ {/if} -
+