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