🚸 (fileUpload) Add clear and skip button labels customization
This commit is contained in:
@ -14,16 +14,28 @@ type Props = {
|
|||||||
export const FileInputSettings = ({ options, onOptionsChange }: Props) => {
|
export const FileInputSettings = ({ options, onOptionsChange }: Props) => {
|
||||||
const handleButtonLabelChange = (button: string) =>
|
const handleButtonLabelChange = (button: string) =>
|
||||||
onOptionsChange({ ...options, labels: { ...options.labels, button } })
|
onOptionsChange({ ...options, labels: { ...options.labels, button } })
|
||||||
|
|
||||||
const handlePlaceholderLabelChange = (placeholder: string) =>
|
const handlePlaceholderLabelChange = (placeholder: string) =>
|
||||||
onOptionsChange({ ...options, labels: { ...options.labels, placeholder } })
|
onOptionsChange({ ...options, labels: { ...options.labels, placeholder } })
|
||||||
|
|
||||||
const handleMultipleFilesChange = (isMultipleAllowed: boolean) =>
|
const handleMultipleFilesChange = (isMultipleAllowed: boolean) =>
|
||||||
onOptionsChange({ ...options, isMultipleAllowed })
|
onOptionsChange({ ...options, isMultipleAllowed })
|
||||||
|
|
||||||
const handleVariableChange = (variable?: Variable) =>
|
const handleVariableChange = (variable?: Variable) =>
|
||||||
onOptionsChange({ ...options, variableId: variable?.id })
|
onOptionsChange({ ...options, variableId: variable?.id })
|
||||||
|
|
||||||
const handleSizeLimitChange = (sizeLimit?: number) =>
|
const handleSizeLimitChange = (sizeLimit?: number) =>
|
||||||
onOptionsChange({ ...options, sizeLimit })
|
onOptionsChange({ ...options, sizeLimit })
|
||||||
|
|
||||||
const handleRequiredChange = (isRequired: boolean) =>
|
const handleRequiredChange = (isRequired: boolean) =>
|
||||||
onOptionsChange({ ...options, isRequired })
|
onOptionsChange({ ...options, isRequired })
|
||||||
|
|
||||||
|
const updateClearButtonLabel = (clear: string) =>
|
||||||
|
onOptionsChange({ ...options, labels: { ...options.labels, clear } })
|
||||||
|
|
||||||
|
const updateSkipButtonLabel = (skip: string) =>
|
||||||
|
onOptionsChange({ ...options, labels: { ...options.labels, skip } })
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack spacing={4}>
|
<Stack spacing={4}>
|
||||||
<SwitchWithLabel
|
<SwitchWithLabel
|
||||||
@ -56,17 +68,24 @@ export const FileInputSettings = ({ options, onOptionsChange }: Props) => {
|
|||||||
withVariableButton={false}
|
withVariableButton={false}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack>
|
<Input
|
||||||
<FormLabel mb="0" htmlFor="button">
|
label="Button label:"
|
||||||
Button label:
|
defaultValue={options.labels.button}
|
||||||
</FormLabel>
|
onChange={handleButtonLabelChange}
|
||||||
<Input
|
withVariableButton={false}
|
||||||
id="button"
|
/>
|
||||||
defaultValue={options.labels.button}
|
<Input
|
||||||
onChange={handleButtonLabelChange}
|
label="Clear button label:"
|
||||||
withVariableButton={false}
|
defaultValue={options.labels.clear}
|
||||||
/>
|
onChange={updateClearButtonLabel}
|
||||||
</Stack>
|
withVariableButton={false}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
label="Skip button label:"
|
||||||
|
defaultValue={options.labels.skip}
|
||||||
|
onChange={updateSkipButtonLabel}
|
||||||
|
withVariableButton={false}
|
||||||
|
/>
|
||||||
<Stack>
|
<Stack>
|
||||||
<FormLabel mb="0" htmlFor="variable">
|
<FormLabel mb="0" htmlFor="variable">
|
||||||
Save upload URL{options.isMultipleAllowed ? 's' : ''} in a variable:
|
Save upload URL{options.isMultipleAllowed ? 's' : ''} in a variable:
|
||||||
|
@ -37,9 +37,11 @@ test('options should work', async ({ page }) => {
|
|||||||
await page.click('text="Allow multiple files?"')
|
await page.click('text="Allow multiple files?"')
|
||||||
await page.fill('div[contenteditable=true]', '<strong>Upload now!!</strong>')
|
await page.fill('div[contenteditable=true]', '<strong>Upload now!!</strong>')
|
||||||
await page.fill('[value="Upload"]', 'Go')
|
await page.fill('[value="Upload"]', 'Go')
|
||||||
|
await page.fill('[value="Clear"]', 'Reset')
|
||||||
|
await page.fill('[value="Skip"]', 'Pass')
|
||||||
await page.fill('input[value="10"]', '20')
|
await page.fill('input[value="10"]', '20')
|
||||||
await page.click('text="Restart"')
|
await page.click('text="Restart"')
|
||||||
await expect(typebotViewer(page).locator(`text="Skip"`)).toBeVisible()
|
await expect(typebotViewer(page).locator(`text="Pass"`)).toBeVisible()
|
||||||
await expect(typebotViewer(page).locator(`text="Upload now!!"`)).toBeVisible()
|
await expect(typebotViewer(page).locator(`text="Upload now!!"`)).toBeVisible()
|
||||||
await typebotViewer(page)
|
await typebotViewer(page)
|
||||||
.locator(`input[type="file"]`)
|
.locator(`input[type="file"]`)
|
||||||
@ -49,7 +51,7 @@ test('options should work', async ({ page }) => {
|
|||||||
getTestAsset('avatar.jpg'),
|
getTestAsset('avatar.jpg'),
|
||||||
])
|
])
|
||||||
await expect(typebotViewer(page).locator(`text="3"`)).toBeVisible()
|
await expect(typebotViewer(page).locator(`text="3"`)).toBeVisible()
|
||||||
await typebotViewer(page).locator('text="Go 3 files"').click()
|
await typebotViewer(page).locator('text="Go"').click()
|
||||||
await expect(
|
await expect(
|
||||||
typebotViewer(page).locator(`text="3 files uploaded"`)
|
typebotViewer(page).locator(`text="3 files uploaded"`)
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
|
@ -2,7 +2,7 @@ import { Spinner, SendButton } from '@/components/SendButton'
|
|||||||
import { useAnswers } from '@/providers/AnswersProvider'
|
import { useAnswers } from '@/providers/AnswersProvider'
|
||||||
import { useTypebot } from '@/providers/TypebotProvider'
|
import { useTypebot } from '@/providers/TypebotProvider'
|
||||||
import { InputSubmitContent } from '@/types'
|
import { InputSubmitContent } from '@/types'
|
||||||
import { FileInputBlock } from 'models'
|
import { defaultFileInputOptions, FileInputBlock } from 'models'
|
||||||
import React, { ChangeEvent, FormEvent, useState, DragEvent } from 'react'
|
import React, { ChangeEvent, FormEvent, useState, DragEvent } from 'react'
|
||||||
import { uploadFiles } from 'utils'
|
import { uploadFiles } from 'utils'
|
||||||
|
|
||||||
@ -181,7 +181,7 @@ export const FileUploadForm = ({
|
|||||||
}
|
}
|
||||||
onClick={onSkip}
|
onClick={onSkip}
|
||||||
>
|
>
|
||||||
Skip
|
{labels.skip ?? defaultFileInputOptions.labels.skip}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -195,17 +195,17 @@ export const FileUploadForm = ({
|
|||||||
}
|
}
|
||||||
onClick={clearFiles}
|
onClick={clearFiles}
|
||||||
>
|
>
|
||||||
Clear
|
{labels.clear ?? defaultFileInputOptions.labels.clear}
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
<SendButton
|
<SendButton
|
||||||
type="submit"
|
type="submit"
|
||||||
label={
|
label={
|
||||||
labels.button
|
labels.button === defaultFileInputOptions.labels.button
|
||||||
? `${labels.button} ${selectedFiles.length} file${
|
? `${labels.button} ${selectedFiles.length} file${
|
||||||
selectedFiles.length > 1 ? 's' : ''
|
selectedFiles.length > 1 ? 's' : ''
|
||||||
}`
|
}`
|
||||||
: 'Upload'
|
: labels.button
|
||||||
}
|
}
|
||||||
disableIcon
|
disableIcon
|
||||||
/>
|
/>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { SendButton, Spinner } from '@/components/SendButton'
|
import { SendButton, Spinner } from '@/components/SendButton'
|
||||||
import { BotContext, InputSubmitContent } from '@/types'
|
import { BotContext, InputSubmitContent } from '@/types'
|
||||||
import { FileInputBlock } from 'models'
|
import { defaultFileInputOptions, FileInputBlock } from 'models'
|
||||||
import { createSignal, Match, Show, Switch } from 'solid-js'
|
import { createSignal, Match, Show, Switch } from 'solid-js'
|
||||||
import { uploadFiles } from 'utils'
|
import { uploadFiles } from 'utils'
|
||||||
|
|
||||||
@ -179,7 +179,8 @@ export const FileUploadForm = (props: Props) => {
|
|||||||
}
|
}
|
||||||
onClick={() => props.onSkip()}
|
onClick={() => props.onSkip()}
|
||||||
>
|
>
|
||||||
Skip
|
{props.block.options.labels.skip ??
|
||||||
|
defaultFileInputOptions.labels.skip}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
</Show>
|
||||||
@ -199,15 +200,17 @@ export const FileUploadForm = (props: Props) => {
|
|||||||
}
|
}
|
||||||
onClick={clearFiles}
|
onClick={clearFiles}
|
||||||
>
|
>
|
||||||
Clear
|
{props.block.options.labels.clear ??
|
||||||
|
defaultFileInputOptions.labels.clear}
|
||||||
</button>
|
</button>
|
||||||
</Show>
|
</Show>
|
||||||
<SendButton type="submit" disableIcon>
|
<SendButton type="submit" disableIcon>
|
||||||
{props.block.options.labels.button
|
{props.block.options.labels.button ===
|
||||||
? `${props.block.options.labels.button} ${
|
defaultFileInputOptions.labels.button
|
||||||
selectedFiles().length
|
? `Upload ${selectedFiles().length} file${
|
||||||
} file${selectedFiles().length > 1 ? 's' : ''}`
|
selectedFiles().length > 1 ? 's' : ''
|
||||||
: 'Upload'}
|
}`
|
||||||
|
: props.block.options.labels.button}
|
||||||
</SendButton>
|
</SendButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -8,6 +8,8 @@ export const fileInputOptionsSchema = optionBaseSchema.and(
|
|||||||
labels: z.object({
|
labels: z.object({
|
||||||
placeholder: z.string(),
|
placeholder: z.string(),
|
||||||
button: z.string(),
|
button: z.string(),
|
||||||
|
clear: z.string().optional(),
|
||||||
|
skip: z.string().optional(),
|
||||||
}),
|
}),
|
||||||
sizeLimit: z.number().optional(),
|
sizeLimit: z.number().optional(),
|
||||||
})
|
})
|
||||||
@ -29,6 +31,8 @@ export const defaultFileInputOptions: FileInputOptions = {
|
|||||||
</strong> or drag and drop<br>
|
</strong> or drag and drop<br>
|
||||||
(size limit: 10MB)`,
|
(size limit: 10MB)`,
|
||||||
button: 'Upload',
|
button: 'Upload',
|
||||||
|
clear: 'Clear',
|
||||||
|
skip: 'Skip',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user