From 55108c80e88ca3395e41f6e8887988bc7c06ae37 Mon Sep 17 00:00:00 2001 From: Baptiste Arnaud Date: Sat, 25 Jun 2022 09:24:47 +0200 Subject: [PATCH] =?UTF-8?q?feat(bot):=20=E2=9A=A1=EF=B8=8F=20Add=20require?= =?UTF-8?q?d=20option=20on=20file=20upload=20input?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bodies/FileInputSettings.tsx | 12 ++++- .../playwright/tests/inputs/file.spec.ts | 3 ++ .../playwright/tests/fileUpload.spec.ts | 3 +- .../ChatGroup/ChatBlock/InputChatBlock.tsx | 9 +++- .../ChatBlock/inputs/FileUploadForm.tsx | 16 ++++++- .../src/components/ChatGroup/ChatGroup.tsx | 44 ++++++++++++------- .../models/src/typebot/blocks/input/file.ts | 2 + 7 files changed, 67 insertions(+), 22 deletions(-) diff --git a/apps/builder/components/shared/Graph/Nodes/BlockNode/SettingsPopoverContent/bodies/FileInputSettings.tsx b/apps/builder/components/shared/Graph/Nodes/BlockNode/SettingsPopoverContent/bodies/FileInputSettings.tsx index fae6042452..f28124d727 100644 --- a/apps/builder/components/shared/Graph/Nodes/BlockNode/SettingsPopoverContent/bodies/FileInputSettings.tsx +++ b/apps/builder/components/shared/Graph/Nodes/BlockNode/SettingsPopoverContent/bodies/FileInputSettings.tsx @@ -17,19 +17,27 @@ export const FileInputSettings = ({ options, onOptionsChange }: Props) => { onOptionsChange({ ...options, labels: { ...options.labels, button } }) const handlePlaceholderLabelChange = (placeholder: string) => onOptionsChange({ ...options, labels: { ...options.labels, placeholder } }) - const handleLongChange = (isMultipleAllowed: boolean) => + 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 ( + diff --git a/apps/builder/playwright/tests/inputs/file.spec.ts b/apps/builder/playwright/tests/inputs/file.spec.ts index ee97fb72b4..b55f5607ea 100644 --- a/apps/builder/playwright/tests/inputs/file.spec.ts +++ b/apps/builder/playwright/tests/inputs/file.spec.ts @@ -29,16 +29,19 @@ test('options should work', async ({ page }) => { 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([path.join(__dirname, '../../fixtures/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]', 'Upload now!!') 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"]`) diff --git a/apps/viewer/playwright/tests/fileUpload.spec.ts b/apps/viewer/playwright/tests/fileUpload.spec.ts index 284db9e631..d7963525f6 100644 --- a/apps/viewer/playwright/tests/fileUpload.spec.ts +++ b/apps/viewer/playwright/tests/fileUpload.spec.ts @@ -5,9 +5,8 @@ import { parse } from 'papaparse' import { typebotViewer } from '../services/selectorUtils' import { importTypebotInDatabase } from '../services/database' import { readFileSync } from 'fs' -import { isDefined } from 'utils' -test('should work as expected', async ({ page, browser }) => { +test('should work as expected', async ({ page }) => { const typebotId = cuid() await importTypebotInDatabase( path.join(__dirname, '../fixtures/typebots/fileUpload.json'), diff --git a/packages/bot-engine/src/components/ChatGroup/ChatBlock/InputChatBlock.tsx b/packages/bot-engine/src/components/ChatGroup/ChatBlock/InputChatBlock.tsx index 194188bac0..6e7ad4df24 100644 --- a/packages/bot-engine/src/components/ChatGroup/ChatBlock/InputChatBlock.tsx +++ b/packages/bot-engine/src/components/ChatGroup/ChatBlock/InputChatBlock.tsx @@ -24,6 +24,7 @@ export const InputChatBlock = ({ hasAvatar, hasGuestAvatar, onTransitionEnd, + onSkip, }: { block: InputBlock hasGuestAvatar: boolean @@ -32,6 +33,7 @@ export const InputChatBlock = ({ answerContent?: InputSubmitContent, isRetry?: boolean ) => void + onSkip: () => void }) => { const { typebot } = useTypebot() const { addAnswer } = useAnswers() @@ -84,6 +86,7 @@ export const InputChatBlock = ({ @@ -94,11 +97,13 @@ export const InputChatBlock = ({ const Input = ({ block, onSubmit, + onSkip, defaultValue, hasGuestAvatar, }: { block: InputBlock onSubmit: (value: InputSubmitContent) => void + onSkip: () => void defaultValue?: string hasGuestAvatar: boolean }) => { @@ -132,6 +137,8 @@ const Input = ({ case InputBlockType.RATING: return case InputBlockType.FILE: - return + return ( + + ) } } diff --git a/packages/bot-engine/src/components/ChatGroup/ChatBlock/inputs/FileUploadForm.tsx b/packages/bot-engine/src/components/ChatGroup/ChatBlock/inputs/FileUploadForm.tsx index 0fcd461e25..0df9825fef 100644 --- a/packages/bot-engine/src/components/ChatGroup/ChatBlock/inputs/FileUploadForm.tsx +++ b/packages/bot-engine/src/components/ChatGroup/ChatBlock/inputs/FileUploadForm.tsx @@ -9,14 +9,16 @@ import { SendButton, Spinner } from './SendButton' type Props = { block: FileInputBlock onSubmit: (url: InputSubmitContent) => void + onSkip: () => void } export const FileUploadForm = ({ block: { id, - options: { isMultipleAllowed, labels, sizeLimit }, + options: { isMultipleAllowed, labels, sizeLimit, isRequired }, }, onSubmit, + onSkip, }: Props) => { const { isPreview, @@ -169,6 +171,18 @@ export const FileUploadForm = ({ )} + {selectedFiles.length === 0 && isRequired === false && ( +
+ +
+ )} {isMultipleAllowed && selectedFiles.length > 0 && !isUploading && (
diff --git a/packages/bot-engine/src/components/ChatGroup/ChatGroup.tsx b/packages/bot-engine/src/components/ChatGroup/ChatGroup.tsx index 61be91f9bd..ed6be63fb2 100644 --- a/packages/bot-engine/src/components/ChatGroup/ChatGroup.tsx +++ b/packages/bot-engine/src/components/ChatGroup/ChatGroup.tsx @@ -243,6 +243,8 @@ const ChatChunks = ({ keepShowingHostAvatar, onDisplayNextBlock, }: Props) => { + const [isSkipped, setIsSkipped] = useState(false) + // eslint-disable-next-line @typescript-eslint/no-explicit-any const avatarSideContainerRef = useRef() @@ -250,6 +252,11 @@ const ChatChunks = ({ refreshTopOffset() }) + const skipInput = () => { + onDisplayNextBlock() + setIsSkipped(true) + } + const refreshTopOffset = () => avatarSideContainerRef.current?.refreshTopOffset() @@ -260,7 +267,9 @@ const ChatChunks = ({ )}
- - {input && ( - - )} - + {!isSkipped && ( + + {input && ( + + )} + + )} ) } diff --git a/packages/models/src/typebot/blocks/input/file.ts b/packages/models/src/typebot/blocks/input/file.ts index cea8b91a58..9a2687eaf7 100644 --- a/packages/models/src/typebot/blocks/input/file.ts +++ b/packages/models/src/typebot/blocks/input/file.ts @@ -3,6 +3,7 @@ import { InputBlockType, optionBaseSchema, blockBaseSchema } from '../shared' export const fileInputOptionsSchema = optionBaseSchema.and( z.object({ + isRequired: z.boolean().optional(), isMultipleAllowed: z.boolean(), labels: z.object({ placeholder: z.string(), @@ -20,6 +21,7 @@ export const fileInputStepSchema = blockBaseSchema.and( ) export const defaultFileInputOptions: FileInputOptions = { + isRequired: true, isMultipleAllowed: false, labels: { placeholder: `