Skip to content

Commit a686508

Browse files
authored
Misc Improvements to assist Connection Form Refactor (#16303)
* Move exports to declaration for formConfig * Add ConnectionOrPartialConnection, move ConnectionForm exports * Removing additionBottomControls as it was unused * Create and use FormError, test createFormErrorMessage * Remove unnecessary eslint ignore, remove unnecessary async/await * rename createFormErrorMessage
1 parent 42c5265 commit a686508

File tree

16 files changed

+102
-106
lines changed

16 files changed

+102
-106
lines changed

airbyte-webapp/src/components/CreateConnectionContent/CreateConnectionContent.tsx

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { faRedoAlt } from "@fortawesome/free-solid-svg-icons";
22
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
33
import React, { Suspense, useMemo } from "react";
44
import { FormattedMessage } from "react-intl";
5-
import styled from "styled-components";
65

76
import { Button, ContentCard } from "components";
87
import { IDataItem } from "components/base/DropDown/components/Option";
@@ -13,25 +12,14 @@ import { Action, Namespace } from "core/analytics";
1312
import { LogsRequestError } from "core/request/LogsRequestError";
1413
import { useAnalyticsService } from "hooks/services/Analytics";
1514
import { useCreateConnection, ValuesProps } from "hooks/services/useConnectionHook";
16-
import ConnectionForm from "views/Connection/ConnectionForm";
17-
import { ConnectionFormProps } from "views/Connection/ConnectionForm/ConnectionForm";
15+
import { ConnectionForm, ConnectionFormProps } from "views/Connection/ConnectionForm";
1816

1917
import { DestinationRead, SourceRead, WebBackendConnectionRead } from "../../core/request/AirbyteClient";
2018
import { useDiscoverSchema } from "../../hooks/services/useSourceHook";
2119
import TryAfterErrorBlock from "./components/TryAfterErrorBlock";
2220
import styles from "./CreateConnectionContent.module.scss";
2321

24-
const SkipButton = styled.div`
25-
margin-top: 6px;
26-
27-
& > button {
28-
min-width: 239px;
29-
margin-left: 9px;
30-
}
31-
`;
32-
3322
interface CreateConnectionContentProps {
34-
additionBottomControls?: React.ReactNode;
3523
source: SourceRead;
3624
destination: DestinationRead;
3725
afterSubmitConnection?: (connection: WebBackendConnectionRead) => void;
@@ -41,7 +29,6 @@ const CreateConnectionContent: React.FC<CreateConnectionContentProps> = ({
4129
source,
4230
destination,
4331
afterSubmitConnection,
44-
additionBottomControls,
4532
}) => {
4633
const { mutateAsync: createConnection } = useCreateConnection();
4734
const analyticsService = useAnalyticsService();
@@ -104,10 +91,7 @@ const CreateConnectionContent: React.FC<CreateConnectionContentProps> = ({
10491
const job = LogsRequestError.extractJobInfo(schemaErrorStatus);
10592
return (
10693
<ContentCard>
107-
<TryAfterErrorBlock
108-
onClick={onDiscoverSchema}
109-
additionControl={<SkipButton>{additionBottomControls}</SkipButton>}
110-
/>
94+
<TryAfterErrorBlock onClick={onDiscoverSchema} />
11195
{job && <JobItem job={job} />}
11296
</ContentCard>
11397
);
@@ -120,7 +104,6 @@ const CreateConnectionContent: React.FC<CreateConnectionContentProps> = ({
120104
<ConnectionForm
121105
mode="create"
122106
connection={connection}
123-
additionBottomControls={additionBottomControls}
124107
onDropDownSelect={onSelectFrequency}
125108
onSubmit={onSubmitConnectionStep}
126109
additionalSchemaControl={

airbyte-webapp/src/hooks/services/useSourceHook.tsx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -180,15 +180,12 @@ const useDiscoverSchema = (
180180
} finally {
181181
setIsLoading(false);
182182
}
183-
// eslint-disable-next-line react-hooks/exhaustive-deps
184-
}, [sourceId]);
183+
}, [disableCache, service, sourceId]);
185184

186185
useEffect(() => {
187-
(async () => {
188-
if (sourceId) {
189-
await onDiscoverSchema();
190-
}
191-
})();
186+
if (sourceId) {
187+
onDiscoverSchema();
188+
}
192189
}, [onDiscoverSchema, sourceId]);
193190

194191
return { schemaErrorStatus, isLoading, schema, catalogId, onDiscoverSchema };

airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ import {
2121
} from "hooks/services/useConnectionHook";
2222
import { equal } from "utils/objects";
2323
import { CatalogDiffModal } from "views/Connection/CatalogDiffModal/CatalogDiffModal";
24-
import ConnectionForm from "views/Connection/ConnectionForm";
25-
import { ConnectionFormSubmitResult } from "views/Connection/ConnectionForm/ConnectionForm";
24+
import { ConnectionForm, ConnectionFormSubmitResult } from "views/Connection/ConnectionForm";
2625

2726
interface ReplicationViewProps {
2827
onAfterSaveSchema: () => void;

airbyte-webapp/src/pages/DestinationPage/pages/CreateDestinationPage/components/DestinationForm.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { LogsRequestError } from "core/request/LogsRequestError";
88
import { useAnalyticsService } from "hooks/services/Analytics";
99
import useRouter from "hooks/useRouter";
1010
import { useGetDestinationDefinitionSpecificationAsync } from "services/connector/DestinationDefinitionSpecificationService";
11-
import { createFormErrorMessage } from "utils/errorStatusMessage";
11+
import { generateMessageFromError, FormError } from "utils/errorStatusMessage";
1212
import { ConnectorCard } from "views/Connector/ConnectorCard";
1313

1414
interface DestinationFormProps {
@@ -21,7 +21,7 @@ interface DestinationFormProps {
2121
afterSelectConnector?: () => void;
2222
destinationDefinitions: DestinationDefinitionRead[];
2323
hasSuccess?: boolean;
24-
error?: { message?: string; status?: number } | null;
24+
error?: FormError | null;
2525
}
2626

2727
const hasDestinationDefinitionId = (state: unknown): state is { destinationDefinitionId: string } => {
@@ -75,7 +75,7 @@ export const DestinationForm: React.FC<DestinationFormProps> = ({
7575
});
7676
};
7777

78-
const errorMessage = error ? createFormErrorMessage(error) : null;
78+
const errorMessage = error ? generateMessageFromError(error) : null;
7979

8080
return (
8181
<ConnectorCard

airbyte-webapp/src/pages/OnboardingPage/components/DestinationStep.tsx

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@ import React, { useEffect, useState } from "react";
22

33
import { Action, Namespace } from "core/analytics";
44
import { ConnectionConfiguration } from "core/domain/connection";
5-
import { JobInfo } from "core/domain/job";
65
import { useAnalyticsService } from "hooks/services/Analytics";
76
import { useCreateDestination } from "hooks/services/useDestinationHook";
87
import { useDestinationDefinitionList } from "services/connector/DestinationDefinitionService";
98
import { useGetDestinationDefinitionSpecificationAsync } from "services/connector/DestinationDefinitionSpecificationService";
10-
import { createFormErrorMessage } from "utils/errorStatusMessage";
9+
import { generateMessageFromError, FormError } from "utils/errorStatusMessage";
1110
import { ConnectorCard } from "views/Connector/ConnectorCard";
1211
import { useDocumentationPanelContext } from "views/Connector/ConnectorDocumentationLayout/DocumentationPanelContext";
1312

@@ -23,11 +22,7 @@ const DestinationStep: React.FC<Props> = ({ onNextStep, onSuccess }) => {
2322
useGetDestinationDefinitionSpecificationAsync(destinationDefinitionId);
2423
const { destinationDefinitions } = useDestinationDefinitionList();
2524
const [successRequest, setSuccessRequest] = useState(false);
26-
const [error, setError] = useState<{
27-
status: number;
28-
response: JobInfo;
29-
message: string;
30-
} | null>(null);
25+
const [error, setError] = useState<FormError | null>(null);
3126

3227
const { mutateAsync: createDestination } = useCreateDestination();
3328

@@ -89,7 +84,7 @@ const DestinationStep: React.FC<Props> = ({ onNextStep, onSuccess }) => {
8984
});
9085
};
9186

92-
const errorMessage = error ? createFormErrorMessage(error) : null;
87+
const errorMessage = error ? generateMessageFromError(error) : null;
9388

9489
return (
9590
<ConnectorCard

airbyte-webapp/src/pages/OnboardingPage/components/SourceStep.tsx

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@ import React, { useEffect, useState } from "react";
22

33
import { Action, Namespace } from "core/analytics";
44
import { ConnectionConfiguration } from "core/domain/connection";
5-
import { JobInfo } from "core/domain/job";
65
import { LogsRequestError } from "core/request/LogsRequestError";
76
import { useAnalyticsService } from "hooks/services/Analytics";
87
import { useCreateSource } from "hooks/services/useSourceHook";
98
import { useSourceDefinitionList } from "services/connector/SourceDefinitionService";
109
import { useGetSourceDefinitionSpecificationAsync } from "services/connector/SourceDefinitionSpecificationService";
11-
import { createFormErrorMessage } from "utils/errorStatusMessage";
10+
import { generateMessageFromError, FormError } from "utils/errorStatusMessage";
1211
import { ConnectorCard } from "views/Connector/ConnectorCard";
1312
import { useDocumentationPanelContext } from "views/Connector/ConnectorDocumentationLayout/DocumentationPanelContext";
1413

@@ -21,11 +20,7 @@ const SourceStep: React.FC<SourcesStepProps> = ({ onNextStep, onSuccess }) => {
2120
const { sourceDefinitions } = useSourceDefinitionList();
2221
const [sourceDefinitionId, setSourceDefinitionId] = useState<string | null>(null);
2322
const [successRequest, setSuccessRequest] = useState(false);
24-
const [error, setError] = useState<{
25-
status: number;
26-
response: JobInfo;
27-
message: string;
28-
} | null>(null);
23+
const [error, setError] = useState<FormError | null>(null);
2924

3025
const { setDocumentationUrl, setDocumentationPanelOpen } = useDocumentationPanelContext();
3126
const { mutateAsync: createSource } = useCreateSource();
@@ -91,7 +86,7 @@ const SourceStep: React.FC<SourcesStepProps> = ({ onNextStep, onSuccess }) => {
9186
...values,
9287
});
9388

94-
const errorMessage = error ? createFormErrorMessage(error) : "";
89+
const errorMessage = error ? generateMessageFromError(error) : "";
9590

9691
return (
9792
<ConnectorCard

airbyte-webapp/src/pages/SourcesPage/pages/CreateSourcePage/components/SourceForm.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { useAnalyticsService } from "hooks/services/Analytics";
88
import useRouter from "hooks/useRouter";
99
import { SourceDefinitionReadWithLatestTag } from "services/connector/SourceDefinitionService";
1010
import { useGetSourceDefinitionSpecificationAsync } from "services/connector/SourceDefinitionSpecificationService";
11-
import { createFormErrorMessage } from "utils/errorStatusMessage";
11+
import { generateMessageFromError, FormError } from "utils/errorStatusMessage";
1212
import { ConnectorCard } from "views/Connector/ConnectorCard";
1313
import { ServiceFormValues } from "views/Connector/ServiceForm/types";
1414

@@ -22,7 +22,7 @@ interface SourceFormProps {
2222
afterSelectConnector?: () => void;
2323
sourceDefinitions: SourceDefinitionReadWithLatestTag[];
2424
hasSuccess?: boolean;
25-
error?: { message?: string; status?: number } | null;
25+
error?: FormError | null;
2626
}
2727

2828
const hasSourceDefinitionId = (state: unknown): state is { sourceDefinitionId: string } => {
@@ -76,7 +76,7 @@ export const SourceForm: React.FC<SourceFormProps> = ({
7676
});
7777
};
7878

79-
const errorMessage = error ? createFormErrorMessage(error) : null;
79+
const errorMessage = error ? generateMessageFromError(error) : null;
8080

8181
return (
8282
<ConnectorCard
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { generateMessageFromError, FormError } from "./errorStatusMessage";
2+
3+
describe("#errorStatusMessage", () => {
4+
it("should return a provided error message", () => {
5+
const errMsg = "test";
6+
expect(generateMessageFromError(new Error(errMsg))).toBe(errMsg);
7+
});
8+
9+
it("should return null if no error message and no status, or status is 0", () => {
10+
expect(generateMessageFromError(new Error())).toBe(null);
11+
const fakeStatusError = new FormError();
12+
fakeStatusError.status = 0;
13+
expect(generateMessageFromError(fakeStatusError)).toBe(null);
14+
});
15+
16+
it("should return a validation error message if status is 400", () => {
17+
const fakeStatusError = new FormError();
18+
fakeStatusError.status = 400;
19+
expect(generateMessageFromError(fakeStatusError)).toMatchInlineSnapshot(`
20+
<Memo(MemoizedFormattedMessage)
21+
id="form.validationError"
22+
/>
23+
`);
24+
});
25+
26+
it("should return a 'some error' message if status is > 0 and not 400", () => {
27+
const fakeStatusError = new FormError();
28+
fakeStatusError.status = 401;
29+
expect(generateMessageFromError(fakeStatusError)).toMatchInlineSnapshot(`
30+
<Memo(MemoizedFormattedMessage)
31+
id="form.someError"
32+
/>
33+
`);
34+
});
35+
});

airbyte-webapp/src/utils/errorStatusMessage.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { FormattedMessage } from "react-intl";
22

3-
export const createFormErrorMessage = (error: { status?: number; message?: string }): JSX.Element | string | null => {
3+
export class FormError extends Error {
4+
status?: number;
5+
}
6+
7+
export const generateMessageFromError = (error: FormError): JSX.Element | string | null => {
48
if (error.message) {
59
return error.message;
610
}

airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionForm.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
import { ConfirmationModalService } from "hooks/services/ConfirmationModal/ConfirmationModalService";
1212
import { render } from "utils/testutils";
1313

14-
import ConnectionForm, { ConnectionFormProps } from "./ConnectionForm";
14+
import { ConnectionForm, ConnectionFormProps } from "./ConnectionForm";
1515

1616
const mockSource: SourceRead = {
1717
sourceId: "test-source",

0 commit comments

Comments
 (0)