2
0

♻️ (builder) Change to features-centric folder structure

This commit is contained in:
Baptiste Arnaud
2022-11-15 09:35:48 +01:00
committed by Baptiste Arnaud
parent 3686465a85
commit 643571fe7d
683 changed files with 3907 additions and 3643 deletions

View File

@ -0,0 +1,12 @@
import { Text } from '@chakra-ui/react'
import { FileInputOptions } from 'models'
type Props = {
options: FileInputOptions
}
export const FileInputContent = ({ options: { isMultipleAllowed } }: Props) => (
<Text noOfLines={1} pr="6">
Collect {isMultipleAllowed ? 'files' : 'file'}
</Text>
)

View File

@ -0,0 +1,7 @@
import { UploadIcon } from '@/components/icons'
import { IconProps } from '@chakra-ui/react'
import React from 'react'
export const FileInputIcon = (props: IconProps) => (
<UploadIcon color="orange.500" {...props} />
)

View File

@ -0,0 +1,81 @@
import { FormLabel, Stack } from '@chakra-ui/react'
import { CodeEditor } from '@/components/CodeEditor'
import { FileInputOptions, Variable } from 'models'
import React from 'react'
import { Input, SmartNumberInput } from '@/components/inputs'
import { SwitchWithLabel } from '@/components/SwitchWithLabel'
import { VariableSearchInput } from '@/components/VariableSearchInput'
type Props = {
options: FileInputOptions
onOptionsChange: (options: FileInputOptions) => void
}
export const FileInputSettings = ({ options, onOptionsChange }: Props) => {
const handleButtonLabelChange = (button: string) =>
onOptionsChange({ ...options, labels: { ...options.labels, button } })
const handlePlaceholderLabelChange = (placeholder: string) =>
onOptionsChange({ ...options, labels: { ...options.labels, placeholder } })
const handleMultipleFilesChange = (isMultipleAllowed: boolean) =>
onOptionsChange({ ...options, isMultipleAllowed })
const handleVariableChange = (variable?: Variable) =>
onOptionsChange({ ...options, variableId: variable?.id })
const handleSizeLimitChange = (sizeLimit?: number) =>
onOptionsChange({ ...options, sizeLimit })
const handleRequiredChange = (isRequired: boolean) =>
onOptionsChange({ ...options, isRequired })
return (
<Stack spacing={4}>
<SwitchWithLabel
label="Required?"
initialValue={options.isRequired ?? true}
onCheckChange={handleRequiredChange}
/>
<SwitchWithLabel
label="Allow multiple files?"
initialValue={options.isMultipleAllowed}
onCheckChange={handleMultipleFilesChange}
/>
<Stack>
<FormLabel mb="0" htmlFor="limit">
Size limit (MB):
</FormLabel>
<SmartNumberInput
id="limit"
value={options.sizeLimit ?? 10}
onValueChange={handleSizeLimitChange}
/>
</Stack>
<Stack>
<FormLabel mb="0">Placeholder:</FormLabel>
<CodeEditor
lang="html"
onChange={handlePlaceholderLabelChange}
value={options.labels.placeholder}
height={'100px'}
withVariableButton={false}
/>
</Stack>
<Stack>
<FormLabel mb="0" htmlFor="button">
Button label:
</FormLabel>
<Input
id="button"
defaultValue={options.labels.button}
onChange={handleButtonLabelChange}
withVariableButton={false}
/>
</Stack>
<Stack>
<FormLabel mb="0" htmlFor="variable">
Save upload URL{options.isMultipleAllowed ? 's' : ''} in a variable:
</FormLabel>
<VariableSearchInput
initialVariableId={options.variableId}
onSelectVariable={handleVariableChange}
/>
</Stack>
</Stack>
)
}

View File

@ -0,0 +1,81 @@
import test, { expect } from '@playwright/test'
import { createTypebots } from 'utils/playwright/databaseActions'
import { parseDefaultGroupWithBlock } from 'utils/playwright/databaseHelpers'
import { defaultFileInputOptions, InputBlockType } from 'models'
import { typebotViewer } from 'utils/playwright/testHelpers'
import cuid from 'cuid'
import { freeWorkspaceId } from 'utils/playwright/databaseSetup'
import { getTestAsset } from '@/test/utils/playwright'
test.describe.configure({ mode: 'parallel' })
test('options should work', async ({ page }) => {
const typebotId = cuid()
await createTypebots([
{
id: typebotId,
...parseDefaultGroupWithBlock({
type: InputBlockType.FILE,
options: defaultFileInputOptions,
}),
},
])
await page.goto(`/typebots/${typebotId}/edit`)
await page.click('text=Preview')
await expect(
typebotViewer(page).locator(`text=Click to upload`)
).toBeVisible()
await expect(typebotViewer(page).locator(`text="Skip"`)).toBeHidden()
await typebotViewer(page)
.locator(`input[type="file"]`)
.setInputFiles([getTestAsset('avatar.jpg')])
await expect(typebotViewer(page).locator(`text=File uploaded`)).toBeVisible()
await page.click('text="Collect file"')
await page.click('text="Required?"')
await page.click('text="Allow multiple files?"')
await page.fill('div[contenteditable=true]', '<strong>Upload now!!</strong>')
await page.fill('[value="Upload"]', 'Go')
await page.fill('input[value="10"]', '20')
await page.click('text="Restart"')
await expect(typebotViewer(page).locator(`text="Skip"`)).toBeVisible()
await expect(typebotViewer(page).locator(`text="Upload now!!"`)).toBeVisible()
await typebotViewer(page)
.locator(`input[type="file"]`)
.setInputFiles([
getTestAsset('avatar.jpg'),
getTestAsset('avatar.jpg'),
getTestAsset('avatar.jpg'),
])
await expect(typebotViewer(page).locator(`text="3"`)).toBeVisible()
await typebotViewer(page).locator('text="Go 3 files"').click()
await expect(
typebotViewer(page).locator(`text="3 files uploaded"`)
).toBeVisible()
})
test.describe('Free workspace', () => {
test("shouldn't be able to publish typebot", async ({ page }) => {
const typebotId = cuid()
await createTypebots([
{
id: typebotId,
...parseDefaultGroupWithBlock({
type: InputBlockType.FILE,
options: defaultFileInputOptions,
}),
workspaceId: freeWorkspaceId,
},
])
await page.goto(`/typebots/${typebotId}/edit`)
await page.click('text="Collect file"')
await page.click('text="Allow multiple files?"')
await page.click('text="Publish"')
await expect(
page.locator(
'text="You need to upgrade your plan in order to use file input blocks"'
)
).toBeVisible()
})
})

View File

@ -0,0 +1,3 @@
export { FileInputSettings } from './components/FileInputSettings'
export { FileInputContent } from './components/FileInputContent'
export { FileInputIcon } from './components/FileInputIcon'