diff --git a/packages/client/src/components/ClientApp.svelte b/packages/client/src/components/ClientApp.svelte index 8db4648cd9..014bea89b3 100644 --- a/packages/client/src/components/ClientApp.svelte +++ b/packages/client/src/components/ClientApp.svelte @@ -18,6 +18,8 @@ import SettingsBar from "./preview/SettingsBar.svelte" import SelectionIndicator from "./preview/SelectionIndicator.svelte" import HoverIndicator from "./preview/HoverIndicator.svelte" + import { Layout, Heading, Body } from "@budibase/bbui" + import ErrorSVG from "../../../builder/assets/error.svg" // Provide contexts setContext("sdk", SDK) @@ -25,6 +27,7 @@ setContext("context", createContextStore()) let dataLoaded = false + let permissionError = false // Load app config onMount(async () => { @@ -46,12 +49,21 @@ }, ] - // Redirect to home layout if no matching route + // Handle no matching route - this is likely a permission error $: { if (dataLoaded && $routeStore.routerLoaded && !$routeStore.activeRoute) { if ($authStore) { - routeStore.actions.navigate("/") + // There is a logged in user, so handle them + if ($screenStore.screens.length) { + // Screens exist so navigate back to the home screen + const firstRoute = $screenStore.screens[0].routing?.route ?? "/" + routeStore.actions.navigate(firstRoute) + } else { + // No screens likely means the user has no permissions to view this app + permissionError = true + } } else { + // The user is not logged in, redirect them to login const returnUrl = `${window.location.pathname}${window.location.hash}` const encodedUrl = encodeURIComponent(returnUrl) window.location = `/builder/auth/login?returnUrl=${encodedUrl}` @@ -60,36 +72,46 @@ } -{#if dataLoaded && $screenStore.activeLayout} +{#if dataLoaded}
- -
- {#key $screenStore.activeLayout._id} - - {/key} + {#if permissionError} +
+ + {@html ErrorSVG} + You don't have permission to use this app + Ask your administrator to grant you access +
- - - - {#key $builderStore.selectedComponentId} + {:else if $screenStore.activeLayout} + +
+ {#key $screenStore.activeLayout._id} + + {/key} +
+ + + + {#key $builderStore.selectedComponentId} + {#if $builderStore.inBuilder} + + {/if} + {/key} + {#if $builderStore.inBuilder} - + + {/if} - {/key} - - {#if $builderStore.inBuilder} - - - {/if} -
+ + {/if}
{/if} @@ -105,4 +127,31 @@ #app-root { position: relative; } + + .error { + position: absolute; + width: 100%; + height: 100%; + display: grid; + place-items: center; + z-index: 1; + text-align: center; + padding: 20px; + } + .error :global(svg) { + fill: var(--spectrum-global-color-gray-500); + width: 80px; + height: 80px; + } + .error :global(h1), + .error :global(p) { + color: var(--spectrum-global-color-gray-800); + } + .error :global(p) { + font-style: italic; + margin-top: -0.5em; + } + .error :global(h1) { + font-weight: 400; + }