1
0
Fork 0
mirror of synced 2024-10-03 19:43:32 +13:00

Improve navigation when logging in and out, remove need to hard reload the page and replace with smooth transitions

This commit is contained in:
Andrew Kingston 2020-12-11 14:24:19 +00:00
parent 8022fc1230
commit 84e1f54fa0
7 changed files with 46 additions and 13 deletions

View file

@ -3,7 +3,7 @@
import { setContext, onMount } from "svelte" import { setContext, onMount } from "svelte"
import Component from "./Component.svelte" import Component from "./Component.svelte"
import SDK from "../sdk" import SDK from "../sdk"
import { createDataStore, routeStore, screenStore } from "../store" import { createDataStore, initialise, screenStore } from "../store"
// Provide contexts // Provide contexts
setContext("sdk", SDK) setContext("sdk", SDK)
@ -14,13 +14,11 @@
// Load app config // Load app config
onMount(async () => { onMount(async () => {
await routeStore.actions.fetchRoutes() await initialise()
await screenStore.actions.fetchScreens()
loaded = true loaded = true
}) })
</script> </script>
{#if loaded && $screenStore.activeLayout} {#if loaded && $screenStore.activeLayout}
<!-- // TODO: need to get the active screen as well -->
<Component definition={$screenStore.activeLayout.props} /> <Component definition={$screenStore.activeLayout.props} />
{/if} {/if}

View file

@ -7,7 +7,15 @@
const { styleable } = getContext("sdk") const { styleable } = getContext("sdk")
const component = getContext("component") const component = getContext("component")
$: routerConfig = getRouterConfig($routeStore.routes) // Only wrap this as an array to take advantage of svelte keying,
// to ensure the svelte-spa-router is fully remounted when route config
// changes
$: configs = [
{
routes: getRouterConfig($routeStore.routes),
id: $routeStore.routeSessionId,
},
]
const getRouterConfig = routes => { const getRouterConfig = routes => {
let config = {} let config = {}
@ -25,11 +33,11 @@
} }
</script> </script>
{#if routerConfig} {#each configs as config (config.id)}
<div use:styleable={$component.styles}> <div use:styleable={$component.styles}>
<Router on:routeLoading={onRouteLoading} routes={routerConfig} /> <Router on:routeLoading={onRouteLoading} routes={config.routes} />
</div> </div>
{/if} {/each}
<style> <style>
div { div {

View file

@ -1,18 +1,29 @@
import * as API from "../api" import * as API from "../api"
import { getAppId } from "../utils/getAppId" import { getAppId } from "../utils/getAppId"
import { writable } from "svelte/store" import { writable } from "svelte/store"
import { initialise } from "./initialise"
import { routeStore } from "./routes"
const createAuthStore = () => { const createAuthStore = () => {
const store = writable("") const store = writable("")
const goToDefaultRoute = () => {
// Setting the active route forces an update of the active screen ID,
// even if we're on the same URL
routeStore.actions.setActiveRoute("/")
// Navigating updates the URL to reflect this route
routeStore.actions.navigate("/")
}
const logIn = async ({ email, password }) => { const logIn = async ({ email, password }) => {
const user = await API.logIn({ email, password }) const user = await API.logIn({ email, password })
if (!user.error) { if (!user.error) {
store.set(user.token) store.set(user.token)
location.reload() await initialise()
goToDefaultRoute()
} }
} }
const logOut = () => { const logOut = async () => {
store.set("") store.set("")
const appId = getAppId() const appId = getAppId()
if (appId) { if (appId) {
@ -20,7 +31,8 @@ const createAuthStore = () => {
window.document.cookie = `budibase:${appId}:${environment}=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;` window.document.cookie = `budibase:${appId}:${environment}=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;`
} }
} }
location.reload() await initialise()
goToDefaultRoute()
} }
return { return {

View file

@ -1,3 +1,6 @@
import { routeStore } from "./routes"
import { screenStore } from "./screens"
export { authStore } from "./auth" export { authStore } from "./auth"
export { routeStore } from "./routes" export { routeStore } from "./routes"
export { screenStore } from "./screens" export { screenStore } from "./screens"
@ -6,3 +9,6 @@ export { bindingStore } from "./binding"
// Data stores are layered and duplicated, so it is not a singleton // Data stores are layered and duplicated, so it is not a singleton
export { createDataStore, dataStore } from "./data" export { createDataStore, dataStore } from "./data"
// Initialises an app by loading screens and routes
export { initialise } from "./initialise"

View file

@ -0,0 +1,7 @@
import { routeStore } from "./routes"
import { screenStore } from "./screens"
export async function initialise() {
await routeStore.actions.fetchRoutes()
await screenStore.actions.fetchScreens()
}

View file

@ -7,6 +7,7 @@ const createRouteStore = () => {
routes: [], routes: [],
routeParams: {}, routeParams: {},
activeRoute: null, activeRoute: null,
routeSessionId: Math.random(),
} }
const store = writable(initialState) const store = writable(initialState)
@ -29,6 +30,7 @@ const createRouteStore = () => {
store.update(state => { store.update(state => {
state.routes = routes state.routes = routes
state.routeSessionId = Math.random()
return state return state
}) })
} }

View file

@ -6,8 +6,8 @@
export let logoUrl export let logoUrl
const logOut = () => { const logOut = async () => {
authStore.actions.logOut() await authStore.actions.logOut()
} }
</script> </script>