rename an app

This commit is contained in:
Maurits Lourens 2021-07-27 17:34:18 +02:00
parent 30be2a00fa
commit f2b1125e0b
5 changed files with 150 additions and 0 deletions

View File

@ -15,6 +15,7 @@
export let exportApp export let exportApp
export let viewApp export let viewApp
export let editApp export let editApp
export let updateApp
export let deleteApp export let deleteApp
export let unpublishApp export let unpublishApp
export let releaseLock export let releaseLock
@ -53,6 +54,9 @@
</MenuItem> </MenuItem>
{/if} {/if}
{#if !app.deployed} {#if !app.deployed}
<MenuItem on:click={() => updateApp(app)} icon="Edit">
Update
</MenuItem>
<MenuItem on:click={() => deleteApp(app)} icon="Delete"> <MenuItem on:click={() => deleteApp(app)} icon="Delete">
Delete Delete
</MenuItem> </MenuItem>

View File

@ -14,6 +14,7 @@
export let exportApp export let exportApp
export let viewApp export let viewApp
export let editApp export let editApp
export let updateApp
export let deleteApp export let deleteApp
export let unpublishApp export let unpublishApp
export let releaseLock export let releaseLock
@ -82,6 +83,7 @@
</MenuItem> </MenuItem>
{/if} {/if}
{#if !app.deployed} {#if !app.deployed}
<MenuItem on:click={() => updateApp(app)} icon="Edit">Update</MenuItem>
<MenuItem on:click={() => deleteApp(app)} icon="Delete">Delete</MenuItem> <MenuItem on:click={() => deleteApp(app)} icon="Delete">Delete</MenuItem>
{/if} {/if}
</ActionMenu> </ActionMenu>

View File

@ -0,0 +1,111 @@
<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"
const values = writable({ name: null })
const errors = writable({})
const touched = writable({})
const validator = {
name: string().required("Your application must have a name"),
}
export let app;
let modal;
let valid = false
let dirty = false;
$: 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()
.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 => 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
await apps.update(app.instance._id, $values.name);
hide();
} catch (error) {
console.error(error)
notifications.error(error)
}
}
export const show = () => {
modal.show()
}
export const hide = () => {
modal.hide()
}
const onCancel = () => {
hide();
}
const onShow = () => {
dirty = false;
}
</script>
<Modal bind:this={modal} on:hide={onCancel} on:show={onShow}>
<ModalContent
title={"Update app"}
confirmText={"Update app"}
onConfirm={updateApp}
disabled={!(valid && dirty)}
>
<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)}
on:change={() => dirty = true}
label="Name"
/>
</ModalContent>
</Modal>

View File

@ -14,6 +14,7 @@
Body, Body,
} from "@budibase/bbui" } from "@budibase/bbui"
import CreateAppModal from "components/start/CreateAppModal.svelte" import CreateAppModal from "components/start/CreateAppModal.svelte"
import UpdateAppModal from "components/start/UpdateAppModal.svelte"
import api, { del } from "builderStore/api" import api, { del } from "builderStore/api"
import analytics from "analytics" import analytics from "analytics"
import { onMount } from "svelte" import { onMount } from "svelte"
@ -30,6 +31,7 @@
let template let template
let selectedApp let selectedApp
let creationModal let creationModal
let updatingModal
let deletionModal let deletionModal
let unpublishModal let unpublishModal
let creatingApp = false let creatingApp = false
@ -164,6 +166,11 @@
selectedApp = null selectedApp = null
} }
const updateApp = async app => {
selectedApp = app
updatingModal.show()
}
const releaseLock = async app => { const releaseLock = async app => {
try { try {
const response = await del(`/api/dev/${app.devId}/lock`) const response = await del(`/api/dev/${app.devId}/lock`)
@ -236,6 +243,7 @@
{editApp} {editApp}
{exportApp} {exportApp}
{deleteApp} {deleteApp}
{updateApp}
/> />
{/each} {/each}
</div> </div>
@ -289,6 +297,12 @@
Are you sure you want to unpublish the app <b>{selectedApp?.name}</b>? Are you sure you want to unpublish the app <b>{selectedApp?.name}</b>?
</ConfirmDialog> </ConfirmDialog>
<UpdateAppModal
app={selectedApp}
bind:this={updatingModal}
>
</UpdateAppModal>
<style> <style>
.title, .title,
.filter { .filter {

View File

@ -1,6 +1,7 @@
import { writable } from "svelte/store" import { writable } from "svelte/store"
import { get } from "builderStore/api" import { get } from "builderStore/api"
import { AppStatus } from "../../constants" import { AppStatus } from "../../constants"
import api from "../../builderStore/api";
export function createAppStore() { export function createAppStore() {
const store = writable([]) const store = writable([])
@ -53,9 +54,27 @@ export function createAppStore() {
} }
} }
async function update (appId, name) {
const response = await api.put(`/api/applications/${appId}`, { name })
if (response.status === 200) {
store.update(state => {
const updatedAppIndex = state.findIndex(app => app.instance._id === appId);
if (updatedAppIndex !== -1) {
const updatedApp = state[updatedAppIndex];
updatedApp.name = name;
state.apps = state.splice(updatedAppIndex, 1, updatedApp);
}
return state
})
} else {
throw new Error("Error updating name")
}
}
return { return {
subscribe: store.subscribe, subscribe: store.subscribe,
load, load,
update,
} }
} }