Skip to content

Commit cfea528

Browse files
authored
🪟 🐛 Fix OAuth validation not allowing to create source or destination (#14197)
* Enable "Set up source/destination" button only if the form is valid * Update how ServiceForm initial values are patched so that it correctly patches the configuration with default values * Update initial values patching in service form to use initialValues to preserve already set values Update useOAuthFlowAdapter to correctly merge the values from the oauth response * Remove unused values var from ServiceForm
1 parent dd4079f commit cfea528

File tree

4 files changed

+26
-26
lines changed

4 files changed

+26
-26
lines changed

airbyte-webapp/src/views/Connector/ServiceForm/FormRoot.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ const FormRoot: React.FC<FormRootProps> = ({
8989
isLoadSchema={isLoadingSchema}
9090
fetchingConnectorError={fetchingConnectorError}
9191
hasSuccess={hasSuccess}
92+
isValid={isValid}
9293
/>
9394
)}
9495
</FormContainer>

airbyte-webapp/src/views/Connector/ServiceForm/ServiceForm.tsx

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Formik, getIn, setIn, useFormikContext } from "formik";
22
import { JSONSchema7 } from "json-schema";
3-
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
4-
import { useToggle } from "react-use";
3+
import React, { useCallback, useEffect, useMemo, useState } from "react";
4+
import { useDeepCompareEffect, useToggle } from "react-use";
55

66
import { FormChangeTracker } from "components/FormChangeTracker";
77

@@ -13,7 +13,6 @@ import { useFormChangeTrackerService, useUniqueFormId } from "hooks/services/For
1313
import { isDefined } from "utils/common";
1414
import RequestConnectorModal from "views/Connector/RequestConnectorModal";
1515

