From 6bbc3d379d157718cfd0012ea24660f4cc96d8ff Mon Sep 17 00:00:00 2001 From: EiffelFly <57251712+EiffelFly@users.noreply.github.com> Date: Mon, 4 Nov 2024 18:38:43 +0800 Subject: [PATCH] feat: support document format --- packages/toolkit/src/constant/pipeline.ts | 15 ++++++ .../DownloadableFileField.tsx | 27 ++++++++++ .../DownloadableFilesField.tsx | 36 +++++++++++++ .../components/component-output/index.ts | 4 ++ .../trigger-request-form-fields/FileField.tsx | 6 ++- .../FilesField.tsx | 8 ++- ...mponentOutputFieldsFromInstillFormTree.tsx | 28 ++++++++-- .../pickPipelineTriggerRequestFormFields.tsx | 51 +++++++++++++++++++ ...nsformPipelineTriggerRequestFieldsToZod.ts | 2 + .../src/view/recipe-editor/VscodeEditor.tsx | 2 + 10 files changed, 171 insertions(+), 8 deletions(-) create mode 100644 packages/toolkit/src/lib/use-instill-form/components/component-output/DownloadableFileField.tsx create mode 100644 packages/toolkit/src/lib/use-instill-form/components/component-output/DownloadableFilesField.tsx diff --git a/packages/toolkit/src/constant/pipeline.ts b/packages/toolkit/src/constant/pipeline.ts index 186a8403cd..cfb92ae556 100644 --- a/packages/toolkit/src/constant/pipeline.ts +++ b/packages/toolkit/src/constant/pipeline.ts @@ -183,3 +183,18 @@ version: v1beta # Click "⌘O" to add a new component # component: `; + +export const DocumentInputAcceptMimeTypes = [ + "application/msword", + "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + "application/vnd.ms-powerpoint", + "application/vnd.openxmlformats-officedocument.presentationml.presentation", + "application/vnd.ms-excel", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + "text/html", + "text/plain", + "text", + "text/markdown", + "text/csv", + "application/pdf", +]; diff --git a/packages/toolkit/src/lib/use-instill-form/components/component-output/DownloadableFileField.tsx b/packages/toolkit/src/lib/use-instill-form/components/component-output/DownloadableFileField.tsx new file mode 100644 index 0000000000..c467c18e04 --- /dev/null +++ b/packages/toolkit/src/lib/use-instill-form/components/component-output/DownloadableFileField.tsx @@ -0,0 +1,27 @@ +"use client"; + +import { Nullable } from "../../../type"; +import { ComponentOutputFieldBaseProps } from "../../types"; +import { FieldRoot } from "./FieldRoot"; + +export type DownloadableFileFieldProps = { + file: Nullable; +} & ComponentOutputFieldBaseProps; + +export const DownloadableFileField = (props: DownloadableFileFieldProps) => { + const { title, hideField, file } = props; + + return ( + + {!hideField && file ? ( + + Download file + + ) : null} + + ); +}; diff --git a/packages/toolkit/src/lib/use-instill-form/components/component-output/DownloadableFilesField.tsx b/packages/toolkit/src/lib/use-instill-form/components/component-output/DownloadableFilesField.tsx new file mode 100644 index 0000000000..2a7cba0795 --- /dev/null +++ b/packages/toolkit/src/lib/use-instill-form/components/component-output/DownloadableFilesField.tsx @@ -0,0 +1,36 @@ +"use client"; + +import { Nullable } from "../../../type"; +import { ComponentOutputFieldBaseProps } from "../../types"; +import { FieldRoot } from "./FieldRoot"; + +export type DownloadableFilesFieldProps = { + files: Nullable[]; +} & ComponentOutputFieldBaseProps; + +export const DownloadableFilesField = (props: DownloadableFilesFieldProps) => { + const { title, hideField, files } = props; + + return ( + + {!hideField ? ( +
+ {files.map((file, index) => { + if (!file) return null; + + return ( + + Download file + + ); + })} +
+ ) : null} +
+ ); +}; diff --git a/packages/toolkit/src/lib/use-instill-form/components/component-output/index.ts b/packages/toolkit/src/lib/use-instill-form/components/component-output/index.ts index dcee27d412..3a125c5d1f 100644 --- a/packages/toolkit/src/lib/use-instill-form/components/component-output/index.ts +++ b/packages/toolkit/src/lib/use-instill-form/components/component-output/index.ts @@ -1,5 +1,7 @@ import { AudioField } from "./AudioField"; import { AudiosField } from "./AudiosField"; +import { DownloadableFileField } from "./DownloadableFileField"; +import { DownloadableFilesField } from "./DownloadableFilesField"; import { ImageField } from "./ImageField"; import { ImagesField } from "./ImagesField"; import { NumberField } from "./NumberField"; @@ -24,4 +26,6 @@ export const ComponentOutputFields = { TextsField, VideoField, VideosField, + DownloadableFileField, + DownloadableFilesField, }; diff --git a/packages/toolkit/src/lib/use-instill-form/components/trigger-request-form-fields/FileField.tsx b/packages/toolkit/src/lib/use-instill-form/components/trigger-request-form-fields/FileField.tsx index 1ba167b43a..f8713ab8c9 100644 --- a/packages/toolkit/src/lib/use-instill-form/components/trigger-request-form-fields/FileField.tsx +++ b/packages/toolkit/src/lib/use-instill-form/components/trigger-request-form-fields/FileField.tsx @@ -25,7 +25,9 @@ export const FileField = ({ disabledFieldControl, disabledReferenceHint, instillFormat, -}: StartOperatorFreeFormFieldBaseProps & AutoFormFieldBaseProps) => { + accept, +}: StartOperatorFreeFormFieldBaseProps & + AutoFormFieldBaseProps & { accept: string }) => { const [uploadedFile, setUploadedFiles] = React.useState>(); const inputRef = React.useRef(null); @@ -54,7 +56,7 @@ export const FileField = ({ ref={inputRef} title="Upload file" fieldKey={path} - accept="*/*" + accept={accept} onChange={async (e) => { const file = e.target.files?.[0]; if (file) { diff --git a/packages/toolkit/src/lib/use-instill-form/components/trigger-request-form-fields/FilesField.tsx b/packages/toolkit/src/lib/use-instill-form/components/trigger-request-form-fields/FilesField.tsx index 6398d6960a..1d743fa596 100644 --- a/packages/toolkit/src/lib/use-instill-form/components/trigger-request-form-fields/FilesField.tsx +++ b/packages/toolkit/src/lib/use-instill-form/components/trigger-request-form-fields/FilesField.tsx @@ -26,7 +26,11 @@ export const FilesField = ({ disabledFieldControl, disabledReferenceHint, instillFormat, -}: StartOperatorFreeFormFieldBaseProps & AutoFormFieldBaseProps) => { + accept, +}: StartOperatorFreeFormFieldBaseProps & + AutoFormFieldBaseProps & { + accept: string; + }) => { const [uploadedFiles, setUploadedFiles] = React.useState([]); const inputRef = React.useRef(null); @@ -56,7 +60,7 @@ export const FilesField = ({ keyPrefix={keyPrefix} title="Upload files" fieldKey={path} - accept="*/*" + accept={accept} multiple={true} onChange={async (e) => { if (e.target.files && e.target.files.length > 0) { diff --git a/packages/toolkit/src/lib/use-instill-form/pick/pickComponentOutputFieldsFromInstillFormTree.tsx b/packages/toolkit/src/lib/use-instill-form/pick/pickComponentOutputFieldsFromInstillFormTree.tsx index f4ba7f5fbe..32bbcbda8e 100644 --- a/packages/toolkit/src/lib/use-instill-form/pick/pickComponentOutputFieldsFromInstillFormTree.tsx +++ b/packages/toolkit/src/lib/use-instill-form/pick/pickComponentOutputFieldsFromInstillFormTree.tsx @@ -213,7 +213,7 @@ export function pickComponentOutputFieldsFromInstillFormTree( if (tree.instillFormat.includes("array:")) { const arrayType = tree.instillFormat.replaceAll("array:", "").split("/")[0]; - if (arrayType?.includes("structured")) { + if (arrayType?.includes("structured") || arrayType === "json") { // Some time even the type hint is array:semi-structured, backend will still be possible // to return array of string or array of number. So we need to handle that case here if (Array.isArray(propertyValue) && propertyValue.length > 0) { @@ -309,7 +309,16 @@ export function pickComponentOutputFieldsFromInstillFormTree( /> ); } - + case "document": { + return ( + + ); + } default: { return ( ); } - case "semi-structured": { + case "semi-structured": + case "json": { return ( ); } + case "document": { + return ( + + ); + } default: { return ( ), }); @@ -398,6 +400,55 @@ export function pickPipelineTriggerRequestFormFields({ disabledFieldControl={disabledFieldControls} disabledReferenceHint={disabledReferenceHint} instillFormat={value.instillFormat} + accept="*/*" + /> + ), + }); + break; + case "document": + items.push({ + key, + instillUIOrder: value.instillUiOrder, + component: ( + + ), + }); + break; + case "array:document": + items.push({ + key, + instillUIOrder: value.instillUiOrder, + component: ( + ), }); diff --git a/packages/toolkit/src/lib/use-instill-form/transform/transformPipelineTriggerRequestFieldsToZod.ts b/packages/toolkit/src/lib/use-instill-form/transform/transformPipelineTriggerRequestFieldsToZod.ts index 57ff8b1cf8..96a59c3b23 100644 --- a/packages/toolkit/src/lib/use-instill-form/transform/transformPipelineTriggerRequestFieldsToZod.ts +++ b/packages/toolkit/src/lib/use-instill-form/transform/transformPipelineTriggerRequestFieldsToZod.ts @@ -79,10 +79,12 @@ export function transformPipelineTriggerRequestFieldsToZod( break; case "file": case "*/*": + case "document": zodSchema = zodSchema.setKey(key, z.string().nullable().optional()); break; case "array:file": case "array:*/*": + case "array:document": zodSchema = zodSchema.setKey( key, z.array(z.string().nullable().optional()).nullable().optional(), diff --git a/packages/toolkit/src/view/recipe-editor/VscodeEditor.tsx b/packages/toolkit/src/view/recipe-editor/VscodeEditor.tsx index bf2e57cc3a..e6a9bf6888 100644 --- a/packages/toolkit/src/view/recipe-editor/VscodeEditor.tsx +++ b/packages/toolkit/src/view/recipe-editor/VscodeEditor.tsx @@ -84,6 +84,8 @@ const availableInstillFormats = [ "array:file", "json", "array:json", + "document", + "array:document", ]; const componentTopLevelKeys = ["type", "input", "setup", "condition", "task"];