budibase/packages/builder/src/components/start/UpdateAppModal.svelte

121 lines
2.9 KiB
Svelte
Raw Normal View History

2021-07-27 17:34:18 +02:00
<script>
import { writable, get as svelteGet } from "svelte/store"
import {
notifications,
Input,
Modal,
ModalContent,
Body,
} from "@budibase/bbui"
import { hostingStore } from "builderStore"
import { apps } from "stores/portal"
import { string, object } from "yup"
import { onMount } from "svelte"
import { capitalise } from "helpers"
import { APP_NAME_REGEX } from "constants"
2021-07-27 17:34:18 +02:00
const values = writable({ name: null })
const errors = writable({})
const touched = writable({})
const validator = {
name: string()
.trim()
.required("Your application must have a name")
.matches(
APP_NAME_REGEX,
"App name must be letters, numbers and spaces only"
),
2021-07-27 17:34:18 +02:00
}
2021-07-28 00:09:15 +02:00
export let app
2021-07-27 17:34:18 +02:00
2021-07-28 00:09:15 +02:00
let modal
2021-07-27 17:34:18 +02:00
let valid = false
2021-07-28 00:09:15 +02:00
let dirty = false
2021-07-27 17:34:18 +02:00
$: checkValidity($values, validator)
$: {
// prevent validation by setting name to undefined without an app
if (app) {
$values.name = app?.name
}
}
onMount(async () => {
await hostingStore.actions.fetchDeployedApps()
const existingAppNames = svelteGet(hostingStore).deployedAppNames
validator.name = string()
.trim()
2021-07-27 17:34:18 +02:00
.required("Your application must have a name")
.matches(
APP_NAME_REGEX,
"App name must be letters, numbers and spaces only"
)
2021-07-27 17:34:18 +02:00
.test(
"non-existing-app-name",
"Another app with the same name already exists",
value => {
return !existingAppNames.some(
appName => dirty && appName.toLowerCase() === value.toLowerCase()
)
}
)
})
const checkValidity = async (values, validator) => {
const obj = object().shape(validator)
Object.keys(validator).forEach(key => ($errors[key] = null))
try {
await obj.validate(values, { abortEarly: false })
} catch (validationErrors) {
validationErrors.inner.forEach(error => {
$errors[error.path] = capitalise(error.message)
})
}
valid = await obj.isValid(values)
}
async function updateApp() {
try {
// Update App
2021-12-14 16:30:20 +01:00
await apps.update(app.instance._id, { name: $values.name.trim() })
2021-07-28 00:09:15 +02:00
hide()
2021-07-27 17:34:18 +02:00
} catch (error) {
console.error(error)
notifications.error(error)
}
}
export const show = () => {
modal.show()
}
export const hide = () => {
modal.hide()
}
const onCancel = () => {
2021-07-28 00:09:15 +02:00
hide()
2021-07-27 17:34:18 +02:00
}
const onShow = () => {
2021-07-28 00:09:15 +02:00
dirty = false
2021-07-27 17:34:18 +02:00
}
</script>
2021-07-28 00:09:15 +02:00
2021-07-27 17:34:18 +02:00
<Modal bind:this={modal} on:hide={onCancel} on:show={onShow}>
<ModalContent
title={"Edit app"}
confirmText={"Save"}
2021-07-27 17:34:18 +02:00
onConfirm={updateApp}
disabled={!(valid && dirty)}
>
2021-08-18 11:24:25 +02:00
<Body size="S">Update the name of your app.</Body>
2021-07-27 17:34:18 +02:00
<Input
bind:value={$values.name}
error={$touched.name && $errors.name}
on:blur={() => ($touched.name = true)}
2021-07-28 00:09:15 +02:00
on:change={() => (dirty = true)}
2021-07-27 17:34:18 +02:00
label="Name"
/>
</ModalContent>
</Modal>