diff --git a/packages/toolkit/package.json b/packages/toolkit/package.json index b221e3d8..5368ebec 100644 --- a/packages/toolkit/package.json +++ b/packages/toolkit/package.json @@ -1,6 +1,6 @@ { "name": "@instill-ai/toolkit", - "version": "0.68.3-rc.53", + "version": "0.68.3-rc.55", "description": "Instill AI's frontend toolkit", "repository": "https://github.com/instill-ai/design-system.git", "bugs": "https://github.com/instill-ai/design-system/issues", diff --git a/packages/toolkit/src/view/data/DataComponentForm.tsx b/packages/toolkit/src/view/data/DataComponentForm.tsx index ee984882..87be41b2 100644 --- a/packages/toolkit/src/view/data/DataComponentForm.tsx +++ b/packages/toolkit/src/view/data/DataComponentForm.tsx @@ -155,7 +155,7 @@ export const DataResourceSchema = z ctx.addIssue({ code: z.ZodIssueCode.custom, message: "object_name is required", - path: ["object_name"], + path: ["input.object_name"], }); } else { const result = validateIntillUpstreamTypes({ @@ -167,7 +167,7 @@ export const DataResourceSchema = z ctx.addIssue({ code: z.ZodIssueCode.custom, message: result.error, - path: ["object_name"], + path: ["input.object_name"], }); } } @@ -176,7 +176,7 @@ export const DataResourceSchema = z ctx.addIssue({ code: z.ZodIssueCode.custom, message: "data is required", - path: ["data"], + path: ["input.data"], }); } else { const result = validateIntillUpstreamTypes({ @@ -188,7 +188,7 @@ export const DataResourceSchema = z ctx.addIssue({ code: z.ZodIssueCode.custom, message: result.error, - path: ["data"], + path: ["input.data"], }); } } @@ -230,10 +230,23 @@ export const DataComponentForm = ({ ...configuration, connector_definition_name: connectorDefinitionName, input: configuration.input ? configuration.input : {}, + task: configuration.task + ? configuration.task + : connectorDefinitionName === "connector-definitions/data-gcs" + ? "TASK_UPLOAD" + : "", }, }); - const { reset, watch } = form; + const { + reset, + watch, + formState: { errors }, + } = form; + + React.useEffect(() => { + console.log(errors); + }, [errors]); React.useEffect(() => { reset({ @@ -247,6 +260,8 @@ export const DataComponentForm = ({ if (!selectedConnectorNodeId) return; const modifiedData = recursiveReplaceNullAndEmptyStringWithUndefined(data); + console.log(modifiedData); + const newNodes = nodes.map((node) => { if ( node.id === selectedConnectorNodeId && @@ -269,8 +284,6 @@ export const DataComponentForm = ({ return node; }); - console.log(newNodes); - updateNodes(() => newNodes); const allReferences: PipelineComponentReference[] = []; @@ -319,7 +332,7 @@ export const DataComponentForm = ({ - The name of the object to be created + The name of the object to be created. @@ -348,7 +361,7 @@ export const DataComponentForm = ({ - The data to be saved in the object + The data to be saved in the object. diff --git a/packages/toolkit/src/view/pipeline-builder/RightPanel.tsx b/packages/toolkit/src/view/pipeline-builder/RightPanel.tsx index b66a92fd..40461830 100644 --- a/packages/toolkit/src/view/pipeline-builder/RightPanel.tsx +++ b/packages/toolkit/src/view/pipeline-builder/RightPanel.tsx @@ -41,35 +41,6 @@ export const RightPanel = () => { - {selectedConnectorNode ? ( -
-
- Resource -
- {selectedConnectorNode.data.nodeType !== "end" && - selectedConnectorNode.data.nodeType !== "start" ? ( -
-
-
- - } - /> -
-

- {selectedConnectorNode.data.component?.resource?.id} -

-
- -
- ) : null} -
- ) : null}

diff --git a/packages/toolkit/src/view/pipeline-builder/components/connector-node/ConnectorNode.tsx b/packages/toolkit/src/view/pipeline-builder/components/connector-node/ConnectorNode.tsx index dd63faec..d1a6841f 100644 --- a/packages/toolkit/src/view/pipeline-builder/components/connector-node/ConnectorNode.tsx +++ b/packages/toolkit/src/view/pipeline-builder/components/connector-node/ConnectorNode.tsx @@ -896,7 +896,7 @@ export const ConnectorNode = ({ data, id }: NodeProps) => { key={ property.title ? property.title : property.path } - className="w-full rounded-[6px] bg-semantic-bg-primary p-2" + className="w-full rounded-[6px] bg-semantic-bg-primary" >

{items.map((item) => ( diff --git a/packages/toolkit/src/view/pipeline-builder/components/connector-node/InputPropertyItem.tsx b/packages/toolkit/src/view/pipeline-builder/components/connector-node/InputPropertyItem.tsx index a0b5044a..979f6daf 100644 --- a/packages/toolkit/src/view/pipeline-builder/components/connector-node/InputPropertyItem.tsx +++ b/packages/toolkit/src/view/pipeline-builder/components/connector-node/InputPropertyItem.tsx @@ -55,7 +55,7 @@ const InputPropertyValue = (props: { if (!reference || !reference.nodeId) { return propertyConfiguration ? ( -
+
{propertyConfiguration}
) : null; diff --git a/packages/toolkit/src/view/pipeline-builder/lib/getConnectorInputOutputSchema.ts b/packages/toolkit/src/view/pipeline-builder/lib/getConnectorInputOutputSchema.ts index 1df2ba1a..2362ec6f 100644 --- a/packages/toolkit/src/view/pipeline-builder/lib/getConnectorInputOutputSchema.ts +++ b/packages/toolkit/src/view/pipeline-builder/lib/getConnectorInputOutputSchema.ts @@ -21,42 +21,53 @@ export function getConnectorInputOutputSchema( // If the component has task field in its component_configuration, it means it has complicate category // The category will be replaces with the task in the component_configuration - const hasTaskField = checkHasTaskField( - component.connector_definition.spec.component_specification - ); - - if (hasTaskField) { - if (component.configuration.task) { - inputSchema = ( + if (component.configuration.task) { + inputSchema = ( + ( + ( + component?.connector_definition?.spec.openapi_specifications[ + component.configuration.task + ].paths["/execute"]?.post + ?.requestBody as OpenAPIV3.RequestBodyObject + ).content["application/json"]?.schema as OpenAPIV3.SchemaObject + ).properties?.inputs as OpenAPIV3.ArraySchemaObject + ).items as OpenAPIV3.SchemaObject; + outputSchema = ( + ( ( ( component?.connector_definition?.spec.openapi_specifications[ component.configuration.task - ].paths["/execute"]?.post - ?.requestBody as OpenAPIV3.RequestBodyObject - ).content["application/json"]?.schema as OpenAPIV3.SchemaObject - ).properties?.inputs as OpenAPIV3.ArraySchemaObject - ).items as OpenAPIV3.SchemaObject; - outputSchema = ( + ].paths["/execute"]?.post?.responses[ + "200" + ] as OpenAPIV3.ResponseObject + ).content as { [key: string]: OpenAPIV3.MediaTypeObject } + )["application/json"]?.schema as OpenAPIV3.SchemaObject + ).properties?.outputs as OpenAPIV3.ArraySchemaObject + ).items as OpenAPIV3.SchemaObject; + } else if ( + component.connector_definition.spec.component_specification.oneOf && + component.connector_definition.spec.component_specification.oneOf + .length > 0 + ) { + const defaultTask = + (( ( - ( - ( - component?.connector_definition?.spec.openapi_specifications[ - component.configuration.task - ].paths["/execute"]?.post?.responses[ - "200" - ] as OpenAPIV3.ResponseObject - ).content as { [key: string]: OpenAPIV3.MediaTypeObject } - )["application/json"]?.schema as OpenAPIV3.SchemaObject - ).properties?.outputs as OpenAPIV3.ArraySchemaObject - ).items as OpenAPIV3.SchemaObject; + component.connector_definition.spec.component_specification + .oneOf[0] as JSONSchema7 + )?.properties?.task as JSONSchema7 + )?.const as string) ?? null; + + if (!defaultTask) { + return { outputSchema, inputSchema }; } - } else { + inputSchema = ( ( ( - component.connector_definition.spec.openapi_specifications.default - .paths["/execute"]?.post + component?.connector_definition?.spec.openapi_specifications[ + defaultTask + ].paths["/execute"]?.post ?.requestBody as OpenAPIV3.RequestBodyObject ).content["application/json"]?.schema as OpenAPIV3.SchemaObject ).properties?.inputs as OpenAPIV3.ArraySchemaObject @@ -65,8 +76,9 @@ export function getConnectorInputOutputSchema( ( ( ( - component.connector_definition?.spec.openapi_specifications - .default.paths["/execute"]?.post?.responses[ + component?.connector_definition?.spec.openapi_specifications[ + defaultTask + ].paths["/execute"]?.post?.responses[ "200" ] as OpenAPIV3.ResponseObject ).content as { [key: string]: OpenAPIV3.MediaTypeObject } diff --git a/packages/toolkit/src/view/pipeline-builder/lib/getPropertiesFromOpenAPISchema.ts b/packages/toolkit/src/view/pipeline-builder/lib/getPropertiesFromOpenAPISchema.ts index 66f5a8b6..852aae74 100644 --- a/packages/toolkit/src/view/pipeline-builder/lib/getPropertiesFromOpenAPISchema.ts +++ b/packages/toolkit/src/view/pipeline-builder/lib/getPropertiesFromOpenAPISchema.ts @@ -23,7 +23,8 @@ export function getPropertiesFromOpenAPISchema( ...properties, ...getPropertiesFromOpenAPISchema( value, - [...parentKeyList, key].join(".") + [...parentKeyList, key].join("."), + key ), ]; } @@ -37,10 +38,11 @@ export function getPropertiesFromOpenAPISchema( items: getPropertiesFromOpenAPISchema( schema.items as OpenAPIV3.SchemaObject, parentKey, - schema.title, + undefined, true ) as OpenAPIV3.ArraySchemaObject["items"], path: parentKey, + title: schema.title ? schema.title : title, }, ]; } else { @@ -50,7 +52,7 @@ export function getPropertiesFromOpenAPISchema( properties.push({ path: parentKey, ...schema, - title: title ? title : schema.title, + title: schema.title ? schema.title : title, }); } } diff --git a/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/ArrayObjectField.tsx b/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/ArrayObjectField.tsx new file mode 100644 index 00000000..bd7640e3 --- /dev/null +++ b/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/ArrayObjectField.tsx @@ -0,0 +1,27 @@ +import * as React from "react"; +import { Nullable } from "../../../lib"; +import { ConnectorNodeFieldRoot, EndNodeFieldRoot } from "./FieldRoot"; + +export type ArrayObjectFieldProps = { + nodeType: "end" | "connector"; + title: Nullable; + children: React.ReactNode; +}; + +export const ArrayObjectField = (props: ArrayObjectFieldProps) => { + const { nodeType, title, children } = props; + + if (nodeType === "connector") { + return ( + + {children} + + ); + } + + return ( + + {children} + + ); +}; diff --git a/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/FieldRoot.tsx b/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/FieldRoot.tsx index 180a0117..2f0adf5b 100644 --- a/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/FieldRoot.tsx +++ b/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/FieldRoot.tsx @@ -1,3 +1,4 @@ +import cn from "clsx"; import * as React from "react"; import { Nullable } from "../../../lib"; @@ -5,15 +6,20 @@ export const ConnectorNodeFieldRoot = ({ key, title, children, + className, }: { key: string; title: Nullable; children: React.ReactNode; + className?: string; }) => { return (

{title} @@ -27,15 +33,20 @@ export const EndNodeFieldRoot = ({ key, title, children, + className, }: { key: string; title: Nullable; children: React.ReactNode; + className?: string; }) => { return (

{title} diff --git a/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/ObjectField.tsx b/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/ObjectField.tsx index 6902eb95..7cba3c0f 100644 --- a/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/ObjectField.tsx +++ b/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/ObjectField.tsx @@ -14,7 +14,7 @@ export const ObjectField = (props: ObjectFieldProps) => { return (

-
+          
             {JSON.stringify(object, null, 2)}
           
@@ -25,7 +25,7 @@ export const ObjectField = (props: ObjectFieldProps) => { return (
-
+        
           {JSON.stringify(object, null, 2)}
         
diff --git a/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/ObjectsField.tsx b/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/ObjectsField.tsx index 21720d3f..4b8b21e9 100644 --- a/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/ObjectsField.tsx +++ b/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/ObjectsField.tsx @@ -17,7 +17,7 @@ export const ObjectsField = (props: ObjectsFieldProps) => { {objects?.map((object) => (
               {JSON.stringify(object, null, 2)}
             
@@ -33,7 +33,7 @@ export const ObjectsField = (props: ObjectsFieldProps) => { {objects?.map((object) => (
             {JSON.stringify(object, null, 2)}
           
diff --git a/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/TextField.tsx b/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/TextField.tsx index 9933abf9..8b63ed05 100644 --- a/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/TextField.tsx +++ b/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/TextField.tsx @@ -15,7 +15,7 @@ export const TextField = (props: TextFieldProps) => { return (
-
+          
             {text}
           
{text ? ( @@ -32,7 +32,7 @@ export const TextField = (props: TextFieldProps) => { return (
-
+        
           {text}
         
{text ? ( diff --git a/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/TextsField.tsx b/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/TextsField.tsx index 0b0e0547..0304baee 100644 --- a/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/TextsField.tsx +++ b/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/TextsField.tsx @@ -19,7 +19,7 @@ export const TextsField = (props: TextsFieldProps) => { key={`${title}-${text}-field`} className="flex w-full p-2 relative border rounded-sm border-semantic-bg-line flex-row justify-between gap-x-2" > -
+            
               {text}
             
{text ? ( @@ -42,7 +42,7 @@ export const TextsField = (props: TextsFieldProps) => { key={`${title}-${text}-field`} className="flex w-full p-2 border border-semantic-bg-line rounded-sm relative flex-row justify-between gap-x-2" > -
+            
               {text}
             
{text ? ( diff --git a/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/useConnectorTestModeOutputFields.tsx b/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/useConnectorTestModeOutputFields.tsx index 8f9c93d4..f8d9e357 100644 --- a/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/useConnectorTestModeOutputFields.tsx +++ b/packages/toolkit/src/view/pipeline-builder/use-node-output-fields/useConnectorTestModeOutputFields.tsx @@ -12,6 +12,7 @@ import { AudiosField } from "./AudiosField"; import { Nullable, PipelineConnectorComponent, + PipelineTrace, TriggerUserPipelineResponse, } from "../../../lib"; import { @@ -21,6 +22,7 @@ import { } from "../lib"; import { ObjectField } from "./ObjectField"; import { ObjectsField } from "./ObjectsField"; +import { ArrayObjectField } from "./ArrayObjectField"; export function useConnectorTestModeOutputFields( component: PipelineConnectorComponent, @@ -28,7 +30,6 @@ export function useConnectorTestModeOutputFields( ) { const fields = React.useMemo(() => { let outputProperties: InstillAIOpenAPIProperty[] = []; - const fields: React.ReactElement[] = []; if (!component) { return []; @@ -42,123 +43,151 @@ export function useConnectorTestModeOutputFields( const trace = traces ? traces[component.id] : null; - for (const property of outputProperties) { - const title = property.path ? property.path : property.title ?? null; + console.log(outputProperties); - let propertyValue: any = null; + const fields = getOutputFieldComponent({ + properties: outputProperties, + trace, + }); - if (trace) { - if (property.path) { - propertyValue = trace.outputs[0][property.path]; - } - } + return fields; + }, [component, traces]); + + return fields; +} + +function getOutputFieldComponent({ + properties, + trace, +}: { + properties: InstillAIOpenAPIProperty[]; + trace: Nullable; +}): React.ReactElement[] { + const fields: React.ReactElement[] = []; - switch (property.instillFormat) { - case "text": { - fields.push( - - ); - break; - } - case "text_array": { - fields.push( - - ); - break; - } - case "image": { - fields.push( - - ); - break; - } - case "image_array": { - fields.push( - - ); - break; - } - case "number": { - fields.push( - - ); - break; - } - case "number_array": { - fields.push( - - ); - break; - } - case "audio": { - fields.push( - - ); - break; - } - case "audio_array": { - fields.push( - - ); - break; - } - case "object": { - fields.push( - - ); - break; - } - case "object_array": { - fields.push( - - ); - break; - } + for (const property of properties) { + const title = property.title ? property.title : property.path ?? null; + + let propertyValue: any = null; + + if (property.type === "array" && !property.instillFormat) { + const arrayFields = getOutputFieldComponent({ + properties: property.items as InstillAIOpenAPIProperty[], + trace, + }); + + fields.push( + + {arrayFields} + + ); + } + + if (trace) { + if (property.path) { + propertyValue = trace.outputs[0][property.path]; } } - return fields; - }, [component, traces]); + switch (property.instillFormat) { + case "text": { + fields.push( + + ); + break; + } + case "text_array": { + fields.push( + + ); + break; + } + case "image": { + fields.push( + + ); + break; + } + case "image_array": { + fields.push( + + ); + break; + } + case "number": { + fields.push( + + ); + break; + } + case "number_array": { + fields.push( + + ); + break; + } + case "audio": { + fields.push( + + ); + break; + } + case "audio_array": { + fields.push( + + ); + break; + } + case "object": { + fields.push( + + ); + break; + } + case "object_array": { + fields.push( + + ); + break; + } + } + } return fields; }