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

184 lines
5.1 KiB
Svelte
Raw Normal View History

<script>
import { writable, get as svelteGet } from "svelte/store"
2021-12-09 07:51:24 +13:00
import { notifications, Input, ModalContent, Dropzone } from "@budibase/bbui"
import { store, automationStore } from "builderStore"
import { API } from "api"
import { apps, admin, auth } from "stores/portal"
2021-09-21 22:47:14 +12:00
import analytics, { Events } from "analytics"
2021-01-07 06:28:22 +13:00
import { onMount } from "svelte"
2021-05-08 00:13:51 +12:00
import { goto } from "@roxi/routify"
import { createValidationStore } from "helpers/validation/yup"
import * as appValidation from "helpers/validation/yup/app"
import TemplateCard from "components/common/TemplateCard.svelte"
2020-05-27 22:54:53 +12:00
2020-09-26 01:47:42 +12:00
export let template
let creating = false
const values = writable({ name: "", url: null })
const validation = createValidationStore()
$: validation.check($values)
onMount(async () => {
$values.name = resolveAppName(template, $values.name)
nameToUrl($values.name)
await setupValidation()
})
2020-08-04 01:59:50 +12:00
const appPrefix = "/app"
$: appUrl = `${window.location.origin}${
$values.url
? `${appPrefix}${$values.url}`
: `${appPrefix}${resolveAppUrl(template, $values.name)}`
}`
const resolveAppUrl = (template, name) => {
let parsedName
const resolvedName = resolveAppName(template, name)
parsedName = resolvedName ? resolvedName.toLowerCase() : ""
const parsedUrl = parsedName ? parsedName.replace(/\s+/g, "-") : ""
return encodeURI(parsedUrl)
}
const resolveAppName = (template, name) => {
if (template && !name) {
return template.name
}
return name ? name.trim() : null
}
const tidyUrl = url => {
if (url && !url.startsWith("/")) {
url = `/${url}`
}
$values.url = url === "" ? null : url
}
const nameToUrl = appName => {
let resolvedUrl = resolveAppUrl(template, appName)
tidyUrl(resolvedUrl)
}
const setupValidation = async () => {
const applications = svelteGet(apps)
appValidation.name(validation, { apps: applications })
appValidation.url(validation, { apps: applications })
appValidation.file(validation, { template })
// init validation
validation.check($values)
2020-08-04 01:59:50 +12:00
}
async function createNewApp() {
creating = true
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.trim())
if ($values.url) {
data.append("url", $values.url.trim())
}
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
const createdApp = await API.createApp(data)
2021-09-21 22:47:14 +12:00
analytics.captureEvent(Events.APP.CREATED, {
name: $values.name,
appId: createdApp.instance._id,
templateToUse: 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
const pkg = await API.fetchAppPackage(createdApp.instance._id)
await store.actions.initialise(pkg)
await automationStore.actions.fetch()
// Update checklist - in case first app
await admin.init()
2020-08-04 02:26:28 +12:00
// Create user
await API.updateOwnMetadata({ roleId: $values.roleId })
2021-11-05 02:03:18 +13:00
await auth.setInitInfo({})
$goto(`/builder/app/${createdApp.instance._id}`)
2020-08-04 01:59:50 +12:00
} catch (error) {
creating = false
2020-08-04 01:59:50 +12:00
console.error(error)
notifications.error("Error creating app")
2020-05-27 21:44:15 +12:00
}
}
2020-05-27 02:25:37 +12:00
</script>
2022-01-20 07:29:09 +13:00
<ModalContent
title={"Create your app"}
2022-01-20 07:29:09 +13:00
confirmText={template?.fromFile ? "Import app" : "Create app"}
onConfirm={createNewApp}
disabled={!$validation.valid}
2022-01-20 07:29:09 +13:00
>
{#if template && !template?.fromFile}
<TemplateCard
name={template.name}
imageSrc={template.image}
backgroundColour={template.background}
overlayEnabled={false}
icon={template.icon}
/>
{/if}
2022-01-20 07:29:09 +13:00
{#if template?.fromFile}
<Dropzone
error={$validation.touched.file && $validation.errors.file}
2022-01-20 07:29:09 +13:00
gallery={false}
label="File to import"
value={[$values.file]}
on:change={e => {
$values.file = e.detail?.[0]
$validation.touched.file = true
}}
/>
2022-01-20 07:29:09 +13:00
{/if}
<Input
bind:value={$values.name}
disabled={creating}
error={$validation.touched.name && $validation.errors.name}
on:blur={() => ($validation.touched.name = true)}
on:change={nameToUrl($values.name)}
2022-01-20 07:29:09 +13:00
label="Name"
placeholder={$auth.user?.firstName
? `${$auth.user.firstName}s app`
2022-01-20 07:29:09 +13:00
: "My app"}
/>
<span>
<Input
bind:value={$values.url}
disabled={creating}
error={$validation.touched.url && $validation.errors.url}
on:blur={() => ($validation.touched.url = true)}
on:change={tidyUrl($values.url)}
label="URL"
placeholder={$values.url
? $values.url
: `/${resolveAppUrl(template, $values.name)}`}
/>
{#if $values.url && $values.url !== "" && !$validation.errors.url}
<div class="app-server" title={appUrl}>
{appUrl}
</div>
{/if}
</span>
2022-01-20 07:29:09 +13:00
</ModalContent>
<style>
.app-server {
color: var(--spectrum-global-color-gray-600);
margin-top: 10px;
width: 320px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>