From 23ce0eb194b645344177e572f3d5b37db0ad5277 Mon Sep 17 00:00:00 2001 From: Po Chun Chiu <57251712+EiffelFly@users.noreply.github.com> Date: Wed, 14 Feb 2024 23:53:54 +0800 Subject: [PATCH] feat(auto-gen-form): handle Airbyte form and instill data form separately (#956) Because - handle Airbyte form and instill data form separately This commit - handle Airbyte form and instill data form separately --- .../components/UploadAvatarFieldWithCrop.tsx | 1 - .../mgmt/useAuthenticatedUser.ts | 2 +- .../lib/react-query-service/mgmt/useUser.tsx | 2 +- .../components/common/VideoPreview.tsx | 2 - .../smart-hint/SmartHintInfoCard.tsx | 1 - .../components/smart-hint/SmartHintList.tsx | 4 +- .../components/smart-hint/TextArea.tsx | 5 - .../components/smart-hint/TextField.tsx | 5 - .../AudioField.tsx | 1 - .../AudiosField.tsx | 1 - .../BooleanField.tsx | 1 - .../FieldHead.tsx | 10 +- .../FileField.tsx | 1 - .../FilesField.tsx | 1 - .../ImageField.tsx | 1 - .../ImagesField.tsx | 1 - .../LongTextField.tsx | 1 - .../NumberField.tsx | 1 - .../NumbersField.tsx | 1 - .../ObjectField.tsx | 1 - .../TextField.tsx | 1 - .../TextareaField.tsx | 1 - .../TextsField.tsx | 1 - .../VideoField.tsx | 1 - .../VideosField.tsx | 1 - .../pickRegularFieldsFromInstillFormTree.tsx | 4 - .../transformInstillJSONSchemaToZod.ts | 4 - packages/toolkit/src/lib/useEntity.ts | 1 + .../src/lib/vdp-sdk/organization/mutations.ts | 2 +- .../src/lib/vdp-sdk/organization/types.ts | 2 +- .../view/airbyte/OneOfConditionSection.tsx | 9 +- ...ceForm.tsx => AirbyteDataResourceForm.tsx} | 6 +- .../src/view/data/DataResourceAutoForm.tsx | 121 ++++++++++++++++++ packages/toolkit/src/view/data/index.ts | 3 +- .../components/CreateResourceDialog.tsx | 54 +++++--- .../EndOperatorNodeFreeForm.tsx | 1 - .../src/view/resource/AddConnectorDialog.tsx | 39 ++++-- .../resource/ResourceSettingPageMainView.tsx | 25 ++-- 38 files changed, 221 insertions(+), 98 deletions(-) rename packages/toolkit/src/view/data/{DataResourceForm.tsx => AirbyteDataResourceForm.tsx} (98%) create mode 100644 packages/toolkit/src/view/data/DataResourceAutoForm.tsx diff --git a/packages/toolkit/src/components/UploadAvatarFieldWithCrop.tsx b/packages/toolkit/src/components/UploadAvatarFieldWithCrop.tsx index 6b060e82d..d3055ed62 100644 --- a/packages/toolkit/src/components/UploadAvatarFieldWithCrop.tsx +++ b/packages/toolkit/src/components/UploadAvatarFieldWithCrop.tsx @@ -1,6 +1,5 @@ import * as React from "react"; import { Button, Dialog, Form, Input } from "@instill-ai/design-system"; -import { GeneralUseFormReturn } from "../lib"; import { FormLabel } from "../view/settings/FormLabel"; import AvatarEditor from "react-avatar-editor"; import { UseFormReturn } from "react-hook-form"; diff --git a/packages/toolkit/src/lib/react-query-service/mgmt/useAuthenticatedUser.ts b/packages/toolkit/src/lib/react-query-service/mgmt/useAuthenticatedUser.ts index e41bbc353..5e21910fd 100644 --- a/packages/toolkit/src/lib/react-query-service/mgmt/useAuthenticatedUser.ts +++ b/packages/toolkit/src/lib/react-query-service/mgmt/useAuthenticatedUser.ts @@ -1,5 +1,5 @@ import { useQuery } from "@tanstack/react-query"; -import { getAuthenticatedUserQuery, type User } from "../../vdp-sdk"; +import { getAuthenticatedUserQuery } from "../../vdp-sdk"; import type { Nullable } from "../../type"; export function useAuthenticatedUser({ diff --git a/packages/toolkit/src/lib/react-query-service/mgmt/useUser.tsx b/packages/toolkit/src/lib/react-query-service/mgmt/useUser.tsx index f38765fa2..ba04fcf90 100644 --- a/packages/toolkit/src/lib/react-query-service/mgmt/useUser.tsx +++ b/packages/toolkit/src/lib/react-query-service/mgmt/useUser.tsx @@ -1,5 +1,5 @@ import { useQuery } from "@tanstack/react-query"; -import { getUserQuery, type User } from "../../vdp-sdk"; +import { getUserQuery } from "../../vdp-sdk"; import type { Nullable } from "../../type"; export function useUser({ diff --git a/packages/toolkit/src/lib/use-instill-form/components/common/VideoPreview.tsx b/packages/toolkit/src/lib/use-instill-form/components/common/VideoPreview.tsx index d716fc4ec..b1d109252 100644 --- a/packages/toolkit/src/lib/use-instill-form/components/common/VideoPreview.tsx +++ b/packages/toolkit/src/lib/use-instill-form/components/common/VideoPreview.tsx @@ -1,7 +1,5 @@ import cn from "clsx"; import * as React from "react"; -import { FieldMode } from "../../types"; -import { Icons } from "@instill-ai/design-system"; export const VideoPreview = ({ src, diff --git a/packages/toolkit/src/lib/use-instill-form/components/smart-hint/SmartHintInfoCard.tsx b/packages/toolkit/src/lib/use-instill-form/components/smart-hint/SmartHintInfoCard.tsx index 189e9923b..077ac858f 100644 --- a/packages/toolkit/src/lib/use-instill-form/components/smart-hint/SmartHintInfoCard.tsx +++ b/packages/toolkit/src/lib/use-instill-form/components/smart-hint/SmartHintInfoCard.tsx @@ -4,7 +4,6 @@ import { Nullable } from "../../../type"; import { Tag } from "@instill-ai/design-system"; import { SmartHintWarning } from "../../types"; import { SmartHint } from "../../../use-smart-hint"; -import { transformInstillFormatToHumanReadableFormat } from "../../transform"; export const SmartHintInfoCard = ({ className, diff --git a/packages/toolkit/src/lib/use-instill-form/components/smart-hint/SmartHintList.tsx b/packages/toolkit/src/lib/use-instill-form/components/smart-hint/SmartHintList.tsx index 43ebf1f8e..b6f106c4f 100644 --- a/packages/toolkit/src/lib/use-instill-form/components/smart-hint/SmartHintList.tsx +++ b/packages/toolkit/src/lib/use-instill-form/components/smart-hint/SmartHintList.tsx @@ -1,6 +1,6 @@ import * as React from "react"; import cn from "clsx"; -import { ScrollArea, Tag } from "@instill-ai/design-system"; +import { ScrollArea } from "@instill-ai/design-system"; import { SmartHint } from "../../../use-smart-hint"; import { onClickSmartHint } from "./onClickSmartHint"; import { ControllerRenderProps } from "react-hook-form"; @@ -19,7 +19,6 @@ export const SmartHintList = ({ setHighlightedHintIndex, inputRef, smartHintEnabledPos, - instillUpstreamTypes, instillAcceptFormats, }: { field: ControllerRenderProps< @@ -38,7 +37,6 @@ export const SmartHintList = ({ setHighlightedHintIndex: React.Dispatch>; inputRef: React.RefObject; smartHintEnabledPos: Nullable; - instillUpstreamTypes: string[]; instillAcceptFormats: string[]; }) => { const humanReadableAcceptFormatString = React.useMemo(() => { diff --git a/packages/toolkit/src/lib/use-instill-form/components/smart-hint/TextArea.tsx b/packages/toolkit/src/lib/use-instill-form/components/smart-hint/TextArea.tsx index 69ef2607c..9103fb2ea 100644 --- a/packages/toolkit/src/lib/use-instill-form/components/smart-hint/TextArea.tsx +++ b/packages/toolkit/src/lib/use-instill-form/components/smart-hint/TextArea.tsx @@ -17,7 +17,6 @@ import { FieldDescriptionTooltip } from "../common"; export const TextArea = ({ form, - fieldKey, path, title, description, @@ -29,16 +28,13 @@ export const TextArea = ({ componentID, size, isHidden, - instillFormat, }: { - fieldKey: Nullable; instillAcceptFormats: string[]; shortDescription?: string; disabled?: boolean; isRequired?: boolean; instillUpstreamTypes: string[]; componentID?: string; - instillFormat?: string; } & AutoFormFieldBaseProps) => { const smartHints = useInstillStore((s) => s.smartHints); const [smartHintsPopoverIsOpen, setSmartHintsPopoverIsOpen] = @@ -208,7 +204,6 @@ export const TextArea = ({ setHighlightedHintIndex={setHighlightedHintIndex} inputRef={inputRef} smartHintEnabledPos={smartHintEnabledPos} - instillUpstreamTypes={instillUpstreamTypes} instillAcceptFormats={instillAcceptFormats} /> diff --git a/packages/toolkit/src/lib/use-instill-form/components/smart-hint/TextField.tsx b/packages/toolkit/src/lib/use-instill-form/components/smart-hint/TextField.tsx index 14857f976..da4bc5c48 100644 --- a/packages/toolkit/src/lib/use-instill-form/components/smart-hint/TextField.tsx +++ b/packages/toolkit/src/lib/use-instill-form/components/smart-hint/TextField.tsx @@ -16,7 +16,6 @@ import { getFieldPlaceholder } from "./getFieldPlaceholder"; import { FieldDescriptionTooltip } from "../common"; export const TextField = ({ - fieldKey, form, path, title, @@ -29,16 +28,13 @@ export const TextField = ({ componentID, size, isHidden, - instillFormat, }: { - fieldKey: Nullable; instillAcceptFormats: string[]; shortDescription?: string; disabled?: boolean; isRequired?: boolean; instillUpstreamTypes: string[]; componentID?: string; - instillFormat?: string; } & AutoFormFieldBaseProps) => { const smartHints = useInstillStore((s) => s.smartHints); const [smartHintsPopoverIsOpen, setSmartHintsPopoverIsOpen] = @@ -216,7 +212,6 @@ export const TextField = ({ setHighlightedHintIndex={setHighlightedHintIndex} inputRef={inputRef} smartHintEnabledPos={smartHintEnabledPos} - instillUpstreamTypes={instillUpstreamTypes} instillAcceptFormats={instillAcceptFormats} /> diff --git a/packages/toolkit/src/lib/use-instill-form/components/start-operator-free-form-fields/AudioField.tsx b/packages/toolkit/src/lib/use-instill-form/components/start-operator-free-form-fields/AudioField.tsx index 83ff49081..603015b50 100644 --- a/packages/toolkit/src/lib/use-instill-form/components/start-operator-free-form-fields/AudioField.tsx +++ b/packages/toolkit/src/lib/use-instill-form/components/start-operator-free-form-fields/AudioField.tsx @@ -35,7 +35,6 @@ export const AudioField = ({ ({ export const FieldHead = ({ mode, - form, title, path, instillFormat, @@ -29,7 +22,6 @@ export const FieldHead = ({ disabledReferenceHint, }: { mode: FieldMode; - form: GeneralUseFormReturn; title: Nullable; path: string; instillFormat: string; diff --git a/packages/toolkit/src/lib/use-instill-form/components/start-operator-free-form-fields/FileField.tsx b/packages/toolkit/src/lib/use-instill-form/components/start-operator-free-form-fields/FileField.tsx index c0dab8512..21f473b49 100644 --- a/packages/toolkit/src/lib/use-instill-form/components/start-operator-free-form-fields/FileField.tsx +++ b/packages/toolkit/src/lib/use-instill-form/components/start-operator-free-form-fields/FileField.tsx @@ -35,7 +35,6 @@ export const FileField = ({ ); } @@ -271,7 +269,6 @@ export function pickRegularFieldsFromInstillFormTree( return ( ); } diff --git a/packages/toolkit/src/lib/use-instill-form/transform/transformInstillJSONSchemaToZod.ts b/packages/toolkit/src/lib/use-instill-form/transform/transformInstillJSONSchemaToZod.ts index 3c3f3eaad..823b8cd2c 100644 --- a/packages/toolkit/src/lib/use-instill-form/transform/transformInstillJSONSchemaToZod.ts +++ b/packages/toolkit/src/lib/use-instill-form/transform/transformInstillJSONSchemaToZod.ts @@ -218,10 +218,6 @@ export function transformInstillJSONSchemaToZod({ (e) => e.instillUpstreamType === "reference" ); - const acceptTemplate = targetSchema.anyOf.some( - (e) => e.instillUpstreamType === "template" - ); - if (instillUpstreamValue) { if (instillUpstreamValue.enum) { const enumValues = instillUpstreamValue.enum as [string, ...string[]]; diff --git a/packages/toolkit/src/lib/useEntity.ts b/packages/toolkit/src/lib/useEntity.ts index 94e99c122..ae01fb98b 100644 --- a/packages/toolkit/src/lib/useEntity.ts +++ b/packages/toolkit/src/lib/useEntity.ts @@ -108,6 +108,7 @@ export function useEntity(): UseEntitySuccessReturn | UseEntityFailedReturn { connectorName, namespaceType.isSuccess, router, + namespaceType.data, ]); if (isSuccess) { diff --git a/packages/toolkit/src/lib/vdp-sdk/organization/mutations.ts b/packages/toolkit/src/lib/vdp-sdk/organization/mutations.ts index 23fcde9d1..74397fd1b 100644 --- a/packages/toolkit/src/lib/vdp-sdk/organization/mutations.ts +++ b/packages/toolkit/src/lib/vdp-sdk/organization/mutations.ts @@ -1,4 +1,4 @@ -import { GeneralRecord, Nullable } from "../../type"; +import { Nullable } from "../../type"; import { createInstillAxiosClient } from "../helper"; import { Organization, diff --git a/packages/toolkit/src/lib/vdp-sdk/organization/types.ts b/packages/toolkit/src/lib/vdp-sdk/organization/types.ts index 2b971b7e1..cb860c3c2 100644 --- a/packages/toolkit/src/lib/vdp-sdk/organization/types.ts +++ b/packages/toolkit/src/lib/vdp-sdk/organization/types.ts @@ -1,4 +1,4 @@ -import { GeneralRecord, Nullable } from "../../type"; +import { Nullable } from "../../type"; import { User } from "../mgmt"; import { StripeSubscriptionDetail } from "../types"; diff --git a/packages/toolkit/src/view/airbyte/OneOfConditionSection.tsx b/packages/toolkit/src/view/airbyte/OneOfConditionSection.tsx index aec0d7d52..611696d4e 100644 --- a/packages/toolkit/src/view/airbyte/OneOfConditionSection.tsx +++ b/packages/toolkit/src/view/airbyte/OneOfConditionSection.tsx @@ -41,6 +41,7 @@ export const OneOfConditionSection = ({ // We store the uiFields in formTree and pass it to this component to preserve // the state of UI fields + const [open, setOpen] = React.useState(false); const [selectedConditionOption, setSelectedConditionOption] = React.useState>(null); @@ -207,6 +208,8 @@ export const OneOfConditionSection = ({ if (setFormIsDirty) { setFormIsDirty(true); } + + setOpen(false); }, [ formTree.path, @@ -229,7 +232,11 @@ export const OneOfConditionSection = ({ will cause a flashed UI issue. */} - + setOpen(open)} + disabled={disableAll} + >

{selectedConditionOption?.value} diff --git a/packages/toolkit/src/view/data/DataResourceForm.tsx b/packages/toolkit/src/view/data/AirbyteDataResourceForm.tsx similarity index 98% rename from packages/toolkit/src/view/data/DataResourceForm.tsx rename to packages/toolkit/src/view/data/AirbyteDataResourceForm.tsx index 62d8eaf7d..1f8cc1a4d 100644 --- a/packages/toolkit/src/view/data/DataResourceForm.tsx +++ b/packages/toolkit/src/view/data/AirbyteDataResourceForm.tsx @@ -35,7 +35,7 @@ import { AirbyteDestinationFields } from "../airbyte"; import { LoadingSpin } from "../../components"; import { InstillErrors } from "../../constant/errors"; -export type DataResourceFormProps = { +export type AirbyteDataResourceFormProps = { dataResource: Nullable; dataDefinition: ConnectorDefinition; accessToken: Nullable; @@ -53,7 +53,9 @@ type BackButtonProps = enableBackButton: false; }; -export const DataResourceForm = (props: DataResourceFormProps) => { +export const AirbyteDataResourceForm = ( + props: AirbyteDataResourceFormProps +) => { const { amplitudeIsInit } = useAmplitudeCtx(); const { disabledAll, diff --git a/packages/toolkit/src/view/data/DataResourceAutoForm.tsx b/packages/toolkit/src/view/data/DataResourceAutoForm.tsx new file mode 100644 index 000000000..f3de53f01 --- /dev/null +++ b/packages/toolkit/src/view/data/DataResourceAutoForm.tsx @@ -0,0 +1,121 @@ +import { useToast } from "@instill-ai/design-system"; +import { + ConnectorDefinition, + ConnectorWithDefinition, + CreateUserConnectorPayload, + Nullable, + UpdateUserConnectorPayload, + sendAmplitudeData, + useAmplitudeCtx, + useCreateUserConnector, + useEntity, + useUpdateUserConnector, +} from "../../lib"; +import { recursiveHelpers } from "../pipeline-builder"; +import { toastInstillError } from "../../lib/toastInstillError"; +import { ResourceResourceForm, ResourceResourceFormData } from "../resource"; + +export type DataResourceAutoFormProps = { + resource: Nullable; + definition: ConnectorDefinition; + accessToken: Nullable; + disabledAll?: boolean; + onSubmit?: (connector: ConnectorWithDefinition) => void; + onBack?: () => void; +}; + +export const DataResourceAutoForm = (props: DataResourceAutoFormProps) => { + const { amplitudeIsInit } = useAmplitudeCtx(); + const { definition, resource, accessToken, onSubmit } = props; + const { toast } = useToast(); + + const createUserConnector = useCreateUserConnector(); + const updateUserConnector = useUpdateUserConnector(); + + const entityObject = useEntity(); + + async function handleSubmit(data: ResourceResourceFormData) { + if (!entityObject.isSuccess) { + return; + } + + if (!resource) { + try { + const payload: CreateUserConnectorPayload = { + id: data.id ?? undefined, + connector_definition_name: definition.name, + description: data.description ?? undefined, + configuration: + recursiveHelpers.replaceNullAndEmptyStringWithUndefined(data), + }; + + const { connector } = await createUserConnector.mutateAsync({ + payload, + entityName: entityObject.entityName, + accessToken, + }); + + if (amplitudeIsInit) { + sendAmplitudeData("create_connector", { + connector_definition_name: definition.name, + }); + } + + if (onSubmit) { + onSubmit(connector); + } + + toast({ + title: "Successfully create AI connector", + variant: "alert-success", + size: "small", + }); + } catch (error) { + toastInstillError({ + title: "Something went wrong when create the AI connector", + toast, + error, + }); + } + + return; + } + + try { + const payload: UpdateUserConnectorPayload = { + connectorName: resource.name, + description: data.description ?? undefined, + configuration: recursiveHelpers.replaceNullAndEmptyStringWithUndefined( + recursiveHelpers.replaceTargetValue(data, "*****MASK*****", undefined) + ), + }; + + const { connector } = await updateUserConnector.mutateAsync({ + payload, + accessToken, + }); + + if (amplitudeIsInit) { + sendAmplitudeData("update_connector"); + } + + if (onSubmit) { + onSubmit(connector); + } + + toast({ + title: "Successfully update Data connector", + variant: "alert-success", + size: "small", + }); + } catch (error) { + toastInstillError({ + title: "Something went wrong when update the Data connector", + toast, + error, + }); + } + } + + return ; +}; diff --git a/packages/toolkit/src/view/data/index.ts b/packages/toolkit/src/view/data/index.ts index dc1e2296e..fe3ea3674 100644 --- a/packages/toolkit/src/view/data/index.ts +++ b/packages/toolkit/src/view/data/index.ts @@ -1 +1,2 @@ -export * from "./DataResourceForm"; +export * from "./AirbyteDataResourceForm"; +export * from "./DataResourceAutoForm"; diff --git a/packages/toolkit/src/view/pipeline-builder/components/CreateResourceDialog.tsx b/packages/toolkit/src/view/pipeline-builder/components/CreateResourceDialog.tsx index bf6a34bfb..47590f5cb 100644 --- a/packages/toolkit/src/view/pipeline-builder/components/CreateResourceDialog.tsx +++ b/packages/toolkit/src/view/pipeline-builder/components/CreateResourceDialog.tsx @@ -8,7 +8,7 @@ import { useInstillStore, useUserConnectors, } from "../../../lib"; -import { DataResourceForm } from "../../data"; +import { AirbyteDataResourceForm, DataResourceAutoForm } from "../../data"; import { ImageWithFallback } from "../../../components"; import { AIResourceAutoForm } from "../../ai"; @@ -170,23 +170,41 @@ export const CreateResourceDialog = (props: CreateResourceDialogProps) => { ) : null} {connectorType === "CONNECTOR_TYPE_DATA" && connectorDefinition ? ( - { - updateState(() => ({ - open: false, - connectorType: null, - connectorDefinition: null, - onCreated: null, - onSelectedExistingResource: null, - })); - }} - enableQuery={enableQuery} - /> + connectorDefinition.id === "airbyte-destination" ? ( + { + updateState(() => ({ + open: false, + connectorType: null, + connectorDefinition: null, + onCreated: null, + onSelectedExistingResource: null, + })); + }} + enableQuery={enableQuery} + /> + ) : ( + { + updateState(() => ({ + open: false, + connectorType: null, + connectorDefinition: null, + onCreated: null, + onSelectedExistingResource: null, + })); + }} + /> + ) ) : null} diff --git a/packages/toolkit/src/view/pipeline-builder/components/nodes/end-operator-node/EndOperatorNodeFreeForm.tsx b/packages/toolkit/src/view/pipeline-builder/components/nodes/end-operator-node/EndOperatorNodeFreeForm.tsx index 213b63087..0503f4f78 100644 --- a/packages/toolkit/src/view/pipeline-builder/components/nodes/end-operator-node/EndOperatorNodeFreeForm.tsx +++ b/packages/toolkit/src/view/pipeline-builder/components/nodes/end-operator-node/EndOperatorNodeFreeForm.tsx @@ -145,7 +145,6 @@ export const EndOperatorNodeFreeForm = ({ { ) : null} {newConnectorType === "CONNECTOR_TYPE_DATA" && newConnectorDefinition ? ( - { - setNewConnectorDefinition(null); - setNewConnectorType(null); - }} - enableQuery={enableQuery} - /> + newConnectorDefinition.id === "airbyte-destination" ? ( + { + setNewConnectorDefinition(null); + setNewConnectorType(null); + }} + enableQuery={enableQuery} + /> + ) : ( + { + setNewConnectorDefinition(null); + setNewConnectorType(null); + }} + /> + ) ) : null} )} diff --git a/packages/toolkit/src/view/resource/ResourceSettingPageMainView.tsx b/packages/toolkit/src/view/resource/ResourceSettingPageMainView.tsx index 29283b7b3..be418cf93 100644 --- a/packages/toolkit/src/view/resource/ResourceSettingPageMainView.tsx +++ b/packages/toolkit/src/view/resource/ResourceSettingPageMainView.tsx @@ -3,7 +3,7 @@ import { PageTitle } from "../../components"; import { GeneralPageProp, useEntity, useUserConnector } from "../../lib"; import { AIResourceAutoForm } from "../ai"; import { BlockchainResourceAutoForm } from "../blockchain"; -import { DataResourceForm } from "../data"; +import { AirbyteDataResourceForm, DataResourceAutoForm } from "../data"; export type ResourceSettingPageMainViewProps = GeneralPageProp; @@ -49,13 +49,22 @@ export const ResourceSettingPageMainView = ( /> ) : null} {userConnector.data.type === "CONNECTOR_TYPE_DATA" ? ( - + userConnector.data.connector_definition.id === + "airbyte-destination" ? ( + + ) : ( + + ) ) : null} ) : (