1
0
Fork 0
mirror of synced 2024-07-07 23:35:49 +12:00

Merge pull request #2135 from mslourens/renaming_an_app

rename an app
This commit is contained in:
Martin McKeaveney 2021-07-28 16:58:08 +01:00 committed by GitHub
commit bde1eb0a3c
5 changed files with 148 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,8 @@
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} />
<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,29 @@ 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,
} }
} }