Update remaining builder stores to use new core API and handle errors properly
This commit is contained in:
parent
453386696f
commit
db3b4c0b8c
|
@ -109,9 +109,11 @@ export const getFrontendStore = () => {
|
||||||
theme: {
|
theme: {
|
||||||
save: async theme => {
|
save: async theme => {
|
||||||
const appId = get(store).appId
|
const appId = get(store).appId
|
||||||
const metadata = { appId, theme }
|
|
||||||
try {
|
try {
|
||||||
await API.saveAppMetadata(metadata)
|
await API.saveAppMetadata({
|
||||||
|
appId,
|
||||||
|
metadata: { theme },
|
||||||
|
})
|
||||||
store.update(state => {
|
store.update(state => {
|
||||||
state.theme = theme
|
state.theme = theme
|
||||||
return state
|
return state
|
||||||
|
@ -124,9 +126,11 @@ export const getFrontendStore = () => {
|
||||||
customTheme: {
|
customTheme: {
|
||||||
save: async customTheme => {
|
save: async customTheme => {
|
||||||
const appId = get(store).appId
|
const appId = get(store).appId
|
||||||
const metadata = { appId, customTheme }
|
|
||||||
try {
|
try {
|
||||||
await API.saveAppMetadata(metadata)
|
await API.saveAppMetadata({
|
||||||
|
appId,
|
||||||
|
metadata: { customTheme },
|
||||||
|
})
|
||||||
store.update(state => {
|
store.update(state => {
|
||||||
state.customTheme = customTheme
|
state.customTheme = customTheme
|
||||||
return state
|
return state
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
Detail,
|
Detail,
|
||||||
Divider,
|
Divider,
|
||||||
Layout,
|
Layout,
|
||||||
|
notifications,
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import { auth } from "stores/portal"
|
import { auth } from "stores/portal"
|
||||||
|
|
||||||
|
@ -45,20 +46,28 @@
|
||||||
improvements,
|
improvements,
|
||||||
comment,
|
comment,
|
||||||
})
|
})
|
||||||
auth.updateSelf({
|
try {
|
||||||
flags: {
|
auth.updateSelf({
|
||||||
feedbackSubmitted: true,
|
flags: {
|
||||||
},
|
feedbackSubmitted: true,
|
||||||
})
|
},
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Error updating user")
|
||||||
|
}
|
||||||
dispatch("complete")
|
dispatch("complete")
|
||||||
}
|
}
|
||||||
|
|
||||||
function cancelFeedback() {
|
function cancelFeedback() {
|
||||||
auth.updateSelf({
|
try {
|
||||||
flags: {
|
auth.updateSelf({
|
||||||
feedbackSubmitted: true,
|
flags: {
|
||||||
},
|
feedbackSubmitted: true,
|
||||||
})
|
},
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Error updating user")
|
||||||
|
}
|
||||||
dispatch("complete")
|
dispatch("complete")
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
<script>
|
<script>
|
||||||
import { ModalContent, Modal, Icon, ColorPicker, Label } from "@budibase/bbui"
|
import {
|
||||||
|
ModalContent,
|
||||||
|
Modal,
|
||||||
|
Icon,
|
||||||
|
ColorPicker,
|
||||||
|
Label,
|
||||||
|
notifications,
|
||||||
|
} from "@budibase/bbui"
|
||||||
import { apps } from "stores/portal"
|
import { apps } from "stores/portal"
|
||||||
|
|
||||||
export let app
|
export let app
|
||||||
|
@ -51,12 +58,16 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
const save = async () => {
|
const save = async () => {
|
||||||
await apps.update(app.instance._id, {
|
try {
|
||||||
icon: {
|
await apps.update(app.instance._id, {
|
||||||
name: selectedIcon,
|
icon: {
|
||||||
color: selectedColor,
|
name: selectedIcon,
|
||||||
},
|
color: selectedColor,
|
||||||
})
|
},
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Error updating app")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -118,15 +118,18 @@
|
||||||
await auth.setInitInfo({})
|
await auth.setInitInfo({})
|
||||||
$goto(`/builder/app/${createdApp.instance._id}`)
|
$goto(`/builder/app/${createdApp.instance._id}`)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
notifications.error("Error creating app")
|
||||||
notifications.error(error)
|
|
||||||
submitting = false
|
submitting = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onCancel() {
|
async function onCancel() {
|
||||||
template = null
|
template = null
|
||||||
await auth.setInitInfo({})
|
try {
|
||||||
|
await auth.setInitInfo({})
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Error setting init info")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -80,8 +80,7 @@
|
||||||
await apps.update(app.instance._id, { name: $values.name.trim() })
|
await apps.update(app.instance._id, { name: $values.name.trim() })
|
||||||
hide()
|
hide()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
notifications.error("Error updating app")
|
||||||
notifications.error(error)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
import { admin, auth } from "stores/portal"
|
import { admin, auth } from "stores/portal"
|
||||||
import { onMount } from "svelte"
|
import { onMount } from "svelte"
|
||||||
import { CookieUtils, Constants } from "@budibase/frontend-core"
|
import { CookieUtils, Constants } from "@budibase/frontend-core"
|
||||||
|
import { notifications } from "@budibase/bbui"
|
||||||
|
|
||||||
let loaded = false
|
let loaded = false
|
||||||
|
|
||||||
|
@ -41,9 +42,12 @@
|
||||||
|
|
||||||
if (user.tenantId !== urlTenantId) {
|
if (user.tenantId !== urlTenantId) {
|
||||||
// user should not be here - play it safe and log them out
|
// user should not be here - play it safe and log them out
|
||||||
await auth.logout()
|
try {
|
||||||
await auth.setOrganisation(null)
|
await auth.logout()
|
||||||
return
|
await auth.setOrganisation(null)
|
||||||
|
} catch (error) {
|
||||||
|
// Swallow error and do nothing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// no user - set the org according to the url
|
// no user - set the org according to the url
|
||||||
|
@ -52,17 +56,18 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
if ($params["?template"]) {
|
try {
|
||||||
await auth.setInitInfo({ init_template: $params["?template"] })
|
if ($params["?template"]) {
|
||||||
|
await auth.setInitInfo({ init_template: $params["?template"] })
|
||||||
|
}
|
||||||
|
await auth.checkAuth()
|
||||||
|
await admin.init()
|
||||||
|
if (useAccountPortal && multiTenancyEnabled) {
|
||||||
|
await validateTenantId()
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Error initialising builder")
|
||||||
}
|
}
|
||||||
|
|
||||||
await auth.checkAuth()
|
|
||||||
await admin.init()
|
|
||||||
|
|
||||||
if (useAccountPortal && multiTenancyEnabled) {
|
|
||||||
await validateTenantId()
|
|
||||||
}
|
|
||||||
|
|
||||||
loaded = true
|
loaded = true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -31,17 +31,21 @@
|
||||||
adminUser.tenantId = tenantId
|
adminUser.tenantId = tenantId
|
||||||
// Save the admin user
|
// Save the admin user
|
||||||
await API.createAdminUser(adminUser)
|
await API.createAdminUser(adminUser)
|
||||||
notifications.success(`Admin user created`)
|
notifications.success("Admin user created")
|
||||||
await admin.init()
|
await admin.init()
|
||||||
$goto("../portal")
|
$goto("../portal")
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
notifications.error(`Failed to create admin user: ${err}`)
|
notifications.error("Failed to create admin user")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
if (!cloud) {
|
if (!cloud) {
|
||||||
await admin.checkImportComplete()
|
try {
|
||||||
|
await admin.checkImportComplete()
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Error checking import status")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
Icon,
|
Icon,
|
||||||
Body,
|
Body,
|
||||||
Modal,
|
Modal,
|
||||||
|
notifications,
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import { onMount } from "svelte"
|
import { onMount } from "svelte"
|
||||||
import { apps, organisation, auth, admin } from "stores/portal"
|
import { apps, organisation, auth, admin } from "stores/portal"
|
||||||
|
@ -26,8 +27,12 @@
|
||||||
let changePasswordModal
|
let changePasswordModal
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
await organisation.init()
|
try {
|
||||||
await apps.load()
|
await organisation.init()
|
||||||
|
await apps.load()
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Error loading apps")
|
||||||
|
}
|
||||||
loaded = true
|
loaded = true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -44,6 +49,14 @@
|
||||||
function getUrl(app) {
|
function getUrl(app) {
|
||||||
return !isCloud ? `/app/${encodeURIComponent(app.name)}` : `/${app.prodId}`
|
return !isCloud ? `/app/${encodeURIComponent(app.name)}` : `/${app.prodId}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const logout = async () => {
|
||||||
|
try {
|
||||||
|
await auth.logout()
|
||||||
|
} catch (error) {
|
||||||
|
// Swallow error and do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if $auth.user && loaded}
|
{#if $auth.user && loaded}
|
||||||
|
@ -79,7 +92,7 @@
|
||||||
Open developer mode
|
Open developer mode
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
{/if}
|
{/if}
|
||||||
<MenuItem icon="LogOut" on:click={auth.logout}>Log out</MenuItem>
|
<MenuItem icon="LogOut" on:click={logout}>Log out</MenuItem>
|
||||||
</ActionMenu>
|
</ActionMenu>
|
||||||
</div>
|
</div>
|
||||||
<Layout noPadding gap="XS">
|
<Layout noPadding gap="XS">
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { ActionButton } from "@budibase/bbui"
|
import { ActionButton, notifications } from "@budibase/bbui"
|
||||||
import OidcLogo from "assets/oidc-logo.png"
|
import OidcLogo from "assets/oidc-logo.png"
|
||||||
import Auth0Logo from "assets/auth0-logo.png"
|
import Auth0Logo from "assets/auth0-logo.png"
|
||||||
import MicrosoftLogo from "assets/microsoft-logo.png"
|
import MicrosoftLogo from "assets/microsoft-logo.png"
|
||||||
|
@ -20,7 +20,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
await oidc.init()
|
try {
|
||||||
|
await oidc.init()
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Error getting OIDC config")
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
$: src = !$oidc.logo
|
$: src = !$oidc.logo
|
||||||
|
|
|
@ -25,7 +25,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
await organisation.init()
|
try {
|
||||||
|
await organisation.init()
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Error getting org config")
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import { redirect } from "@roxi/routify"
|
import { redirect } from "@roxi/routify"
|
||||||
import { auth, admin } from "stores/portal"
|
import { auth, admin } from "stores/portal"
|
||||||
import { onMount } from "svelte"
|
import { onMount } from "svelte"
|
||||||
|
import { notifications } from "@budibase/bbui"
|
||||||
|
|
||||||
$: tenantSet = $auth.tenantSet
|
$: tenantSet = $auth.tenantSet
|
||||||
$: multiTenancyEnabled = $admin.multiTenancy
|
$: multiTenancyEnabled = $admin.multiTenancy
|
||||||
|
@ -17,8 +18,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
await admin.init()
|
try {
|
||||||
await auth.checkQueryString()
|
await admin.init()
|
||||||
|
await auth.checkQueryString()
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Error getting checklist")
|
||||||
|
}
|
||||||
loaded = true
|
loaded = true
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
username,
|
username,
|
||||||
password,
|
password,
|
||||||
})
|
})
|
||||||
|
|
||||||
if ($auth?.user?.forceResetPassword) {
|
if ($auth?.user?.forceResetPassword) {
|
||||||
$goto("./reset")
|
$goto("./reset")
|
||||||
} else {
|
} else {
|
||||||
|
@ -39,8 +38,7 @@
|
||||||
$goto("../portal")
|
$goto("../portal")
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
notifications.error(err.message ? err.message : "Invalid credentials")
|
||||||
notifications.error(err.message ? err.message : "Invalid Credentials")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +47,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
await organisation.init()
|
try {
|
||||||
|
await organisation.init()
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Error getting org config")
|
||||||
|
}
|
||||||
loaded = true
|
loaded = true
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,5 +1,13 @@
|
||||||
<script>
|
<script>
|
||||||
import { Body, Button, Divider, Heading, Input, Layout } from "@budibase/bbui"
|
import {
|
||||||
|
Body,
|
||||||
|
Button,
|
||||||
|
Divider,
|
||||||
|
Heading,
|
||||||
|
Input,
|
||||||
|
Layout,
|
||||||
|
notifications,
|
||||||
|
} from "@budibase/bbui"
|
||||||
import { goto } from "@roxi/routify"
|
import { goto } from "@roxi/routify"
|
||||||
import { auth, admin } from "stores/portal"
|
import { auth, admin } from "stores/portal"
|
||||||
import Logo from "assets/bb-emblem.svg"
|
import Logo from "assets/bb-emblem.svg"
|
||||||
|
@ -13,13 +21,17 @@
|
||||||
$: useAccountPortal = cloud && !$admin.disableAccountPortal
|
$: useAccountPortal = cloud && !$admin.disableAccountPortal
|
||||||
|
|
||||||
async function setOrg() {
|
async function setOrg() {
|
||||||
if (tenantId == null || tenantId === "") {
|
try {
|
||||||
tenantId = "default"
|
if (tenantId == null || tenantId === "") {
|
||||||
|
tenantId = "default"
|
||||||
|
}
|
||||||
|
await auth.setOrg(tenantId)
|
||||||
|
// re-init now org selected
|
||||||
|
await admin.init()
|
||||||
|
$goto("../")
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Error setting organisation")
|
||||||
}
|
}
|
||||||
await auth.setOrg(tenantId)
|
|
||||||
// re-init now org selected
|
|
||||||
await admin.init()
|
|
||||||
$goto("../")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleKeydown(evt) {
|
function handleKeydown(evt) {
|
||||||
|
|
|
@ -31,7 +31,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
await organisation.init()
|
try {
|
||||||
|
await organisation.init()
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Error getting org config")
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -10,14 +10,11 @@
|
||||||
|
|
||||||
async function acceptInvite() {
|
async function acceptInvite() {
|
||||||
try {
|
try {
|
||||||
const res = await users.acceptInvite(inviteCode, password)
|
await users.acceptInvite(inviteCode, password)
|
||||||
if (!res) {
|
notifications.success("Invitation accepted successfully")
|
||||||
throw new Error(res.message)
|
|
||||||
}
|
|
||||||
notifications.success(`User created.`)
|
|
||||||
$goto("../auth/login")
|
$goto("../auth/login")
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
notifications.error(err)
|
notifications.error("Error accepting invitation")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
MenuItem,
|
MenuItem,
|
||||||
Modal,
|
Modal,
|
||||||
clickOutside,
|
clickOutside,
|
||||||
|
notifications,
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import ConfigChecklist from "components/common/ConfigChecklist.svelte"
|
import ConfigChecklist from "components/common/ConfigChecklist.svelte"
|
||||||
import { organisation, auth } from "stores/portal"
|
import { organisation, auth } from "stores/portal"
|
||||||
|
@ -78,6 +79,14 @@
|
||||||
return menu
|
return menu
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const logout = async () => {
|
||||||
|
try {
|
||||||
|
await auth.logout()
|
||||||
|
} catch (error) {
|
||||||
|
// Swallow error and do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const showMobileMenu = () => (mobileMenuVisible = true)
|
const showMobileMenu = () => (mobileMenuVisible = true)
|
||||||
const hideMobileMenu = () => (mobileMenuVisible = false)
|
const hideMobileMenu = () => (mobileMenuVisible = false)
|
||||||
|
|
||||||
|
@ -87,7 +96,11 @@
|
||||||
if (!$auth.user?.builder?.global) {
|
if (!$auth.user?.builder?.global) {
|
||||||
$redirect("../")
|
$redirect("../")
|
||||||
} else {
|
} else {
|
||||||
await organisation.init()
|
try {
|
||||||
|
await organisation.init()
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Error getting org config")
|
||||||
|
}
|
||||||
loaded = true
|
loaded = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,7 +171,7 @@
|
||||||
<MenuItem icon="UserDeveloper" on:click={() => $goto("../apps")}>
|
<MenuItem icon="UserDeveloper" on:click={() => $goto("../apps")}>
|
||||||
Close developer mode
|
Close developer mode
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem icon="LogOut" on:click={auth.logout}>Log out</MenuItem>
|
<MenuItem icon="LogOut" on:click={logout}>Log out</MenuItem>
|
||||||
</ActionMenu>
|
</ActionMenu>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -139,7 +139,6 @@
|
||||||
$goto(`/builder/app/${createdApp.instance._id}`)
|
$goto(`/builder/app/${createdApp.instance._id}`)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
notifications.error("Error creating app")
|
notifications.error("Error creating app")
|
||||||
console.error(error)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,17 +247,23 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
await apps.load()
|
try {
|
||||||
await templates.load()
|
await apps.load()
|
||||||
if ($templates?.length === 0) {
|
await templates.load()
|
||||||
notifications.error("There was a problem loading quick start templates.")
|
if ($templates?.length === 0) {
|
||||||
}
|
notifications.error(
|
||||||
// if the portal is loaded from an external URL with a template param
|
"There was a problem loading quick start templates."
|
||||||
const initInfo = await auth.getInitInfo()
|
)
|
||||||
if (initInfo?.init_template) {
|
}
|
||||||
creatingFromTemplate = true
|
// If the portal is loaded from an external URL with a template param
|
||||||
createAppFromTemplateUrl(initInfo.init_template)
|
const initInfo = await auth.getInitInfo()
|
||||||
return
|
if (initInfo?.init_template) {
|
||||||
|
creatingFromTemplate = true
|
||||||
|
createAppFromTemplateUrl(initInfo.init_template)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Error loading apps and templates")
|
||||||
}
|
}
|
||||||
loaded = true
|
loaded = true
|
||||||
})
|
})
|
||||||
|
|
|
@ -207,15 +207,18 @@
|
||||||
notifications.success(`Settings saved`)
|
notifications.success(`Settings saved`)
|
||||||
analytics.captureEvent(Events.SSO.SAVED)
|
analytics.captureEvent(Events.SSO.SAVED)
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(() => {
|
||||||
notifications.error(`Failed to update auth settings`)
|
notifications.error("Failed to update auth settings")
|
||||||
console.error(error.message)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
await organisation.init()
|
try {
|
||||||
|
await organisation.init()
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Error getting org config")
|
||||||
|
}
|
||||||
|
|
||||||
// Fetch Google config
|
// Fetch Google config
|
||||||
let googleDoc
|
let googleDoc
|
||||||
|
|
|
@ -36,9 +36,9 @@
|
||||||
try {
|
try {
|
||||||
// Save your template config
|
// Save your template config
|
||||||
await email.templates.save(selectedTemplate)
|
await email.templates.save(selectedTemplate)
|
||||||
notifications.success(`Template saved.`)
|
notifications.success("Template saved")
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
notifications.error(`Failed to update template settings. ${err}`)
|
notifications.error("Failed to update template settings")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,15 @@
|
||||||
<script>
|
<script>
|
||||||
|
import { onMount } from "svelte"
|
||||||
import { email } from "stores/portal"
|
import { email } from "stores/portal"
|
||||||
|
import { notifications } from "@budibase/bbui"
|
||||||
|
|
||||||
email.templates.fetch()
|
onMount(async () => {
|
||||||
|
try {
|
||||||
|
await email.templates.fetch()
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Error fetching email templates")
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<slot />
|
<slot />
|
||||||
|
|
|
@ -64,31 +64,43 @@
|
||||||
const apps = fetchData(`/api/global/roles`)
|
const apps = fetchData(`/api/global/roles`)
|
||||||
|
|
||||||
async function deleteUser() {
|
async function deleteUser() {
|
||||||
const res = await users.delete(userId)
|
try {
|
||||||
if (res.status === 200) {
|
await users.delete(userId)
|
||||||
notifications.success(`User ${$userFetch?.data?.email} deleted.`)
|
notifications.success(`User ${$userFetch?.data?.email} deleted.`)
|
||||||
$goto("./")
|
$goto("./")
|
||||||
} else {
|
} catch (error) {
|
||||||
notifications.error(res?.message ? res.message : "Failed to delete user.")
|
notifications.error("Error deleting user")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let toggleDisabled = false
|
let toggleDisabled = false
|
||||||
|
|
||||||
async function updateUserFirstName(evt) {
|
async function updateUserFirstName(evt) {
|
||||||
await users.save({ ...$userFetch?.data, firstName: evt.target.value })
|
try {
|
||||||
await userFetch.refresh()
|
await users.save({ ...$userFetch?.data, firstName: evt.target.value })
|
||||||
|
await userFetch.refresh()
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Error updating user")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateUserLastName(evt) {
|
async function updateUserLastName(evt) {
|
||||||
await users.save({ ...$userFetch?.data, lastName: evt.target.value })
|
try {
|
||||||
await userFetch.refresh()
|
await users.save({ ...$userFetch?.data, lastName: evt.target.value })
|
||||||
|
await userFetch.refresh()
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Error updating user")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function toggleFlag(flagName, detail) {
|
async function toggleFlag(flagName, detail) {
|
||||||
toggleDisabled = true
|
toggleDisabled = true
|
||||||
await users.save({ ...$userFetch?.data, [flagName]: { global: detail } })
|
try {
|
||||||
await userFetch.refresh()
|
await users.save({ ...$userFetch?.data, [flagName]: { global: detail } })
|
||||||
|
await userFetch.refresh()
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Error updating user")
|
||||||
|
}
|
||||||
toggleDisabled = false
|
toggleDisabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,12 +21,12 @@
|
||||||
const [email, error, touched] = createValidationStore("", emailValidator)
|
const [email, error, touched] = createValidationStore("", emailValidator)
|
||||||
|
|
||||||
async function createUserFlow() {
|
async function createUserFlow() {
|
||||||
const res = await users.invite({ email: $email, builder, admin })
|
try {
|
||||||
if (res.status) {
|
const res = await users.invite({ email: $email, builder, admin })
|
||||||
notifications.error(res.message)
|
|
||||||
} else {
|
|
||||||
notifications.success(res.message)
|
notifications.success(res.message)
|
||||||
analytics.captureEvent(Events.USER.INVITE, { type: selected })
|
analytics.captureEvent(Events.USER.INVITE, { type: selected })
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Error inviting user")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -16,17 +16,17 @@
|
||||||
admin = false
|
admin = false
|
||||||
|
|
||||||
async function createUser() {
|
async function createUser() {
|
||||||
const res = await users.create({
|
try {
|
||||||
email: $email,
|
await users.create({
|
||||||
password,
|
email: $email,
|
||||||
builder,
|
password,
|
||||||
admin,
|
builder,
|
||||||
forceResetPassword: true,
|
admin,
|
||||||
})
|
forceResetPassword: true,
|
||||||
if (res.status) {
|
})
|
||||||
notifications.error(res.message)
|
|
||||||
} else {
|
|
||||||
notifications.success("Successfully created user")
|
notifications.success("Successfully created user")
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Error creating user")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -10,16 +10,16 @@
|
||||||
const password = Math.random().toString(36).substr(2, 20)
|
const password = Math.random().toString(36).substr(2, 20)
|
||||||
|
|
||||||
async function resetPassword() {
|
async function resetPassword() {
|
||||||
const res = await users.save({
|
try {
|
||||||
...user,
|
await users.save({
|
||||||
password,
|
...user,
|
||||||
forceResetPassword: true,
|
password,
|
||||||
})
|
forceResetPassword: true,
|
||||||
if (res.status) {
|
})
|
||||||
notifications.error(res.message)
|
notifications.success("Password reset successfully")
|
||||||
} else {
|
|
||||||
notifications.success("Password reset.")
|
|
||||||
dispatch("update")
|
dispatch("update")
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Error resetting password")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -18,33 +18,31 @@
|
||||||
let selectedRole = user?.roles?.[app?._id]
|
let selectedRole = user?.roles?.[app?._id]
|
||||||
|
|
||||||
async function updateUserRoles() {
|
async function updateUserRoles() {
|
||||||
let res
|
try {
|
||||||
if (selectedRole === NO_ACCESS) {
|
if (selectedRole === NO_ACCESS) {
|
||||||
// remove the user role
|
// Remove the user role
|
||||||
const filteredRoles = { ...user.roles }
|
const filteredRoles = { ...user.roles }
|
||||||
delete filteredRoles[app?._id]
|
delete filteredRoles[app?._id]
|
||||||
res = await users.save({
|
await users.save({
|
||||||
...user,
|
...user,
|
||||||
roles: {
|
roles: {
|
||||||
...filteredRoles,
|
...filteredRoles,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// add the user role
|
// Add the user role
|
||||||
res = await users.save({
|
await users.save({
|
||||||
...user,
|
...user,
|
||||||
roles: {
|
roles: {
|
||||||
...user.roles,
|
...user.roles,
|
||||||
[app._id]: selectedRole,
|
[app._id]: selectedRole,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.status === 400) {
|
|
||||||
notifications.error("Failed to update role")
|
|
||||||
} else {
|
|
||||||
notifications.success("Role updated")
|
notifications.success("Role updated")
|
||||||
dispatch("update")
|
dispatch("update")
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Failed to update role")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -11,13 +11,13 @@
|
||||||
Label,
|
Label,
|
||||||
Layout,
|
Layout,
|
||||||
Modal,
|
Modal,
|
||||||
|
notifications,
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import TagsRenderer from "./_components/TagsTableRenderer.svelte"
|
import TagsRenderer from "./_components/TagsTableRenderer.svelte"
|
||||||
import AddUserModal from "./_components/AddUserModal.svelte"
|
import AddUserModal from "./_components/AddUserModal.svelte"
|
||||||
import BasicOnboardingModal from "./_components/BasicOnboardingModal.svelte"
|
import BasicOnboardingModal from "./_components/BasicOnboardingModal.svelte"
|
||||||
import { users } from "stores/portal"
|
import { users } from "stores/portal"
|
||||||
|
import { onMount } from "svelte"
|
||||||
users.init()
|
|
||||||
|
|
||||||
const schema = {
|
const schema = {
|
||||||
email: {},
|
email: {},
|
||||||
|
@ -47,6 +47,14 @@
|
||||||
createUserModal.hide()
|
createUserModal.hide()
|
||||||
basicOnboardingModal.show()
|
basicOnboardingModal.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
try {
|
||||||
|
await users.init()
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Error getting user list")
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Layout noPadding>
|
<Layout noPadding>
|
||||||
|
|
|
@ -44,24 +44,28 @@
|
||||||
async function saveConfig() {
|
async function saveConfig() {
|
||||||
loading = true
|
loading = true
|
||||||
|
|
||||||
// Upload logo if required
|
try {
|
||||||
if ($values.logo && !$values.logo.url) {
|
// Upload logo if required
|
||||||
await uploadLogo($values.logo)
|
if ($values.logo && !$values.logo.url) {
|
||||||
await organisation.init()
|
await uploadLogo($values.logo)
|
||||||
}
|
await organisation.init()
|
||||||
|
}
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
company: $values.company ?? "",
|
company: $values.company ?? "",
|
||||||
platformUrl: $values.platformUrl ?? "",
|
platformUrl: $values.platformUrl ?? "",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove logo if required
|
// Remove logo if required
|
||||||
if (!$values.logo) {
|
if (!$values.logo) {
|
||||||
config.logoUrl = ""
|
config.logoUrl = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update settings
|
// Update settings
|
||||||
await organisation.save(config)
|
await organisation.save(config)
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error("Error saving org config")
|
||||||
|
}
|
||||||
loading = false
|
loading = false
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -23,65 +23,37 @@ export function createAdminStore() {
|
||||||
const admin = writable(DEFAULT_CONFIG)
|
const admin = writable(DEFAULT_CONFIG)
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
try {
|
const tenantId = get(auth).tenantId
|
||||||
const tenantId = get(auth).tenantId
|
const checklist = await API.getChecklist(tenantId)
|
||||||
const checklist = await API.getChecklist(tenantId)
|
const totalSteps = Object.keys(checklist).length
|
||||||
const totalSteps = Object.keys(checklist).length
|
const completedSteps = Object.values(checklist).filter(
|
||||||
const completedSteps = Object.values(checklist).filter(
|
x => x?.checked
|
||||||
x => x?.checked
|
).length
|
||||||
).length
|
await getEnvironment()
|
||||||
await getEnvironment()
|
admin.update(store => {
|
||||||
admin.update(store => {
|
store.loaded = true
|
||||||
store.loaded = true
|
store.checklist = checklist
|
||||||
store.checklist = checklist
|
store.onboardingProgress = (completedSteps / totalSteps) * 100
|
||||||
store.onboardingProgress = (completedSteps / totalSteps) * 100
|
return store
|
||||||
return store
|
})
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
admin.update(store => {
|
|
||||||
store.checklist = null
|
|
||||||
return store
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function checkImportComplete() {
|
async function checkImportComplete() {
|
||||||
try {
|
const result = await API.checkImportComplete()
|
||||||
const result = await API.checkImportComplete()
|
admin.update(store => {
|
||||||
admin.update(store => {
|
store.importComplete = result ? result.imported : false
|
||||||
store.importComplete = result ? result.imported : false
|
return store
|
||||||
return store
|
})
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
admin.update(store => {
|
|
||||||
store.importComplete = false
|
|
||||||
return store
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getEnvironment() {
|
async function getEnvironment() {
|
||||||
let multiTenancyEnabled = false
|
const environment = await API.getEnvironment()
|
||||||
let cloud = false
|
|
||||||
let disableAccountPortal = false
|
|
||||||
let accountPortalUrl = ""
|
|
||||||
let isDev = false
|
|
||||||
try {
|
|
||||||
const environment = await API.getEnvironment()
|
|
||||||
multiTenancyEnabled = environment.multiTenancy
|
|
||||||
cloud = environment.cloud
|
|
||||||
disableAccountPortal = environment.disableAccountPortal
|
|
||||||
accountPortalUrl = environment.accountPortalUrl
|
|
||||||
isDev = environment.isDev
|
|
||||||
} catch (err) {
|
|
||||||
// Just let it stay disabled
|
|
||||||
}
|
|
||||||
admin.update(store => {
|
admin.update(store => {
|
||||||
store.multiTenancy = multiTenancyEnabled
|
store.multiTenancy = environment.multiTenancy
|
||||||
store.cloud = cloud
|
store.cloud = environment.cloud
|
||||||
store.disableAccountPortal = disableAccountPortal
|
store.disableAccountPortal = environment.disableAccountPortal
|
||||||
store.accountPortalUrl = accountPortalUrl
|
store.accountPortalUrl = environment.accountPortalUrl
|
||||||
store.isDev = isDev
|
store.isDev = environment.isDev
|
||||||
return store
|
return store
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { writable } from "svelte/store"
|
import { writable } from "svelte/store"
|
||||||
import { get } from "builderStore/api"
|
|
||||||
import { AppStatus } from "../../constants"
|
import { AppStatus } from "../../constants"
|
||||||
import api from "../../builderStore/api"
|
import { API } from "api"
|
||||||
|
|
||||||
const extractAppId = id => {
|
const extractAppId = id => {
|
||||||
const split = id?.split("_") || []
|
const split = id?.split("_") || []
|
||||||
|
@ -12,77 +11,67 @@ export function createAppStore() {
|
||||||
const store = writable([])
|
const store = writable([])
|
||||||
|
|
||||||
async function load() {
|
async function load() {
|
||||||
try {
|
const json = await API.getApps()
|
||||||
const res = await get(`/api/applications?status=all`)
|
if (Array.isArray(json)) {
|
||||||
const json = await res.json()
|
// Merge apps into one sensible list
|
||||||
if (res.ok && Array.isArray(json)) {
|
let appMap = {}
|
||||||
// Merge apps into one sensible list
|
let devApps = json.filter(app => app.status === AppStatus.DEV)
|
||||||
let appMap = {}
|
let deployedApps = json.filter(app => app.status === AppStatus.DEPLOYED)
|
||||||
let devApps = json.filter(app => app.status === AppStatus.DEV)
|
|
||||||
let deployedApps = json.filter(app => app.status === AppStatus.DEPLOYED)
|
|
||||||
|
|
||||||
// First append all dev app version
|
// First append all dev app version
|
||||||
devApps.forEach(app => {
|
devApps.forEach(app => {
|
||||||
const id = extractAppId(app.appId)
|
const id = extractAppId(app.appId)
|
||||||
appMap[id] = {
|
appMap[id] = {
|
||||||
...app,
|
...app,
|
||||||
devId: app.appId,
|
devId: app.appId,
|
||||||
devRev: app._rev,
|
devRev: app._rev,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Then merge with all prod app versions
|
// Then merge with all prod app versions
|
||||||
deployedApps.forEach(app => {
|
deployedApps.forEach(app => {
|
||||||
const id = extractAppId(app.appId)
|
const id = extractAppId(app.appId)
|
||||||
|
|
||||||
// Skip any deployed apps which don't have a dev counterpart
|
// Skip any deployed apps which don't have a dev counterpart
|
||||||
if (!appMap[id]) {
|
if (!appMap[id]) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
appMap[id] = {
|
appMap[id] = {
|
||||||
...appMap[id],
|
...appMap[id],
|
||||||
...app,
|
...app,
|
||||||
prodId: app.appId,
|
prodId: app.appId,
|
||||||
prodRev: app._rev,
|
prodRev: app._rev,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Transform into an array and clean up
|
// Transform into an array and clean up
|
||||||
const apps = Object.values(appMap)
|
const apps = Object.values(appMap)
|
||||||
apps.forEach(app => {
|
apps.forEach(app => {
|
||||||
app.appId = extractAppId(app.devId)
|
app.appId = extractAppId(app.devId)
|
||||||
delete app._id
|
delete app._id
|
||||||
delete app._rev
|
delete app._rev
|
||||||
})
|
})
|
||||||
store.set(apps)
|
store.set(apps)
|
||||||
} else {
|
} else {
|
||||||
store.set([])
|
|
||||||
}
|
|
||||||
return json
|
|
||||||
} catch (error) {
|
|
||||||
store.set([])
|
store.set([])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function update(appId, value) {
|
async function update(appId, value) {
|
||||||
console.log({ value })
|
await API.saveAppMetadata({
|
||||||
const response = await api.put(`/api/applications/${appId}`, { ...value })
|
appId,
|
||||||
if (response.status === 200) {
|
metadata: value,
|
||||||
store.update(state => {
|
})
|
||||||
const updatedAppIndex = state.findIndex(
|
store.update(state => {
|
||||||
app => app.instance._id === appId
|
const updatedAppIndex = state.findIndex(app => app.instance._id === appId)
|
||||||
)
|
if (updatedAppIndex !== -1) {
|
||||||
if (updatedAppIndex !== -1) {
|
let updatedApp = state[updatedAppIndex]
|
||||||
let updatedApp = state[updatedAppIndex]
|
updatedApp = { ...updatedApp, ...value }
|
||||||
updatedApp = { ...updatedApp, ...value }
|
state.apps = state.splice(updatedAppIndex, 1, updatedApp)
|
||||||
state.apps = state.splice(updatedAppIndex, 1, updatedApp)
|
}
|
||||||
}
|
return state
|
||||||
return state
|
})
|
||||||
})
|
|
||||||
} else {
|
|
||||||
throw new Error("Error updating name")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { derived, writable, get } from "svelte/store"
|
import { derived, writable, get } from "svelte/store"
|
||||||
import api from "../../builderStore/api"
|
import { API } from "api"
|
||||||
import { admin } from "stores/portal"
|
import { admin } from "stores/portal"
|
||||||
import analytics from "analytics"
|
import analytics from "analytics"
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ export function createAuthStore() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setInitInfo(info) {
|
async function setInitInfo(info) {
|
||||||
await api.post(`/api/global/auth/init`, info)
|
await API.setInitInfo(info)
|
||||||
auth.update(store => {
|
auth.update(store => {
|
||||||
store.initInfo = info
|
store.initInfo = info
|
||||||
return store
|
return store
|
||||||
|
@ -99,13 +99,12 @@ export function createAuthStore() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getInitInfo() {
|
async function getInitInfo() {
|
||||||
const response = await api.get(`/api/global/auth/init`)
|
const info = await API.getInitInfo()
|
||||||
const json = response.json()
|
|
||||||
auth.update(store => {
|
auth.update(store => {
|
||||||
store.initInfo = json
|
store.initInfo = info
|
||||||
return store
|
return store
|
||||||
})
|
})
|
||||||
return json
|
return info
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -124,77 +123,43 @@ export function createAuthStore() {
|
||||||
await setOrganisation(tenantId)
|
await setOrganisation(tenantId)
|
||||||
},
|
},
|
||||||
checkAuth: async () => {
|
checkAuth: async () => {
|
||||||
const response = await api.get("/api/global/users/self")
|
const user = await API.fetchBuilderSelf()
|
||||||
if (response.status !== 200) {
|
setUser(user)
|
||||||
setUser(null)
|
|
||||||
} else {
|
|
||||||
const json = await response.json()
|
|
||||||
setUser(json)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
login: async creds => {
|
login: async creds => {
|
||||||
const tenantId = get(store).tenantId
|
const tenantId = get(store).tenantId
|
||||||
const response = await api.post(
|
const response = await API.logIn({
|
||||||
`/api/global/auth/${tenantId}/login`,
|
username: creds.username,
|
||||||
creds
|
password: creds.password,
|
||||||
)
|
tenantId,
|
||||||
const json = await response.json()
|
})
|
||||||
if (response.status === 200) {
|
setUser(response.user)
|
||||||
setUser(json.user)
|
|
||||||
} else {
|
|
||||||
throw new Error(json.message ? json.message : "Invalid credentials")
|
|
||||||
}
|
|
||||||
return json
|
|
||||||
},
|
},
|
||||||
logout: async () => {
|
logout: async () => {
|
||||||
const response = await api.post(`/api/global/auth/logout`)
|
await API.logOut()
|
||||||
if (response.status !== 200) {
|
|
||||||
throw "Unable to create logout"
|
|
||||||
}
|
|
||||||
await response.json()
|
|
||||||
await setInitInfo({})
|
await setInitInfo({})
|
||||||
setUser(null)
|
setUser(null)
|
||||||
setPostLogout()
|
setPostLogout()
|
||||||
},
|
},
|
||||||
updateSelf: async fields => {
|
updateSelf: async fields => {
|
||||||
const newUser = { ...get(auth).user, ...fields }
|
const newUser = { ...get(auth).user, ...fields }
|
||||||
const response = await api.post("/api/global/users/self", newUser)
|
await API.updateSelf(newUser)
|
||||||
if (response.status === 200) {
|
setUser(newUser)
|
||||||
setUser(newUser)
|
|
||||||
} else {
|
|
||||||
throw "Unable to update user details"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
forgotPassword: async email => {
|
forgotPassword: async email => {
|
||||||
const tenantId = get(store).tenantId
|
const tenantId = get(store).tenantId
|
||||||
const response = await api.post(`/api/global/auth/${tenantId}/reset`, {
|
await API.requestForgotPassword({
|
||||||
|
tenantId,
|
||||||
email,
|
email,
|
||||||
})
|
})
|
||||||
if (response.status !== 200) {
|
|
||||||
throw "Unable to send email with reset link"
|
|
||||||
}
|
|
||||||
await response.json()
|
|
||||||
},
|
},
|
||||||
resetPassword: async (password, code) => {
|
resetPassword: async (password, resetCode) => {
|
||||||
const tenantId = get(store).tenantId
|
const tenantId = get(store).tenantId
|
||||||
const response = await api.post(
|
await API.resetPassword({
|
||||||
`/api/global/auth/${tenantId}/reset/update`,
|
tenantId,
|
||||||
{
|
password,
|
||||||
password,
|
resetCode,
|
||||||
resetCode: code,
|
})
|
||||||
}
|
|
||||||
)
|
|
||||||
if (response.status !== 200) {
|
|
||||||
throw "Unable to reset password"
|
|
||||||
}
|
|
||||||
await response.json()
|
|
||||||
},
|
|
||||||
createUser: async user => {
|
|
||||||
const response = await api.post(`/api/global/users`, user)
|
|
||||||
if (response.status !== 200) {
|
|
||||||
throw "Unable to create user"
|
|
||||||
}
|
|
||||||
await response.json()
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { writable } from "svelte/store"
|
import { writable } from "svelte/store"
|
||||||
import { API } from "api"
|
import { API } from "api"
|
||||||
import { notifications } from "@budibase/bbui"
|
|
||||||
|
|
||||||
export function createEmailStore() {
|
export function createEmailStore() {
|
||||||
const store = writable({})
|
const store = writable({})
|
||||||
|
@ -9,35 +8,26 @@ export function createEmailStore() {
|
||||||
subscribe: store.subscribe,
|
subscribe: store.subscribe,
|
||||||
templates: {
|
templates: {
|
||||||
fetch: async () => {
|
fetch: async () => {
|
||||||
try {
|
// Fetch the email template definitions and templates
|
||||||
// fetch the email template definitions and templates
|
const definitions = await API.getEmailTemplateDefinitions()
|
||||||
const definitions = await API.getEmailTemplateDefinitions()
|
const templates = await API.getEmailTemplates()
|
||||||
const templates = await API.getEmailTemplates()
|
store.set({
|
||||||
store.set({
|
definitions,
|
||||||
definitions,
|
templates,
|
||||||
templates,
|
})
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
notifications.error("Error fetching email templates")
|
|
||||||
store.set({})
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
save: async template => {
|
save: async template => {
|
||||||
try {
|
// Save your template config
|
||||||
// Save your template config
|
const savedTemplate = await API.saveEmailTemplate(template)
|
||||||
const savedTemplate = await API.saveEmailTemplate(template)
|
template._rev = savedTemplate._rev
|
||||||
template._rev = savedTemplate._rev
|
template._id = savedTemplate._id
|
||||||
template._id = savedTemplate._id
|
store.update(state => {
|
||||||
store.update(state => {
|
const currentIdx = state.templates.findIndex(
|
||||||
const currentIdx = state.templates.findIndex(
|
template => template.purpose === savedTemplate.purpose
|
||||||
template => template.purpose === savedTemplate.purpose
|
)
|
||||||
)
|
state.templates.splice(currentIdx, 1, template)
|
||||||
state.templates.splice(currentIdx, 1, template)
|
return state
|
||||||
return state
|
})
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
notifications.error("Error saving email template")
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,10 +11,11 @@ const OIDC_CONFIG = {
|
||||||
export function createOidcStore() {
|
export function createOidcStore() {
|
||||||
const store = writable(OIDC_CONFIG)
|
const store = writable(OIDC_CONFIG)
|
||||||
const { set, subscribe } = store
|
const { set, subscribe } = store
|
||||||
|
return {
|
||||||
async function init() {
|
subscribe,
|
||||||
const tenantId = get(auth).tenantId
|
set,
|
||||||
try {
|
init: async () => {
|
||||||
|
const tenantId = get(auth).tenantId
|
||||||
const config = await API.getOIDCConfig(tenantId)
|
const config = await API.getOIDCConfig(tenantId)
|
||||||
if (Object.keys(config || {}).length) {
|
if (Object.keys(config || {}).length) {
|
||||||
// Just use the first config for now.
|
// Just use the first config for now.
|
||||||
|
@ -23,15 +24,7 @@ export function createOidcStore() {
|
||||||
} else {
|
} else {
|
||||||
set(OIDC_CONFIG)
|
set(OIDC_CONFIG)
|
||||||
}
|
}
|
||||||
} catch (error) {
|
},
|
||||||
set(OIDC_CONFIG)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
subscribe,
|
|
||||||
set,
|
|
||||||
init,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { writable, get } from "svelte/store"
|
import { writable, get } from "svelte/store"
|
||||||
import api from "builderStore/api"
|
import { API } from "api"
|
||||||
import { auth } from "stores/portal"
|
import { auth } from "stores/portal"
|
||||||
|
|
||||||
const DEFAULT_CONFIG = {
|
const DEFAULT_CONFIG = {
|
||||||
|
@ -19,35 +19,23 @@ export function createOrganisationStore() {
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
const tenantId = get(auth).tenantId
|
const tenantId = get(auth).tenantId
|
||||||
const res = await api.get(`/api/global/configs/public?tenantId=${tenantId}`)
|
const tenant = await API.getTenantConfig(tenantId)
|
||||||
const json = await res.json()
|
set({ ...DEFAULT_CONFIG, ...tenant.config, _rev: tenant._rev })
|
||||||
|
|
||||||
if (json.status === 400) {
|
|
||||||
set(DEFAULT_CONFIG)
|
|
||||||
} else {
|
|
||||||
set({ ...DEFAULT_CONFIG, ...json.config, _rev: json._rev })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function save(config) {
|
async function save(config) {
|
||||||
// delete non-persisted fields
|
// Delete non-persisted fields
|
||||||
const storeConfig = get(store)
|
const storeConfig = get(store)
|
||||||
delete storeConfig.oidc
|
delete storeConfig.oidc
|
||||||
delete storeConfig.google
|
delete storeConfig.google
|
||||||
delete storeConfig.oidcCallbackUrl
|
delete storeConfig.oidcCallbackUrl
|
||||||
delete storeConfig.googleCallbackUrl
|
delete storeConfig.googleCallbackUrl
|
||||||
|
await API.saveConfig({
|
||||||
const res = await api.post("/api/global/configs", {
|
|
||||||
type: "settings",
|
type: "settings",
|
||||||
config: { ...get(store), ...config },
|
config: { ...get(store), ...config },
|
||||||
_rev: get(store)._rev,
|
_rev: get(store)._rev,
|
||||||
})
|
})
|
||||||
const json = await res.json()
|
|
||||||
if (json.status) {
|
|
||||||
return json
|
|
||||||
}
|
|
||||||
await init()
|
await init()
|
||||||
return { status: 200 }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,18 +1,15 @@
|
||||||
import { writable } from "svelte/store"
|
import { writable } from "svelte/store"
|
||||||
import api from "builderStore/api"
|
import { API } from "api"
|
||||||
|
|
||||||
export function templatesStore() {
|
export function templatesStore() {
|
||||||
const { subscribe, set } = writable([])
|
const { subscribe, set } = writable([])
|
||||||
|
|
||||||
async function load() {
|
|
||||||
const response = await api.get("/api/templates?type=app")
|
|
||||||
const json = await response.json()
|
|
||||||
set(json)
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
subscribe,
|
subscribe,
|
||||||
load,
|
load: async () => {
|
||||||
|
const templates = await API.getAppTemplates()
|
||||||
|
set(templates)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,38 +1,28 @@
|
||||||
import { writable } from "svelte/store"
|
import { writable } from "svelte/store"
|
||||||
import api, { post } from "builderStore/api"
|
import { API } from "api"
|
||||||
import { update } from "lodash"
|
import { update } from "lodash"
|
||||||
|
|
||||||
export function createUsersStore() {
|
export function createUsersStore() {
|
||||||
const { subscribe, set } = writable([])
|
const { subscribe, set } = writable([])
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
const response = await api.get(`/api/global/users`)
|
const users = await API.getUsers()
|
||||||
const json = await response.json()
|
set(users)
|
||||||
set(json)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function invite({ email, builder, admin }) {
|
async function invite({ email, builder, admin }) {
|
||||||
const body = { email, userInfo: {} }
|
await API.inviteUser({
|
||||||
if (admin) {
|
email,
|
||||||
body.userInfo.admin = {
|
builder,
|
||||||
global: true,
|
admin,
|
||||||
}
|
})
|
||||||
}
|
|
||||||
if (builder) {
|
|
||||||
body.userInfo.builder = {
|
|
||||||
global: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const response = await api.post(`/api/global/users/invite`, body)
|
|
||||||
return await response.json()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function acceptInvite(inviteCode, password) {
|
async function acceptInvite(inviteCode, password) {
|
||||||
const response = await api.post("/api/global/users/invite/accept", {
|
await API.acceptInvite({
|
||||||
inviteCode,
|
inviteCode,
|
||||||
password,
|
password,
|
||||||
})
|
})
|
||||||
return await response.json()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function create({
|
async function create({
|
||||||
|
@ -56,29 +46,17 @@ export function createUsersStore() {
|
||||||
if (admin) {
|
if (admin) {
|
||||||
body.admin = { global: true }
|
body.admin = { global: true }
|
||||||
}
|
}
|
||||||
const response = await api.post("/api/global/users", body)
|
await API.saveUser(body)
|
||||||
await init()
|
await init()
|
||||||
return await response.json()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function del(id) {
|
async function del(id) {
|
||||||
const response = await api.delete(`/api/global/users/${id}`)
|
await API.deleteUser(id)
|
||||||
update(users => users.filter(user => user._id !== id))
|
update(users => users.filter(user => user._id !== id))
|
||||||
const json = await response.json()
|
|
||||||
return {
|
|
||||||
...json,
|
|
||||||
status: response.status,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function save(data) {
|
async function save(data) {
|
||||||
try {
|
await API.saveUser(data)
|
||||||
const res = await post(`/api/global/users`, data)
|
|
||||||
return await res.json()
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error)
|
|
||||||
return error
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -10,14 +10,12 @@ export const buildAppEndpoints = API => ({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves and patches metadata about an app.
|
* Saves and patches metadata about an app.
|
||||||
|
* @param appId the ID of the app to update
|
||||||
* @param metadata the app metadata to save
|
* @param metadata the app metadata to save
|
||||||
*/
|
*/
|
||||||
saveAppMetadata: async metadata => {
|
saveAppMetadata: async ({ appId, metadata }) => {
|
||||||
if (!metadata?.appId) {
|
|
||||||
throw API.error("App metadata must have an appId set")
|
|
||||||
}
|
|
||||||
return await API.put({
|
return await API.put({
|
||||||
url: `/api/applications/${metadata.appId}`,
|
url: `/api/applications/${appId}`,
|
||||||
body: metadata,
|
body: metadata,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -132,4 +130,13 @@ export const buildAppEndpoints = API => ({
|
||||||
url: `/api/applications/${appId}/sync`,
|
url: `/api/applications/${appId}/sync`,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a list of apps.
|
||||||
|
*/
|
||||||
|
getApps: async () => {
|
||||||
|
return await API.get({
|
||||||
|
url: "/api/applications?status=all",
|
||||||
|
})
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,18 +1,15 @@
|
||||||
export const buildAuthEndpoints = API => ({
|
export const buildAuthEndpoints = API => ({
|
||||||
/**
|
/**
|
||||||
* Performs a log in request.
|
* Performs a login request.
|
||||||
|
* @param tenantId the ID of the tenant to log in to
|
||||||
|
* @param username the username (email)
|
||||||
|
* @param password the password
|
||||||
*/
|
*/
|
||||||
logIn: async ({ email, password }) => {
|
logIn: async ({ tenantId, username, password }) => {
|
||||||
if (!email) {
|
|
||||||
return API.error("Please enter your email")
|
|
||||||
}
|
|
||||||
if (!password) {
|
|
||||||
return API.error("Please enter your password")
|
|
||||||
}
|
|
||||||
return await API.post({
|
return await API.post({
|
||||||
url: "/api/global/auth",
|
url: `/api/global/auth/${tenantId}/login`,
|
||||||
body: {
|
body: {
|
||||||
username: email,
|
username,
|
||||||
password,
|
password,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -28,137 +25,52 @@ export const buildAuthEndpoints = API => ({
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches the currently logged in user object
|
* Sets initialisation info.
|
||||||
|
* @param info the info to set
|
||||||
*/
|
*/
|
||||||
fetchSelf: async () => {
|
setInitInfo: async info => {
|
||||||
return await API.get({
|
|
||||||
url: "/api/self",
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a user for an app.
|
|
||||||
* @param user the user to create
|
|
||||||
*/
|
|
||||||
createAppUser: async user => {
|
|
||||||
return await API.post({
|
return await API.post({
|
||||||
url: "/api/users/metadata",
|
url: "/api/global/auth/init",
|
||||||
body: user,
|
body: info,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the current user metadata.
|
* Gets the initialisation info.
|
||||||
* @param metadata the metadata to save
|
|
||||||
*/
|
*/
|
||||||
updateOwnMetadata: async metadata => {
|
getInitInfo: async () => {
|
||||||
|
return await API.get({
|
||||||
|
url: "/api/global/auth/init",
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a password reset email.
|
||||||
|
* @param tenantId the ID of the tenant the user is in
|
||||||
|
* @param email the email address of the user
|
||||||
|
*/
|
||||||
|
requestForgotPassword: async ({ tenantId, email }) => {
|
||||||
return await API.post({
|
return await API.post({
|
||||||
url: "/api/users/metadata/self",
|
url: `/api/global/auth/${tenantId}/reset`,
|
||||||
body: metadata,
|
body: {
|
||||||
|
email,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an admin user.
|
* Resets a user's password.
|
||||||
* @param adminUser the admin user to create
|
* @param tenantId the ID of the tenant the user is in
|
||||||
|
* @param password the new password to set
|
||||||
|
* @param resetCode the reset code to authenticate the request
|
||||||
*/
|
*/
|
||||||
createAdminUser: async adminUser => {
|
resetPassword: async ({ tenantId, password, resetCode }) => {
|
||||||
return await API.post({
|
return await API.post({
|
||||||
url: "/api/global/users/init",
|
url: `/api/global/auth/${tenantId}/reset/update`,
|
||||||
body: adminUser,
|
body: {
|
||||||
})
|
password,
|
||||||
},
|
resetCode,
|
||||||
|
},
|
||||||
/**
|
|
||||||
* Saves a global config.
|
|
||||||
* @param config the config to save
|
|
||||||
*/
|
|
||||||
saveConfig: async config => {
|
|
||||||
return await API.post({
|
|
||||||
url: "/api/global/configs",
|
|
||||||
body: config,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a global config of a certain type.
|
|
||||||
* @param type the type to fetch
|
|
||||||
*/
|
|
||||||
getConfig: async type => {
|
|
||||||
return await API.get({
|
|
||||||
url: `/api/global/configs/${type}`,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the OIDC config for a certain tenant.
|
|
||||||
* @param tenantId the tenant ID to get the config for
|
|
||||||
*/
|
|
||||||
getOIDCConfig: async tenantId => {
|
|
||||||
return await API.get({
|
|
||||||
url: `/api/global/configs/public/oidc?tenantId=${tenantId}`,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the checklist for a specific tenant.
|
|
||||||
* @param tenantId the tenant ID to get the checklist for
|
|
||||||
*/
|
|
||||||
getChecklist: async tenantId => {
|
|
||||||
return await API.get({
|
|
||||||
url: `/api/global/configs/checklist?tenantId=${tenantId}`,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: find out what this is
|
|
||||||
*/
|
|
||||||
checkImportComplete: async () => {
|
|
||||||
return await API.get({
|
|
||||||
url: "/api/cloud/import/complete",
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the current environment details.
|
|
||||||
*/
|
|
||||||
getEnvironment: async () => {
|
|
||||||
return await API.get({
|
|
||||||
url: "/api/system/environment",
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the company logo for the environment.
|
|
||||||
* @param data the logo form data
|
|
||||||
*/
|
|
||||||
uploadLogo: async data => {
|
|
||||||
return await API.post({
|
|
||||||
url: "/api/global/configs/upload/settings/logoUrl",
|
|
||||||
body: data,
|
|
||||||
json: false,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Uploads a logo for an OIDC provider.
|
|
||||||
* @param name the name of the OIDC provider
|
|
||||||
* @param data the logo form data to upload
|
|
||||||
*/
|
|
||||||
uploadOIDCLogo: async ({ name, data }) => {
|
|
||||||
return await API.post({
|
|
||||||
url: `/api/global/configs/upload/logos_oidc/${name}`,
|
|
||||||
body: data,
|
|
||||||
json: false,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the list of OIDC logos.
|
|
||||||
*/
|
|
||||||
getOIDCLogos: async () => {
|
|
||||||
return await API.get({
|
|
||||||
url: "/api/global/configs/logos_oidc",
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
export const buildConfigEndpoints = API => ({
|
||||||
|
/**
|
||||||
|
* Saves a global config.
|
||||||
|
* @param config the config to save
|
||||||
|
*/
|
||||||
|
saveConfig: async config => {
|
||||||
|
return await API.post({
|
||||||
|
url: "/api/global/configs",
|
||||||
|
body: config,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a global config of a certain type.
|
||||||
|
* @param type the type to fetch
|
||||||
|
*/
|
||||||
|
getConfig: async type => {
|
||||||
|
return await API.get({
|
||||||
|
url: `/api/global/configs/${type}`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the config for a certain tenant.
|
||||||
|
* @param tenantId the tenant ID to get the config for
|
||||||
|
*/
|
||||||
|
getTenantConfig: async tenantId => {
|
||||||
|
return await API.get({
|
||||||
|
url: `/api/global/configs/public?tenantId=${tenantId}`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the OIDC config for a certain tenant.
|
||||||
|
* @param tenantId the tenant ID to get the config for
|
||||||
|
*/
|
||||||
|
getOIDCConfig: async tenantId => {
|
||||||
|
return await API.get({
|
||||||
|
url: `/api/global/configs/public/oidc?tenantId=${tenantId}`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the checklist for a specific tenant.
|
||||||
|
* @param tenantId the tenant ID to get the checklist for
|
||||||
|
*/
|
||||||
|
getChecklist: async tenantId => {
|
||||||
|
return await API.get({
|
||||||
|
url: `/api/global/configs/checklist?tenantId=${tenantId}`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the company logo for the environment.
|
||||||
|
* @param data the logo form data
|
||||||
|
*/
|
||||||
|
uploadLogo: async data => {
|
||||||
|
return await API.post({
|
||||||
|
url: "/api/global/configs/upload/settings/logoUrl",
|
||||||
|
body: data,
|
||||||
|
json: false,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uploads a logo for an OIDC provider.
|
||||||
|
* @param name the name of the OIDC provider
|
||||||
|
* @param data the logo form data to upload
|
||||||
|
*/
|
||||||
|
uploadOIDCLogo: async ({ name, data }) => {
|
||||||
|
return await API.post({
|
||||||
|
url: `/api/global/configs/upload/logos_oidc/${name}`,
|
||||||
|
body: data,
|
||||||
|
json: false,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list of OIDC logos.
|
||||||
|
*/
|
||||||
|
getOIDCLogos: async () => {
|
||||||
|
return await API.get({
|
||||||
|
url: "/api/global/configs/logos_oidc",
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
|
@ -4,9 +4,11 @@ import { buildAppEndpoints } from "./app"
|
||||||
import { buildAttachmentEndpoints } from "./attachments"
|
import { buildAttachmentEndpoints } from "./attachments"
|
||||||
import { buildAuthEndpoints } from "./auth"
|
import { buildAuthEndpoints } from "./auth"
|
||||||
import { buildAutomationEndpoints } from "./automations"
|
import { buildAutomationEndpoints } from "./automations"
|
||||||
|
import { buildConfigEndpoints } from "./configs"
|
||||||
import { buildDatasourceEndpoints } from "./datasources"
|
import { buildDatasourceEndpoints } from "./datasources"
|
||||||
import { buildFlagEndpoints } from "./flags"
|
import { buildFlagEndpoints } from "./flags"
|
||||||
import { buildHostingEndpoints } from "./hosting"
|
import { buildHostingEndpoints } from "./hosting"
|
||||||
|
import { buildOtherEndpoints } from "./other"
|
||||||
import { buildPermissionsEndpoints } from "./permissions"
|
import { buildPermissionsEndpoints } from "./permissions"
|
||||||
import { buildQueryEndpoints } from "./queries"
|
import { buildQueryEndpoints } from "./queries"
|
||||||
import { buildRelationshipEndpoints } from "./relationships"
|
import { buildRelationshipEndpoints } from "./relationships"
|
||||||
|
@ -16,6 +18,7 @@ import { buildRowEndpoints } from "./rows"
|
||||||
import { buildScreenEndpoints } from "./screens"
|
import { buildScreenEndpoints } from "./screens"
|
||||||
import { buildTableEndpoints } from "./tables"
|
import { buildTableEndpoints } from "./tables"
|
||||||
import { buildTemplateEndpoints } from "./templates"
|
import { buildTemplateEndpoints } from "./templates"
|
||||||
|
import { buildUserEndpoints } from "./user"
|
||||||
import { buildViewEndpoints } from "./views"
|
import { buildViewEndpoints } from "./views"
|
||||||
|
|
||||||
const defaultAPIClientConfig = {
|
const defaultAPIClientConfig = {
|
||||||
|
@ -189,9 +192,11 @@ export const createAPIClient = config => {
|
||||||
...buildAttachmentEndpoints(API),
|
...buildAttachmentEndpoints(API),
|
||||||
...buildAuthEndpoints(API),
|
...buildAuthEndpoints(API),
|
||||||
...buildAutomationEndpoints(API),
|
...buildAutomationEndpoints(API),
|
||||||
|
...buildConfigEndpoints(API),
|
||||||
...buildDatasourceEndpoints(API),
|
...buildDatasourceEndpoints(API),
|
||||||
...buildFlagEndpoints(API),
|
...buildFlagEndpoints(API),
|
||||||
...buildHostingEndpoints(API),
|
...buildHostingEndpoints(API),
|
||||||
|
...buildOtherEndpoints(API),
|
||||||
...buildPermissionsEndpoints(API),
|
...buildPermissionsEndpoints(API),
|
||||||
...buildQueryEndpoints(API),
|
...buildQueryEndpoints(API),
|
||||||
...buildRelationshipEndpoints(API),
|
...buildRelationshipEndpoints(API),
|
||||||
|
@ -201,6 +206,7 @@ export const createAPIClient = config => {
|
||||||
...buildScreenEndpoints(API),
|
...buildScreenEndpoints(API),
|
||||||
...buildTableEndpoints(API),
|
...buildTableEndpoints(API),
|
||||||
...buildTemplateEndpoints(API),
|
...buildTemplateEndpoints(API),
|
||||||
|
...buildUserEndpoints(API),
|
||||||
...buildViewEndpoints(API),
|
...buildViewEndpoints(API),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
export const buildOtherEndpoints = API => ({
|
||||||
|
/**
|
||||||
|
* TODO: find out what this is
|
||||||
|
*/
|
||||||
|
checkImportComplete: async () => {
|
||||||
|
return await API.get({
|
||||||
|
url: "/api/cloud/import/complete",
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current environment details.
|
||||||
|
*/
|
||||||
|
getEnvironment: async () => {
|
||||||
|
return await API.get({
|
||||||
|
url: "/api/system/environment",
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
|
@ -25,4 +25,13 @@ export const buildTemplateEndpoints = API => ({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a list of app templates.
|
||||||
|
*/
|
||||||
|
getAppTemplates: async () => {
|
||||||
|
return await API.get({
|
||||||
|
url: "/api/templates?type=app",
|
||||||
|
})
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
export const buildUserEndpoints = API => ({
|
||||||
|
/**
|
||||||
|
* Fetches the currently logged-in user object.
|
||||||
|
* Used in client apps.
|
||||||
|
*/
|
||||||
|
fetchSelf: async () => {
|
||||||
|
return await API.get({
|
||||||
|
url: "/api/self",
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches the currently logged-in user object.
|
||||||
|
* Used in the builder.
|
||||||
|
*/
|
||||||
|
fetchBuilderSelf: async () => {
|
||||||
|
return await API.get({
|
||||||
|
url: "/api/global/users/self",
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a list of users in the current tenant.
|
||||||
|
*/
|
||||||
|
getUsers: async () => {
|
||||||
|
return await API.get({
|
||||||
|
url: "/api/global/users",
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a user for an app.
|
||||||
|
* @param user the user to create
|
||||||
|
*/
|
||||||
|
createAppUser: async user => {
|
||||||
|
return await API.post({
|
||||||
|
url: "/api/users/metadata",
|
||||||
|
body: user,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the current user metadata.
|
||||||
|
* @param metadata the metadata to save
|
||||||
|
*/
|
||||||
|
updateOwnMetadata: async metadata => {
|
||||||
|
return await API.post({
|
||||||
|
url: "/api/users/metadata/self",
|
||||||
|
body: metadata,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an admin user.
|
||||||
|
* @param adminUser the admin user to create
|
||||||
|
*/
|
||||||
|
createAdminUser: async adminUser => {
|
||||||
|
return await API.post({
|
||||||
|
url: "/api/global/users/init",
|
||||||
|
body: adminUser,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the current logged-in user.
|
||||||
|
* @param user the new user object to save
|
||||||
|
*/
|
||||||
|
updateSelf: async user => {
|
||||||
|
return await API.post({
|
||||||
|
url: "/api/global/users/self",
|
||||||
|
body: user,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates or updates a user in the current tenant.
|
||||||
|
* @param user the new user to create
|
||||||
|
*/
|
||||||
|
saveUser: async user => {
|
||||||
|
return await API.post({
|
||||||
|
url: "/api/global/users",
|
||||||
|
body: user,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a user from the curernt tenant.
|
||||||
|
* @param userId the ID of the user to delete
|
||||||
|
*/
|
||||||
|
deleteUser: async userId => {
|
||||||
|
return await API.delete({
|
||||||
|
url: `/api/global/users/${userId}`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invites a user to the current tenant.
|
||||||
|
* @param email the email address to send the invitation to
|
||||||
|
* @param builder whether the user should be a global builder
|
||||||
|
* @param admin whether the user should be a global admin
|
||||||
|
*/
|
||||||
|
inviteUser: async ({ email, builder, admin }) => {
|
||||||
|
return await API.post({
|
||||||
|
url: "/api/global/users/invite",
|
||||||
|
body: {
|
||||||
|
email,
|
||||||
|
userInfo: {
|
||||||
|
admin: admin ? { global: true } : undefined,
|
||||||
|
builder: builder ? { global: true } : undefined,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accepts an invitation to join the platform and creates a user.
|
||||||
|
* @param inviteCode the invite code sent in the email
|
||||||
|
* @param password the password for the newly created user
|
||||||
|
*/
|
||||||
|
acceptInvitation: async ({ inviteCode, password }) => {
|
||||||
|
return await API.post({
|
||||||
|
url: "/api/global/users/invite/accept",
|
||||||
|
body: {
|
||||||
|
inviteCode,
|
||||||
|
password,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
Loading…
Reference in New Issue