Merge pull request #5855 from Budibase/feature/fill-app-name-on-create

Feature/fill app name on create
This commit is contained in:
Martin McKeaveney 2022-05-16 17:38:33 +01:00 committed by GitHub
commit d68b695d62
9 changed files with 192 additions and 13 deletions

View File

@ -1,6 +1,6 @@
<script> <script>
import "@spectrum-css/textfield/dist/index-vars.css" import "@spectrum-css/textfield/dist/index-vars.css"
import { createEventDispatcher } from "svelte" import { createEventDispatcher, onMount } from "svelte"
export let value = null export let value = null
export let placeholder = null export let placeholder = null
@ -13,8 +13,11 @@
export let quiet = false export let quiet = false
export let dataCy export let dataCy
export let align export let align
export let autofocus = false
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
let field
let focus = false let focus = false
const updateValue = newValue => { const updateValue = newValue => {
@ -58,6 +61,11 @@
updateValue(event.target.value) updateValue(event.target.value)
} }
} }
onMount(() => {
focus = autofocus
if (focus) field.focus()
})
</script> </script>
<div <div
@ -77,6 +85,7 @@
</svg> </svg>
{/if} {/if}
<input <input
bind:this={field}
{disabled} {disabled}
{readonly} {readonly}
{id} {id}

View File

