Minor UI updates for the create app modal. A spinner has been added to the modal confirmation UX. The app name is pre-populated using the app name. The app URL can no longer be null

This commit is contained in:
Dean 2022-03-23 12:43:20 +00:00
parent 768f9e8679
commit cc0280ca0c
5 changed files with 66 additions and 43 deletions

View File

@ -5,6 +5,7 @@
import Divider from "../Divider/Divider.svelte"
import Icon from "../Icon/Icon.svelte"
import Context from "../context"
import ProgressCircle from "../ProgressCircle/ProgressCircle.svelte"
export let title = undefined
export let size = "S"
@ -102,15 +103,22 @@
<Button group secondary on:click={close}>{cancelText}</Button>
{/if}
{#if showConfirmButton}
<Button
group
cta
{...$$restProps}
disabled={confirmDisabled}
on:click={confirm}
>
{confirmText}
</Button>
<span class="confirm-wrap">
<Button
group
cta
{...$$restProps}
disabled={confirmDisabled}
on:click={confirm}
>
{#if loading}
<ProgressCircle overBackground={true} size="S" />
{/if}
{#if !loading}
{confirmText}
{/if}
</Button>
</span>
{/if}
</div>
{/if}
@ -169,4 +177,8 @@
.spectrum-Dialog-buttonGroup {
padding-left: 0;
}
.confirm-wrap :global(.spectrum-Button-label) {
display: contents;
}
</style>

View File

@ -13,18 +13,20 @@
export let template
let creating = false
const values = writable({ name: "", url: null })
const validation = createValidationStore()
$: validation.check($values)
onMount(async () => {
$values.url = resolveAppUrl(template, $values.name, $values.url)
$values.name = resolveAppName(template, $values.name)
nameToUrl($values.name)
await setupValidation()
})
$: appUrl = `${window.location.origin}${
$values.url ? $values.url : `/${resolveAppUrl(template, $values.name)}`
$values.url ? $values.url : `${resolveAppUrl(template, $values.name)}`
}`
const resolveAppUrl = (template, name) => {
@ -39,7 +41,19 @@
if (template && !name) {
return template.name
}
return name.trim()
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 () => {
@ -52,6 +66,8 @@
}
async function createNewApp() {
creating = true
try {
// Create form data to create app
let data = new FormData()
@ -86,17 +102,11 @@
await auth.setInitInfo({})
$goto(`/builder/app/${createdApp.instance._id}`)
} catch (error) {
creating = false
console.error(error)
notifications.error("Error creating app")
}
}
// auto add slash to url
$: {
if ($values.url && !$values.url.startsWith("/")) {
$values.url = `/${$values.url}`
}
}
</script>
<ModalContent
@ -128,41 +138,38 @@
{/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)}
label="Name"
placeholder={$auth.user.firstName
placeholder={$auth.user?.firstName
? `${$auth.user.firstName}s app`
: "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.name}
<div class="app-server-wrap" title={appUrl}>
<span class="app-server-prefix">
{window.location.origin}
</span>
{$values.url
? $values.url
: `/${resolveAppUrl(template, $values.name)}`}
{#if $values.url && $values.url !== "" && !$validation.errors.url}
<div class="app-server" title={appUrl}>
{`${window.location.origin}${$values.url}`}
</div>
{/if}
</span>
</ModalContent>
<style>
.app-server-prefix {
color: var(--spectrum-global-color-gray-500);
}
.app-server-wrap {
.app-server {
color: var(--spectrum-global-color-gray-600);
margin-top: 10px;
width: 320px;
white-space: nowrap;

View File

@ -35,13 +35,14 @@ export const url = (validation, { apps, currentApp } = { apps: [] }) => {
validation.addValidator(
"url",
string()
.trim()
.nullable()
.matches(APP_URL_REGEX, "App URL must not contain spaces")
.required("Your application must have a url")
.matches(APP_URL_REGEX, "Please enter a valid url")
.test(
"non-existing-app-url",
"Another app with the same URL already exists",
value => {
// url is nullable
if (!value) {
return true
}

View File

@ -9,6 +9,7 @@
Body,
Modal,
Divider,
Link,
} from "@budibase/bbui"
import CreateAppModal from "components/start/CreateAppModal.svelte"
import TemplateDisplay from "components/common/TemplateDisplay.svelte"
@ -60,14 +61,15 @@
<Page wide>
<Layout noPadding gap="XL">
<span>
<Button
primary
<Link
quiet
secondary
on:click={() => {
$goto("../")
}}
>
Back
</Button>
&lt;&nbsp;Back
</Link>
</span>
<div class="title">

View File

@ -1,6 +1,6 @@
<script>
import { goto } from "@roxi/routify"
import { Layout, Page, notifications, Button } from "@budibase/bbui"
import { Layout, Page, notifications, Link } from "@budibase/bbui"
import TemplateDisplay from "components/common/TemplateDisplay.svelte"
import { onMount } from "svelte"
import { templates } from "stores/portal"
@ -25,14 +25,15 @@
<Page wide>
<Layout noPadding gap="XL">
<span>
<Button
primary
<Link
quiet
secondary
on:click={() => {
$goto("../")
}}
>
Back
</Button>
&lt;&nbsp;Back
</Link>
</span>
{#if loaded && $templates?.length}
<TemplateDisplay templates={$templates} />