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