@ -14,6 +14,7 @@
export let updateOnChange = true export let updateOnChange = true
export let quiet = false export let quiet = false
export let dataCy export let dataCy
export let autofocus
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const onChange = e => { const onChange = e => {
@ -33,6 +34,7 @@
{placeholder} {placeholder}
{type} {type}
{quiet} {quiet}
{autofocus}
on:change={onChange} on:change={onChange}
on:click on:click
on:input on:input

File diff suppressed because one or more lines are too long

View File

@ -63,7 +63,10 @@ filterTests(['smoke', 'all'], () => {
const appName = "Cypress Tests" const appName = "Cypress Tests"
cy.get(".spectrum-Modal").within(() => { cy.get(".spectrum-Modal").within(() => {
cy.get("input").eq(0).should('have.focus')
//Auto fill //Auto fill
cy.get("input").eq(0).clear()
cy.get("input").eq(0).type(appName).should("have.value", appName).blur() cy.get("input").eq(0).type(appName).should("have.value", appName).blur()
cy.get("input").eq(1).should("have.value", "/cypress-tests") cy.get("input").eq(1).should("have.value", "/cypress-tests")
cy.get(".spectrum-ButtonGroup").contains("Create app").should('not.be.disabled') cy.get(".spectrum-ButtonGroup").contains("Create app").should('not.be.disabled')
@ -97,6 +100,75 @@ filterTests(['smoke', 'all'], () => {
cy.deleteApp(appName) cy.deleteApp(appName)
}) })
it("should create the first application from scratch with a default name", () => {
cy.createApp()
cy.visit(`${Cypress.config().baseUrl}/builder`)
cy.wait(1000)
cy.applicationInAppTable("My app")
cy.deleteApp("My app")
})
it("should create the first application from scratch, using the users first name as the default app name", () => {
cy.visit(`${Cypress.config().baseUrl}/builder`)
cy.updateUserInformation("Ted", "Userman")
cy.createApp()
cy.visit(`${Cypress.config().baseUrl}/builder`)
cy.wait(1000)
cy.applicationInAppTable("Teds app")
cy.deleteApp("Teds app")
//Accomodate names that end in 'S'
cy.updateUserInformation("Chris", "Userman")
cy.createApp()
cy.visit(`${Cypress.config().baseUrl}/builder`)
cy.wait(1000)
cy.applicationInAppTable("Chris app")
cy.deleteApp("Chris app")
cy.updateUserInformation("", "")
})
it("should create an application from an export", () => {
const exportedApp = 'cypress/fixtures/exported-app.txt'
cy.importApp(exportedApp, "")
cy.visit(`${Cypress.config().baseUrl}/builder`)
cy.applicationInAppTable("My app")
cy.get(".appTable .name").eq(0).click()
cy.deleteApp("My app")
})
it("should create an application from an export, using the users first name as the default app name", () => {
const exportedApp = 'cypress/fixtures/exported-app.txt'
cy.updateUserInformation("Ted", "Userman")
cy.importApp(exportedApp, "")
cy.visit(`${Cypress.config().baseUrl}/builder`)
cy.applicationInAppTable("Teds app")
cy.get(".appTable .name").eq(0).click()
cy.deleteApp("Teds app")
cy.updateUserInformation("", "")
})
it("should generate the first application from a template", () => { it("should generate the first application from a template", () => {
cy.visit(`${Cypress.config().baseUrl}/builder`) cy.visit(`${Cypress.config().baseUrl}/builder`)
cy.wait(500) cy.wait(500)

View File

@ -39,6 +39,71 @@ Cypress.Commands.add("closeModal", () => {
}) })
}) })
Cypress.Commands.add("importApp", (exportFilePath, name) => {
cy.visit(`${Cypress.config().baseUrl}/builder`)
cy.request(`${Cypress.config().baseUrl}/api/applications?status=all`)
.its("body")
.then(val => {
if (val.length > 0) {
cy.get(`[data-cy="create-app-btn"]`).click({ force: true })
cy.wait(500)
}
cy.get(`[data-cy="import-app-btn"]`).click({ force: true })
})
cy.get(".spectrum-Modal").within(() => {
cy.get("input").eq(1).should("have.focus")
cy.get(".spectrum-Dropzone").selectFile(exportFilePath, {
action: "drag-drop",
})
cy.get(".gallery .filename").contains("exported-app.txt")
if (name && name != "") {
cy.get("input").eq(0).type(name).should("have.value", name).blur()
}
cy.get(".confirm-wrap button")
.should("not.be.disabled")
.click({ force: true })
cy.wait(5000)
})
})
Cypress.Commands.add("updateUserInformation", (firstName, lastName) => {
cy.get(".user-dropdown .avatar > .icon").click({ force: true })
cy.get(".spectrum-Popover[data-cy='user-menu']").within(() => {
cy.get("li[data-cy='user-info']").click({ force: true })
})
cy.get(".spectrum-Modal.is-open").within(() => {
cy.get("[data-cy='user-first-name']").clear()
if (!firstName || firstName == "") {
cy.get("[data-cy='user-first-name']").invoke("val").should("be.empty")
} else {
cy.get("[data-cy='user-first-name']")
.type(firstName)
.should("have.value", firstName)
.blur()
}
cy.get("[data-cy='user-last-name']").clear()
if (!lastName || lastName == "") {
cy.get("[data-cy='user-last-name']").invoke("val").should("be.empty")
} else {
cy.get("[data-cy='user-last-name']")
.type(lastName)
.should("have.value", lastName)
.blur()
}
cy.get("button").contains("Update information").click({ force: true })
})
})
Cypress.Commands.add("createApp", (name, addDefaultTable) => { Cypress.Commands.add("createApp", (name, addDefaultTable) => {
const shouldCreateDefaultTable = const shouldCreateDefaultTable =
typeof addDefaultTable != "boolean" ? true : addDefaultTable typeof addDefaultTable != "boolean" ? true : addDefaultTable
@ -57,7 +122,11 @@ Cypress.Commands.add("createApp", (name, addDefaultTable) => {
}) })
cy.get(".spectrum-Modal").within(() => { cy.get(".spectrum-Modal").within(() => {
cy.get("input").eq(0).type(name).should("have.value", name).blur() cy.get("input").eq(0).should("have.focus")
if (name && name != "") {
cy.get("input").eq(0).clear()
cy.get("input").eq(0).type(name).should("have.value", name).blur()
}
cy.get(".spectrum-ButtonGroup") cy.get(".spectrum-ButtonGroup")
.contains("Create app") .contains("Create app")
.click({ force: true }) .click({ force: true })

View File

@ -27,6 +27,14 @@
Personalise the platform by adding your first name and last name. Personalise the platform by adding your first name and last name.
</Body> </Body>
<Input disabled bind:value={$auth.user.email} label="Email" /> <Input disabled bind:value={$auth.user.email} label="Email" />
<Input bind:value={$values.firstName} label="First name" /> <Input
<Input bind:value={$values.lastName} label="Last name" /> bind:value={$values.firstName}
label="First name"
dataCy="user-first-name"
/>
<Input
bind:value={$values.lastName}
label="Last name"
dataCy="user-last-name"
/>
</ModalContent> </ModalContent>

View File

@ -16,13 +16,26 @@
export let template export let template
let creating = false let creating = false
let defaultAppName
const values = writable({ name: "", url: null }) const values = writable({ name: "", url: null })
const validation = createValidationStore() const validation = createValidationStore()
$: validation.check($values) $: validation.check($values)
onMount(async () => { onMount(async () => {
$values.name = resolveAppName(template, $values.name) const lastChar = $auth.user?.firstName
? $auth.user?.firstName[$auth.user?.firstName.length - 1]
: null
defaultAppName =
lastChar && lastChar.toLowerCase() == "s"
? `${$auth.user?.firstName} app`
: `${$auth.user.firstName}s app`
$values.name = resolveAppName(
template,
!$auth.user?.firstName ? "My app" : defaultAppName
)
nameToUrl($values.name) nameToUrl($values.name)
await setupValidation() await setupValidation()
}) })
@ -44,7 +57,7 @@
} }
const resolveAppName = (template, name) => { const resolveAppName = (template, name) => {
if (template && !name) { if (template && !template.fromFile) {
return template.name return template.name
} }
return name ? name.trim() : null return name ? name.trim() : null
@ -83,7 +96,7 @@
} }
data.append("useTemplate", template != null) data.append("useTemplate", template != null)
if (template) { if (template) {
data.append("templateName", template.name) //or here? data.append("templateName", template.name)
data.append("templateKey", template.key) data.append("templateKey", template.key)
data.append("templateFile", $values.file) data.append("templateFile", $values.file)
} }
@ -159,15 +172,14 @@
/> />
{/if} {/if}
<Input <Input
autofocus={true}
bind:value={$values.name} bind:value={$values.name}
disabled={creating} disabled={creating}
error={$validation.touched.name && $validation.errors.name} error={$validation.touched.name && $validation.errors.name}
on:blur={() => ($validation.touched.name = true)} on:blur={() => ($validation.touched.name = true)}
on:change={nameToUrl($values.name)} on:change={nameToUrl($values.name)}
label="Name" label="Name"
placeholder={$auth.user?.firstName placeholder={defaultAppName}
? `${$auth.user.firstName}s app`
: "My app"}
/> />
<span> <span>
<Input <Input

View File

@ -69,7 +69,7 @@
<Layout noPadding> <Layout noPadding>
<div class="header"> <div class="header">
<img alt="logo" src={$organisation.logoUrl || Logo} /> <img alt="logo" src={$organisation.logoUrl || Logo} />
<ActionMenu align="right"> <ActionMenu align="right" dataCy="user-menu">
<div slot="control" class="avatar"> <div slot="control" class="avatar">
<Avatar <Avatar
size="M" size="M"

View File

@ -160,7 +160,7 @@
/> />
</div> </div>
<div class="user-dropdown"> <div class="user-dropdown">
<ActionMenu align="right"> <ActionMenu align="right" dataCy="user-menu">
<div slot="control" class="avatar"> <div slot="control" class="avatar">
<Avatar <Avatar
size="M" size="M"
@ -169,7 +169,11 @@
/> />
<Icon size="XL" name="ChevronDown" /> <Icon size="XL" name="ChevronDown" />
</div> </div>
<MenuItem icon="UserEdit" on:click={() => userInfoModal.show()}> <MenuItem
icon="UserEdit"
on:click={() => userInfoModal.show()}
dataCy={"user-info"}
>
Update user information Update user information
</MenuItem> </MenuItem>
{#if $auth.isBuilder} {#if $auth.isBuilder}