1
0
Fork 0
mirror of synced 2024-09-21 11:53:49 +12:00
budibase/packages/builder/src/components/start/CreateAppModal.svelte

213 lines
6.1 KiB
Svelte
Raw Normal View History

<script>
import { writable, get as svelteGet } from "svelte/store"
import {
notifications,
Input,
ModalContent,
Dropzone,
Body,
Checkbox,
} from "@budibase/bbui"
import { store, automationStore, hostingStore } from "builderStore"
import { string, mixed, object } from "yup"
2020-08-04 02:26:28 +12:00
import api, { get } from "builderStore/api"
import { post } from "builderStore/api"
import analytics from "analytics"
2021-01-07 06:28:22 +13:00
import { onMount } from "svelte"
import { capitalise } from "helpers"
2021-05-08 00:13:51 +12:00
import { goto } from "@roxi/routify"
2020-05-27 22:54:53 +12:00
2020-09-26 01:47:42 +12:00
export let template
2020-05-27 22:54:53 +12:00
const values = writable({ name: null })
const errors = writable({})
const touched = writable({})
const validator = {
name: string().required("Your application must have a name"),
file: mixed().required("Please choose a file to import"),
}
2020-08-04 01:59:50 +12:00
let submitting = false
let valid = false
$: checkValidity($values, validator)
onMount(async () => {
await hostingStore.actions.fetchDeployedApps()
const existingAppNames = svelteGet(hostingStore).deployedAppNames
validator.name = string()
.required("Your application must have a name")
.test(
"non-existing-app-name",
"Another app with the same name already exists",
value => {
return !existingAppNames.some(
appName => appName.toLowerCase() === value.toLowerCase()
)
}
)
})
2020-08-04 01:59:50 +12:00
const checkValidity = async (values, validator) => {
const obj = object().shape(validator)
2021-05-04 22:32:22 +12:00
Object.keys(validator).forEach(key => ($errors[key] = null))
2020-08-04 01:59:50 +12:00
try {
await obj.validate(values, { abortEarly: false })
} catch (validationErrors) {
2021-05-04 22:32:22 +12:00
validationErrors.inner.forEach(error => {
$errors[error.path] = capitalise(error.message)
})
2020-08-04 01:59:50 +12:00
}
valid = await obj.isValid(values)
2020-08-04 01:59:50 +12:00
}
async function createNewApp() {
2020-08-04 01:59:50 +12:00
submitting = true
// Check a template exists if we are important
if (template && !$values.file) {
$errors.file = "Please choose a file to import"
valid = false
submitting = false
return false
}
2020-08-04 01:59:50 +12:00
try {
2021-03-16 07:32:20 +13:00
// Create form data to create app
let data = new FormData()
data.append("name", $values.name)
2021-03-16 07:32:20 +13:00
data.append("useTemplate", template != null)
if (template) {
data.append("templateName", template.name)
data.append("templateKey", template.key)
data.append("templateFile", $values.file)
2021-03-16 07:32:20 +13:00
}
2020-08-04 02:26:28 +12:00
// Create App
2021-03-16 07:32:20 +13:00
const appResp = await post("/api/applications", data, {})
2020-08-04 02:26:28 +12:00
const appJson = await appResp.json()
2021-02-24 07:37:37 +13:00
if (!appResp.ok) {
throw new Error(appJson.message)
}
analytics.captureEvent("App Created", {
name: $values.name,
2020-08-04 02:26:28 +12:00
appId: appJson._id,
2020-09-26 01:47:42 +12:00
template,
2020-08-04 01:59:50 +12:00
})
2020-08-04 02:26:28 +12:00
// Select Correct Application/DB in prep for creating user
2020-11-20 05:56:23 +13:00
const applicationPkg = await get(
`/api/applications/${appJson._id}/appPackage`
)
2020-08-04 02:26:28 +12:00
const pkg = await applicationPkg.json()
if (applicationPkg.ok) {
2020-11-05 06:09:45 +13:00
await store.actions.initialise(pkg)
2020-11-25 07:11:34 +13:00
await automationStore.actions.fetch()
2020-08-04 02:26:28 +12:00
} else {
throw new Error(pkg)
}
// Create user
const user = {
roleId: $values.roleId,
2020-08-04 02:26:28 +12:00
}
const userResp = await api.post(`/api/users/metadata/self`, user)
await userResp.json()
2021-05-08 00:13:51 +12:00
$goto(`/builder/app/${appJson._id}`)
2020-08-04 01:59:50 +12:00
} catch (error) {
console.error(error)
notifications.error(error)
2021-02-24 07:37:37 +13:00
submitting = false
2020-05-27 21:44:15 +12:00
}
}
2020-05-27 02:25:37 +12:00
</script>
<ModalContent
title={template ? "Import app" : "Create new app"}
confirmText={template ? "Import app" : "Create app"}
onConfirm={createNewApp}
disabled={!valid}
>
{#if template}
<Dropzone
error={$touched.file && $errors.file}
gallery={false}
label="File to import"
value={[$values.file]}
on:change={e => {
$values.file = e.detail?.[0]
$touched.file = true
}}
/>
2020-10-08 21:35:11 +13:00
{/if}
<Body size="S">
Give your new app a name, and choose which groups have access (paid plans
only).
</Body>
<Input
bind:value={$values.name}
error={$touched.name && $errors.name}
on:blur={() => ($touched.name = true)}
label="Name"
/>
<Checkbox label="Group access" disabled value={true} text="All users" />
</ModalContent>
2020-08-04 01:59:50 +12:00
<!--<div class="container">-->
<!-- <div class="sidebar">-->
<!-- <img src={Logo} alt="budibase icon" />-->
<!-- <div class="steps">-->
<!-- {#each steps as component, i}-->
<!-- <Indicator-->
<!-- active={$currentStep === i}-->
<!-- done={i < $currentStep}-->
<!-- step={i + 1}-->
<!-- />-->
<!-- {/each}-->
<!-- </div>-->
<!-- </div>-->
<!-- <div class="body">-->
<!-- <div class="heading">-->
<!-- <Heading size="L">Get started with Budibase</Heading>-->
<!-- </div>-->
<!-- <div class="step">-->
<!-- {#each steps as component, i (i)}-->
<!-- <div class:hidden={$currentStep !== i}>-->
<!-- <svelte:component-->
<!-- this={component}-->
<!-- {template}-->
<!-- {values}-->
<!-- {errors}-->
<!-- {touched}-->
<!-- />-->
<!-- </div>-->
<!-- {/each}-->
<!-- </div>-->
<!-- <div class="footer">-->
<!-- {#if $currentStep > 0}-->
<!-- <Button medium secondary on:click={() => $currentStep&#45;&#45;}>Back</Button>-->
<!-- {/if}-->
<!-- {#if $currentStep < steps.length - 1}-->
<!-- <Button medium cta on:click={() => $currentStep++} disabled={!valid}>-->
<!-- Next-->
<!-- </Button>-->
<!-- {/if}-->
<!-- {#if $currentStep === steps.length - 1}-->
<!-- <Button-->
<!-- medium-->
<!-- cta-->
<!-- on:click={createNewApp}-->
<!-- disabled={!valid || submitting}-->
<!-- >-->
<!-- {submitting ? "Loading..." : "Submit"}-->
<!-- </Button>-->
<!-- {/if}-->
<!-- </div>-->
<!-- </div>-->
<!-- {#if submitting}-->
<!-- <div in:fade class="spinner-container">-->
<!-- <Spinner />-->
<!-- <span class="spinner-text">Creating your app...</span>-->
<!-- </div>-->
<!-- {/if}-->