Fetch app definition and routes from the server
This commit is contained in:
parent
71b59d7cca
commit
674b89df5d
|
@ -0,0 +1,10 @@
|
|||
import API from "./api"
|
||||
|
||||
/**
|
||||
* Fetches screen definition for an app.
|
||||
*/
|
||||
export const fetchAppDefinition = async appId => {
|
||||
return await API.get({
|
||||
url: `/api/applications/${appId}/definition`,
|
||||
})
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
import api from "./api"
|
||||
import API from "./api"
|
||||
|
||||
/**
|
||||
* Uploads an attachment to the server.
|
||||
*/
|
||||
export const uploadAttachment = async data => {
|
||||
return await api.post({
|
||||
return await API.post({
|
||||
url: "/api/attachments/upload",
|
||||
body: data,
|
||||
json: false,
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
import api from "./api"
|
||||
import API from "./api"
|
||||
|
||||
/**
|
||||
* Performs a log in request.
|
||||
*/
|
||||
export const logIn = async ({ username, password }) => {
|
||||
if (!username) {
|
||||
return api.error("Please enter your username")
|
||||
return API.error("Please enter your username")
|
||||
}
|
||||
if (!password) {
|
||||
return api.error("Please enter your password")
|
||||
return API.error("Please enter your password")
|
||||
}
|
||||
return await api.post({
|
||||
return await API.post({
|
||||
url: "/api/authenticate",
|
||||
body: { username, password },
|
||||
})
|
||||
|
|
|
@ -6,3 +6,4 @@ export * from "./attachments"
|
|||
export * from "./views"
|
||||
export * from "./relationships"
|
||||
export * from "./routes"
|
||||
export * from "./app"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import api from "./api"
|
||||
import API from "./api"
|
||||
import { enrichRows } from "./rows"
|
||||
|
||||
/**
|
||||
|
@ -8,7 +8,7 @@ export const fetchRelationshipData = async ({ tableId, rowId, fieldName }) => {
|
|||
if (!tableId || !rowId || !fieldName) {
|
||||
return []
|
||||
}
|
||||
const response = await api.get({ url: `/api/${tableId}/${rowId}/enrich` })
|
||||
const response = await API.get({ url: `/api/${tableId}/${rowId}/enrich` })
|
||||
const rows = response[fieldName] || []
|
||||
return await enrichRows(rows, tableId)
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import api from "./api"
|
||||
import API from "./api"
|
||||
|
||||
/**
|
||||
* Fetches available routes for the client app.
|
||||
*/
|
||||
export const fetchRoutes = async () => {
|
||||
return await api.get({
|
||||
return await API.get({
|
||||
url: `/api/routing/client`,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import api from "./api"
|
||||
import API from "./api"
|
||||
import { fetchTableDefinition } from "./tables"
|
||||
|
||||
/**
|
||||
* Fetches data about a certain row in a table.
|
||||
*/
|
||||
export const fetchRow = async ({ tableId, rowId }) => {
|
||||
const row = await api.get({
|
||||
const row = await API.get({
|
||||
url: `/api/${tableId}/rows/${rowId}`,
|
||||
})
|
||||
return (await enrichRows([row], tableId))[0]
|
||||
|
@ -15,7 +15,7 @@ export const fetchRow = async ({ tableId, rowId }) => {
|
|||
* Creates a row in a table.
|
||||
*/
|
||||
export const saveRow = async row => {
|
||||
return await api.post({
|
||||
return await API.post({
|
||||
url: `/api/${row.tableId}/rows`,
|
||||
body: row,
|
||||
})
|
||||
|
@ -25,7 +25,7 @@ export const saveRow = async row => {
|
|||
* Updates a row in a table.
|
||||
*/
|
||||
export const updateRow = async row => {
|
||||
return await api.patch({
|
||||
return await API.patch({
|
||||
url: `/api/${row.tableId}/rows/${row._id}`,
|
||||
body: row,
|
||||
})
|
||||
|
@ -35,7 +35,7 @@ export const updateRow = async row => {
|
|||
* Deletes a row from a table.
|
||||
*/
|
||||
export const deleteRow = async ({ tableId, rowId, revId }) => {
|
||||
return await api.del({
|
||||
return await API.del({
|
||||
url: `/api/${tableId}/rows/${rowId}/${revId}`,
|
||||
})
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ export const deleteRow = async ({ tableId, rowId, revId }) => {
|
|||
* Deletes many rows from a table.
|
||||
*/
|
||||
export const deleteRows = async ({ tableId, rows }) => {
|
||||
return await api.post({
|
||||
return await API.post({
|
||||
url: `/api/${tableId}/rows`,
|
||||
body: {
|
||||
rows,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import api from "./api"
|
||||
import API from "./api"
|
||||
import { enrichRows } from "./rows"
|
||||
|
||||
/**
|
||||
|
@ -6,13 +6,13 @@ import { enrichRows } from "./rows"
|
|||
* Since definitions cannot change at runtime, the result is cached.
|
||||
*/
|
||||
export const fetchTableDefinition = async tableId => {
|
||||
return await api.get({ url: `/api/tables/${tableId}`, cache: true })
|
||||
return await API.get({ url: `/api/tables/${tableId}`, cache: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches all rows from a table.
|
||||
*/
|
||||
export const fetchTableData = async tableId => {
|
||||
const rows = await api.get({ url: `/api/${tableId}/rows` })
|
||||
const rows = await API.get({ url: `/api/${tableId}/rows` })
|
||||
return await enrichRows(rows, tableId)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import api from "./api"
|
||||
import API from "./api"
|
||||
import { enrichRows } from "./rows"
|
||||
|
||||
/**
|
||||
|
@ -25,6 +25,6 @@ export const fetchViewData = async ({
|
|||
? `/api/views/${name}?${params}`
|
||||
: `/api/views/${name}`
|
||||
|
||||
const rows = await api.get({ url: QUERY_VIEW_URL })
|
||||
const rows = await API.get({ url: QUERY_VIEW_URL })
|
||||
return await enrichRows(rows, tableId)
|
||||
}
|
||||
|
|
|
@ -1,14 +1,22 @@
|
|||
<script>
|
||||
import { setContext } from "svelte"
|
||||
import { setContext, onMount } from "svelte"
|
||||
import Component from "./Component.svelte"
|
||||
import SDK from "../sdk"
|
||||
import { routeStore, screenStore } from "../store"
|
||||
|
||||
// Provide SDK for components
|
||||
setContext("app", SDK)
|
||||
|
||||
const frontendDefinition = window["##BUDIBASE_FRONTEND_DEFINITION##"]
|
||||
$: pageDefinition = frontendDefinition?.page?.props
|
||||
$: console.log(frontendDefinition)
|
||||
let loaded = false
|
||||
|
||||
// Load app config
|
||||
onMount(async () => {
|
||||
await routeStore.actions.fetchRoutes()
|
||||
await screenStore.actions.fetchScreens()
|
||||
loaded = true
|
||||
})
|
||||
</script>
|
||||
|
||||
<Component definition={pageDefinition} />
|
||||
{#if loaded}
|
||||
<Component definition={$screenStore.page.props} />
|
||||
{/if}
|
||||
|
|
|
@ -6,27 +6,26 @@
|
|||
import { styleable } from "../utils"
|
||||
|
||||
export let styles
|
||||
let routes
|
||||
$: routerConfig = getRouterConfig($routeStore.routes)
|
||||
|
||||
onMount(async () => {
|
||||
await routeStore.actions.fetchRoutes()
|
||||
await screenStore.actions.fetchScreens()
|
||||
routes = {}
|
||||
$routeStore.routes.forEach(route => {
|
||||
routes[route.path] = Screen
|
||||
const getRouterConfig = routes => {
|
||||
let config = {}
|
||||
routes.forEach(route => {
|
||||
config[route.path] = Screen
|
||||
})
|
||||
|
||||
// Add catch-all route so that we serve the Screen component always
|
||||
routes["*"] = Screen
|
||||
})
|
||||
config["*"] = Screen
|
||||
return config
|
||||
}
|
||||
|
||||
function onRouteLoading({ detail }) {
|
||||
const onRouteLoading = ({ detail }) => {
|
||||
routeStore.actions.setActiveRoute(detail.route)
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if routes}
|
||||
{#if routerConfig}
|
||||
<div use:styleable={styles}>
|
||||
<Router on:routeLoading={onRouteLoading} {routes} />
|
||||
<Router on:routeLoading={onRouteLoading} routes={routerConfig} />
|
||||
</div>
|
||||
{/if}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import * as API from "../api"
|
||||
import { getAppId } from "../utils"
|
||||
import { writable } from "svelte/store"
|
||||
import { loc } from "svelte-spa-router"
|
||||
|
||||
const createAuthStore = () => {
|
||||
const store = writable("")
|
||||
|
@ -12,8 +13,8 @@ const createAuthStore = () => {
|
|||
const user = await API.logIn({ username, password })
|
||||
if (!user.error) {
|
||||
store.set(user.token)
|
||||
location.reload()
|
||||
}
|
||||
return !user.error
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -21,14 +22,13 @@ const createAuthStore = () => {
|
|||
*/
|
||||
const logOut = () => {
|
||||
store.set("")
|
||||
|
||||
// Expire any cookies
|
||||
const appId = getAppId()
|
||||
if (appId) {
|
||||
for (let environment of ["local", "cloud"]) {
|
||||
window.document.cookie = `budibase:${appId}:${environment}=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;`
|
||||
}
|
||||
}
|
||||
location.reload()
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -12,18 +12,15 @@ const createRouteStore = () => {
|
|||
|
||||
const fetchRoutes = async () => {
|
||||
const routeConfig = await API.fetchRoutes()
|
||||
let routes = {}
|
||||
Object.values(routeConfig.routes).forEach(pathConfig => {
|
||||
Object.entries(config).forEach(([subPath, subPathConfig]) => {})
|
||||
let routes = []
|
||||
Object.values(routeConfig.routes).forEach(route => {
|
||||
Object.entries(route.subpaths).forEach(([path, config]) => {
|
||||
routes.push({
|
||||
path,
|
||||
screenId: config.screenId,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
console.log(routes2)
|
||||
|
||||
const frontendDefinition = window["##BUDIBASE_FRONTEND_DEFINITION##"]
|
||||
const routes = frontendDefinition.screens.map(screen => ({
|
||||
path: screen.route,
|
||||
screenId: screen._id,
|
||||
}))
|
||||
store.update(state => {
|
||||
state.routes = routes
|
||||
return state
|
||||
|
|
|
@ -1,22 +1,34 @@
|
|||
import { writable, derived } from "svelte/store"
|
||||
import { routeStore } from "./routes"
|
||||
import * as API from "../api"
|
||||
import { getAppId } from "../utils"
|
||||
|
||||
const createScreenStore = () => {
|
||||
const screens = writable([])
|
||||
const store = derived([screens, routeStore], ([$screens, $routeStore]) => {
|
||||
const config = writable({
|
||||
screens: [],
|
||||
page: {},
|
||||
})
|
||||
const store = derived([config, routeStore], ([$config, $routeStore]) => {
|
||||
const { screens, page } = $config
|
||||
const activeScreen =
|
||||
$screens.length === 1
|
||||
? $screens[0]
|
||||
: $screens.find(screen => screen.route === $routeStore.activeRoute)
|
||||
screens.length === 1
|
||||
? screens[0]
|
||||
: screens.find(
|
||||
screen => screen.routing.route === $routeStore.activeRoute
|
||||
)
|
||||
return {
|
||||
screens: $screens,
|
||||
screens,
|
||||
page,
|
||||
activeScreen,
|
||||
}
|
||||
})
|
||||
|
||||
const fetchScreens = () => {
|
||||
const frontendDefinition = window["##BUDIBASE_FRONTEND_DEFINITION##"]
|
||||
screens.set(frontendDefinition.screens)
|
||||
const fetchScreens = async () => {
|
||||
const appDefinition = await API.fetchAppDefinition(getAppId())
|
||||
config.set({
|
||||
screens: appDefinition.screens,
|
||||
page: appDefinition.page,
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -14,12 +14,10 @@
|
|||
<style>
|
||||
div {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: stretch;
|
||||
}
|
||||
div :global(> *) {
|
||||
flex: 1 1 auto;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -24,12 +24,7 @@
|
|||
|
||||
const login = async () => {
|
||||
loading = true
|
||||
const success = await authStore.actions.logIn({ username, password })
|
||||
if (success) {
|
||||
location.reload()
|
||||
} else {
|
||||
error = true
|
||||
}
|
||||
await authStore.actions.logIn({ username, password })
|
||||
loading = false
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
const logOut = () => {
|
||||
authStore.actions.logOut()
|
||||
location.reload()
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
Loading…
Reference in New Issue