From 4b22f02b2abf6163c7fddbaad99e04d227dcfb5f Mon Sep 17 00:00:00 2001 From: Teal Larson Date: Fri, 17 Jun 2022 12:54:39 -0400 Subject: [PATCH 1/4] add form values tracker context --- .../components/ReplicationView.tsx | 27 ++++++++++++++++--- .../ConnectionForm/ConnectionForm.tsx | 19 ++++++++++++- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx index e541012864f4..fb82b1f38248 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx @@ -1,7 +1,7 @@ import { faSyncAlt } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FormikHelpers } from "formik"; -import React, { useState } from "react"; +import React, { useMemo, useState } from "react"; import { FormattedMessage } from "react-intl"; import { useAsyncFn } from "react-use"; import styled from "styled-components"; @@ -20,6 +20,7 @@ import { } from "hooks/services/useConnectionHook"; import { equal } from "utils/objects"; import ConnectionForm from "views/Connection/ConnectionForm"; +import { FormikConnectionFormValues } from "views/Connection/ConnectionForm/formConfig"; interface ReplicationViewProps { onAfterSaveSchema: () => void; @@ -52,6 +53,7 @@ export const ReplicationView: React.FC = ({ onAfterSaveSch const { openConfirmationModal, closeConfirmationModal } = useConfirmationModalService(); const [activeUpdatingSchemaMode, setActiveUpdatingSchemaMode] = useState(false); const [saved, setSaved] = useState(false); + const [connectionFormValues, setConnectionFormValues] = useState(); const { mutateAsync: updateConnection } = useUpdateConnection(); const { mutateAsync: resetConnection } = useResetConnection(); @@ -65,7 +67,23 @@ export const ReplicationView: React.FC = ({ onAfterSaveSch [connectionId] ); - const connection = activeUpdatingSchemaMode ? connectionWithRefreshCatalog : initialConnection; + const connection = useMemo(() => { + if (activeUpdatingSchemaMode && connectionWithRefreshCatalog) { + // merge with connectionFormValues: + // + return { + ...connectionWithRefreshCatalog, + namespaceDefinition: + connectionFormValues?.namespaceDefinition ?? connectionWithRefreshCatalog.namespaceDefinition, + namespaceFormat: connectionFormValues?.namespaceFormat ?? connectionWithRefreshCatalog.namespaceFormat, + prefix: connectionFormValues?.prefix ?? connectionWithRefreshCatalog.prefix, + schedule: connectionFormValues?.schedule ?? connectionWithRefreshCatalog.schedule, + }; + } + return initialConnection; + }, [activeUpdatingSchemaMode, connectionWithRefreshCatalog, initialConnection, connectionFormValues]); + + // const connection = activeUpdatingSchemaMode ? connectionWithRefreshCatalog : initialConnection; const onSubmit = async (values: ValuesProps, formikHelpers?: FormikHelpers) => { if (!connection) { @@ -125,7 +143,7 @@ export const ReplicationView: React.FC = ({ onAfterSaveSch await refreshCatalog(); }; - const onExitRefreshCatalogMode = () => { + const onCancelConnectionFormEdit = () => { setActiveUpdatingSchemaMode(false); }; @@ -158,9 +176,10 @@ export const ReplicationView: React.FC = ({ onAfterSaveSch onSubmit={onSubmitForm} onReset={onReset} successMessage={saved && } - onCancel={onExitRefreshCatalogMode} + onCancel={onCancelConnectionFormEdit} editSchemeMode={activeUpdatingSchemaMode} additionalSchemaControl={renderUpdateSchemaButton()} + onChangeValues={setConnectionFormValues} /> ) : ( diff --git a/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionForm.tsx b/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionForm.tsx index 61f0669cebad..9a3d76853f15 100644 --- a/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionForm.tsx +++ b/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionForm.tsx @@ -1,7 +1,8 @@ -import { Field, FieldProps, Form, Formik, FormikHelpers } from "formik"; +import { Field, FieldProps, Form, Formik, FormikHelpers, useFormikContext } from "formik"; import React, { useCallback, useState } from "react"; import { FormattedMessage, useIntl } from "react-intl"; import { useToggle } from "react-use"; +import { useDebounce } from "react-use"; import styled from "styled-components"; import { ControlLabels, DropDown, DropDownRow, H5, Input, Label } from "components"; @@ -93,6 +94,19 @@ interface ConnectionFormSubmitResult { export type ConnectionFormMode = "create" | "edit" | "readonly"; +function FormValuesChangeTracker({ onChangeValues }: { onChangeValues?: (values: T) => void }) { + // Grab values from context + const { values } = useFormikContext(); + useDebounce( + () => { + onChangeValues?.(values); + }, + 200, + [values, onChangeValues] + ); + return null; +} + interface ConnectionFormProps { onSubmit: (values: ConnectionFormValues) => Promise; className?: string; @@ -101,6 +115,7 @@ interface ConnectionFormProps { onReset?: (connectionId?: string) => void; onDropDownSelect?: (item: DropDownRow.IDataItem) => void; onCancel?: () => void; + onChangeValues?: (values: FormikConnectionFormValues) => void; /** Should be passed when connection is updated with withRefreshCatalog flag */ editSchemeMode?: boolean; @@ -124,6 +139,7 @@ const ConnectionForm: React.FC = ({ editSchemeMode, additionalSchemaControl, connection, + onChangeValues, }) => { const { openConfirmationModal, closeConfirmationModal } = useConfirmationModalService(); const destDefinition = useGetDestinationDefinitionSpecification(connection.destination.destinationDefinitionId); @@ -204,6 +220,7 @@ const ConnectionForm: React.FC = ({ {({ isSubmitting, setFieldValue, isValid, dirty, resetForm, values }) => ( + {!isEditMode && ( From 0a05b8eaa5f335b24f441767c7c85296a6afde8b Mon Sep 17 00:00:00 2001 From: Teal Larson Date: Fri, 17 Jun 2022 12:58:59 -0400 Subject: [PATCH 2/4] add clarifying comment --- .../ConnectionItemPage/components/ReplicationView.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx index fb82b1f38248..5da103b1e8ee 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx @@ -69,8 +69,11 @@ export const ReplicationView: React.FC = ({ onAfterSaveSch const connection = useMemo(() => { if (activeUpdatingSchemaMode && connectionWithRefreshCatalog) { - // merge with connectionFormValues: - // + // merge connectionFormValues (unsaved previous form state) with the refreshed connection data: + // 1. if there is a namespace definition, format, prefix, or schedule in connectionFormValues, + // use those and fill in the rest from the database + // 2. otherwise, use the values from the database + // 3. if none of the above, use the default values. return { ...connectionWithRefreshCatalog, namespaceDefinition: From 0e0ab7996eff5b5adbf966c3379076c20231354e Mon Sep 17 00:00:00 2001 From: Teal Larson Date: Fri, 17 Jun 2022 14:20:29 -0400 Subject: [PATCH 3/4] add same functionality to create connection --- .../CreateConnectionContent.tsx | 14 ++++++++++++-- .../components/ReplicationView.tsx | 2 -- .../views/Connection/ConnectionForm/formConfig.tsx | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/airbyte-webapp/src/components/CreateConnectionContent/CreateConnectionContent.tsx b/airbyte-webapp/src/components/CreateConnectionContent/CreateConnectionContent.tsx index 8f6ba0328170..6a8c38df1ff8 100644 --- a/airbyte-webapp/src/components/CreateConnectionContent/CreateConnectionContent.tsx +++ b/airbyte-webapp/src/components/CreateConnectionContent/CreateConnectionContent.tsx @@ -1,6 +1,6 @@ import { faRedoAlt } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import React, { Suspense, useMemo } from "react"; +import React, { Suspense, useMemo, useState } from "react"; import { FormattedMessage } from "react-intl"; import styled from "styled-components"; @@ -13,6 +13,7 @@ import { LogsRequestError } from "core/request/LogsRequestError"; import { useAnalyticsService } from "hooks/services/Analytics/useAnalyticsService"; import { useCreateConnection, ValuesProps } from "hooks/services/useConnectionHook"; import ConnectionForm from "views/Connection/ConnectionForm"; +import { FormikConnectionFormValues } from "views/Connection/ConnectionForm/formConfig"; import { DestinationRead, SourceRead, WebBackendConnectionRead } from "../../core/request/AirbyteClient"; import { useDiscoverSchema } from "../../hooks/services/useSourceHook"; @@ -52,15 +53,23 @@ const CreateConnectionContent: React.FC = ({ const { schema, isLoading, schemaErrorStatus, catalogId, onDiscoverSchema } = useDiscoverSchema(source.sourceId); + const [connectionFormValues, setConnectionFormValues] = useState(); + const connection = useMemo( () => ({ + name: connectionFormValues?.name ?? "", + namespaceDefinition: connectionFormValues?.namespaceDefinition, + namespaceFormat: connectionFormValues?.namespaceFormat, + prefix: connectionFormValues?.prefix, + schedule: connectionFormValues?.schedule, syncCatalog: schema, destination, source, catalogId, }), - [schema, destination, source, catalogId] + [connectionFormValues, schema, destination, source, catalogId] ); + console.log(connection.schedule); const onSubmitConnectionStep = async (values: ValuesProps) => { const connection = await createConnection({ @@ -126,6 +135,7 @@ const CreateConnectionContent: React.FC = ({ } onSubmit={onSubmitConnectionStep} + onChangeValues={setConnectionFormValues} /> )} diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx index 5da103b1e8ee..6eb75031cc3f 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx @@ -86,8 +86,6 @@ export const ReplicationView: React.FC = ({ onAfterSaveSch return initialConnection; }, [activeUpdatingSchemaMode, connectionWithRefreshCatalog, initialConnection, connectionFormValues]); - // const connection = activeUpdatingSchemaMode ? connectionWithRefreshCatalog : initialConnection; - const onSubmit = async (values: ValuesProps, formikHelpers?: FormikHelpers) => { if (!connection) { // onSubmit should only be called when a connection object exists. diff --git a/airbyte-webapp/src/views/Connection/ConnectionForm/formConfig.tsx b/airbyte-webapp/src/views/Connection/ConnectionForm/formConfig.tsx index 6b1f790df46b..76a305edc5e0 100644 --- a/airbyte-webapp/src/views/Connection/ConnectionForm/formConfig.tsx +++ b/airbyte-webapp/src/views/Connection/ConnectionForm/formConfig.tsx @@ -234,7 +234,7 @@ const useInitialValues = ( const initialValues: FormikConnectionFormValues = { name: connection.name ?? `${connection.source.name} <> ${connection.destination.name}`, syncCatalog: initialSchema, - schedule: connection.connectionId ? connection.schedule ?? null : DEFAULT_SCHEDULE, + schedule: connection.connectionId || connection.schedule ? connection.schedule ?? null : DEFAULT_SCHEDULE, prefix: connection.prefix || "", namespaceDefinition: connection.namespaceDefinition || NamespaceDefinitionType.source, namespaceFormat: connection.namespaceFormat ?? SOURCE_NAMESPACE_TAG, From 8664a068fe3b40fe83fcbad7e67f9bb701d4420c Mon Sep 17 00:00:00 2001 From: Teal Larson Date: Thu, 23 Jun 2022 09:35:34 -0400 Subject: [PATCH 4/4] Update airbyte-webapp/src/components/CreateConnectionContent/CreateConnectionContent.tsx Co-authored-by: Edmundo Ruiz Ghanem <168664+edmundito@users.noreply.github.com> --- .../CreateConnectionContent/CreateConnectionContent.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/airbyte-webapp/src/components/CreateConnectionContent/CreateConnectionContent.tsx b/airbyte-webapp/src/components/CreateConnectionContent/CreateConnectionContent.tsx index 6a8c38df1ff8..659d6bb4c0bb 100644 --- a/airbyte-webapp/src/components/CreateConnectionContent/CreateConnectionContent.tsx +++ b/airbyte-webapp/src/components/CreateConnectionContent/CreateConnectionContent.tsx @@ -69,7 +69,6 @@ const CreateConnectionContent: React.FC = ({ }), [connectionFormValues, schema, destination, source, catalogId] ); - console.log(connection.schedule); const onSubmitConnectionStep = async (values: ValuesProps) => { const connection = await createConnection({