16-
import { ConnectionConfiguration } from "../../../core/domain/connection";
1716
import { CheckConnectionRead } from "../../../core/request/AirbyteClient";
1817
import { useDocumentationPanelContext } from "../ConnectorDocumentationLayout/DocumentationPanelContext";
1918
import { ConnectorNameControl } from "./components/Controls/ConnectorNameControl";
@@ -41,31 +40,28 @@ const FormikPatch: React.FC = () => {
4140
*/
4241
const PatchInitialValuesWithWidgetConfig: React.FC<{
4342
schema: JSONSchema7;
44-
}> = ({ schema }) => {
43+
initialValues: ServiceFormValues;
44+
}> = ({ schema, initialValues }) => {
4545
const { widgetsInfo } = useServiceForm();
46-
const { values, resetForm } = useFormikContext<ServiceFormValues>();
46+
const { setFieldValue } = useFormikContext<ServiceFormValues>();
4747

48-
const valueRef = useRef<ConnectionConfiguration>();
49-
valueRef.current = values.connectionConfiguration;
48+
useDeepCompareEffect(() => {
49+
const widgetsInfoEntries = Object.entries(widgetsInfo);
5050

51-
useEffect(() => {
5251
// set all const fields to form field values, so we could send form
53-
const constPatchedValues = Object.entries(widgetsInfo)
54-
.filter(([_, v]) => isDefined(v.const))
55-
.reduce((acc, [k, v]) => setIn(acc, k, v.const), valueRef.current);
52+
const patchedConstValues = widgetsInfoEntries
53+
.filter(([_, value]) => isDefined(value.const))
54+
.reduce((acc, [key, value]) => setIn(acc, key, value.const), initialValues);
5655

5756
// set default fields as current values, so values could be populated correctly
5857
// fix for https://github.com/airbytehq/airbyte/issues/6791
59-
const defaultPatchedValues = Object.entries(widgetsInfo)
60-
.filter(([k, v]) => isDefined(v.default) && !isDefined(getIn(constPatchedValues, k)))
61-
.reduce((acc, [k, v]) => setIn(acc, k, v.default), constPatchedValues);
62-
63-
resetForm({
64-
values: {
65-
...values,
66-
connectionConfiguration: defaultPatchedValues,
67-
},
68-
});
58+
const patchedDefaultValues = widgetsInfoEntries
59+
.filter(([key, value]) => isDefined(value.default) && !isDefined(getIn(patchedConstValues, key)))
60+
.reduce((acc, [key, value]) => setIn(acc, key, value.default), patchedConstValues);
61+
62+
if (patchedDefaultValues?.connectionConfiguration) {
63+
setFieldValue("connectionConfiguration", patchedDefaultValues.connectionConfiguration);
64+
}
6965

7066
// eslint-disable-next-line react-hooks/exhaustive-deps
7167
}, [schema]);
@@ -237,6 +233,7 @@ const ServiceForm: React.FC<ServiceFormProps> = (props) => {
237233
initialValues={initialValues}
238234
validationSchema={validationSchema}
239235
onSubmit={onFormSubmit}
236+
enableReinitialize
240237
>
241238
{({ dirty }) => (
242239
<ServiceFormContextProvider
@@ -252,7 +249,7 @@ const ServiceForm: React.FC<ServiceFormProps> = (props) => {
252249
{!props.isEditMode && <SetDefaultName />}
253250
<FormikPatch />
254251
<FormChangeTracker changed={dirty} formId={formId} />
255-
<PatchInitialValuesWithWidgetConfig schema={jsonSchema} />
252+
<PatchInitialValuesWithWidgetConfig schema={jsonSchema} initialValues={initialValues} />
256253
<FormRoot
257254
{...props}
258255
errorMessage={props.errorMessage}

airbyte-webapp/src/views/Connector/ServiceForm/components/CreateControls.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { TestingConnectionError, FetchingConnectorError } from "./TestingConnect
88
import TestingConnectionSpinner from "./TestingConnectionSpinner";
99
import TestingConnectionSuccess from "./TestingConnectionSuccess";
1010

11-
interface IProps {
11+
interface CreateControlProps {
1212
formType: "source" | "destination";
1313
isSubmitting: boolean;
1414
errorMessage?: React.ReactNode;
@@ -18,6 +18,7 @@ interface IProps {
1818

1919
isTestConnectionInProgress: boolean;
2020
onCancelTesting?: () => void;
21+
isValid: boolean;
2122
}
2223

2324
const ButtonContainer = styled.div`
@@ -31,7 +32,7 @@ const SubmitButton = styled(Button)`
3132
margin-left: auto;
3233
`;
3334

34-
const CreateControls: React.FC<IProps> = ({
35+
const CreateControls: React.FC<CreateControlProps> = ({
3536
isTestConnectionInProgress,
3637
isSubmitting,
3738
formType,
@@ -40,6 +41,7 @@ const CreateControls: React.FC<IProps> = ({
4041
fetchingConnectorError,
4142
isLoadSchema,
4243
onCancelTesting,
44+
isValid,
4345
}) => {
4446
if (isSubmitting) {
4547
return <TestingConnectionSpinner isCancellable={isTestConnectionInProgress} onCancelTesting={onCancelTesting} />;
@@ -53,7 +55,7 @@ const CreateControls: React.FC<IProps> = ({
5355
<ButtonContainer>
5456
{errorMessage && !fetchingConnectorError && <TestingConnectionError errorMessage={errorMessage} />}
5557
{fetchingConnectorError && <FetchingConnectorError />}
56-
<SubmitButton type="submit" disabled={isLoadSchema}>
58+
<SubmitButton type="submit" disabled={isLoadSchema || !isValid}>
5759
<FormattedMessage id={`onboarding.${formType}SetUp.buttonText`} />
5860
</SubmitButton>
5961
</ButtonContainer>

airbyte-webapp/src/views/Connector/ServiceForm/components/Sections/auth/useOauthFlowAdapter.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ function useFormikOauthAdapter(connector: ConnectorDefinitionSpecification): {
3434
);
3535
} else {
3636
newValues = merge(values, {
37-
connectionConfiguration: completeOauthResponse,
37+
connectionConfiguration: { credentials: completeOauthResponse },
3838
});
3939
}
4040

0 commit comments

Comments
 (0)