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 dc34e86431
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 192 additions and 13 deletions

View File

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

View File

@ -14,6 +14,7 @@
export let updateOnChange = true
export let quiet = false
export let dataCy
export let autofocus
const dispatch = createEventDispatcher()
const onChange = e => {
@ -33,6 +34,7 @@
{placeholder}
{type}
{quiet}
{autofocus}
on:change={onChange}
on:click
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"
cy.get(".spectrum-Modal").within(() => {
cy.get("input").eq(0).should('have.focus')
//Auto fill
cy.get("input").eq(0).clear()
cy.get("input").eq(0).type(appName).should("have.value", appName).blur()
cy.get("input").eq(1).should("have.value", "/cypress-tests")
cy.get(".spectrum-ButtonGroup").contains("Create app").should('not.be.disabled')
@ -97,6 +100,75 @@ filterTests(['smoke', 'all'], () => {
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", () => {
cy.visit(`${Cypress.config().baseUrl}/builder`)
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) => {
const shouldCreateDefaultTable =
typeof addDefaultTable != "boolean" ? true : addDefaultTable
@ -57,7 +122,11 @@ Cypress.Commands.add("createApp", (name, addDefaultTable) => {
})
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")
.contains("Create app")
.click({ force: true })

View File

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

View File

@ -16,13 +16,26 @@
export let template
let creating = false
let defaultAppName
const values = writable({ name: "", url: null })
const validation = createValidationStore()
$: validation.check($values)
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)
await setupValidation()
})
@ -44,7 +57,7 @@
}
const resolveAppName = (template, name) => {
if (template && !name) {
if (template && !template.fromFile) {
return template.name
}
return name ? name.trim() : null
@ -83,7 +96,7 @@
}
data.append("useTemplate", template != null)
if (template) {
data.append("templateName", template.name) //or here?
data.append("templateName", template.name)
data.append("templateKey", template.key)
data.append("templateFile", $values.file)
}
@ -159,15 +172,14 @@
/>
{/if}
<Input
autofocus={true}
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
? `${$auth.user.firstName}s app`
: "My app"}
placeholder={defaultAppName}
/>
<span>
<Input

View File

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

View File

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