From 1dbc67b9acc69a30aebef9ba9bf09b4154904c82 Mon Sep 17 00:00:00 2001 From: Artem Astapenko Date: Mon, 22 Nov 2021 17:53:26 +0700 Subject: [PATCH 01/43] Add replication page. Remove connection form from settings --- airbyte-webapp/src/locales/en.json | 1 + .../pages/ConnectionPage/ConnectionPage.tsx | 5 + .../ConnectionItemPage/ConnectionItemPage.tsx | 33 ++- .../components/ReplicationView.tsx | 217 ++++++++++++++++++ .../components/SettingsView.tsx | 207 +---------------- airbyte-webapp/src/pages/routes.tsx | 1 + 6 files changed, 254 insertions(+), 210 deletions(-) create mode 100644 airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx diff --git a/airbyte-webapp/src/locales/en.json b/airbyte-webapp/src/locales/en.json index 8783298d416a3..9570a931b904a 100644 --- a/airbyte-webapp/src/locales/en.json +++ b/airbyte-webapp/src/locales/en.json @@ -295,6 +295,7 @@ "connection.successSync": "Succeeded sync", "connection.noSyncData": "Sync was not started", "connection.refreshSchema": "Refresh schema", + "connection.replication": "Replication", "tables.sourceIsValidating": "Validating the source", "tables.sourceIsValidatingBefore": "before you add a new destination", diff --git a/airbyte-webapp/src/pages/ConnectionPage/ConnectionPage.tsx b/airbyte-webapp/src/pages/ConnectionPage/ConnectionPage.tsx index bdb7f0130cfd2..4923fe4b24131 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/ConnectionPage.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/ConnectionPage.tsx @@ -41,6 +41,11 @@ const ConnectionPage: React.FC = () => { + + + + + diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx index 1193a8128a2ce..6d9e57086a734 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx @@ -18,9 +18,10 @@ import DestinationDefinitionResource from "core/resources/DestinationDefinition" import SourceDefinitionResource from "core/resources/SourceDefinition"; import { equal } from "utils/objects"; import { useAnalyticsService } from "hooks/services/Analytics/useAnalyticsService"; +import ReplicationView from "./components/ReplicationView"; type ConnectionItemPageProps = { - currentStep: "status" | "settings"; + currentStep: "status" | "settings" | "replication"; }; const ConnectionItemPage: React.FC = ({ @@ -61,6 +62,10 @@ const ConnectionItemPage: React.FC = ({ id: "status", name: , }, + { + id: "replication", + name: , + }, { id: "settings", name: , @@ -72,6 +77,10 @@ const ConnectionItemPage: React.FC = ({ push( `${Routes.Connections}/${connection.connectionId}${Routes.Settings}` ); + } else if (id === "replication") { + push( + `${Routes.Connections}/${connection.connectionId}${Routes.Replication}` + ); } else { push(`${Routes.Connections}/${connection.connectionId}`); } @@ -89,6 +98,7 @@ const ConnectionItemPage: React.FC = ({ }; const renderStep = () => { + console.log(currentStep); if (currentStep === "status") { return ( = ({ /> ); } + if (currentStep === "replication") { + return ( + + ); + } - return ( - - ); + return ; }; const linkToSource = () => ( diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx new file mode 100644 index 0000000000000..bbdbcd8d8d829 --- /dev/null +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx @@ -0,0 +1,217 @@ +import React, { useState } from "react"; +import { FormattedMessage } from "react-intl"; +import styled from "styled-components"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faRedoAlt } from "@fortawesome/free-solid-svg-icons"; + +import { Button } from "components"; +import ContentCard from "components/ContentCard"; +import useConnection, { + useConnectionLoad, + ValuesProps, +} from "hooks/services/useConnectionHook"; +import ConnectionForm from "views/Connection/ConnectionForm"; +import ResetDataModal from "components/ResetDataModal"; +import { ModalTypes } from "components/ResetDataModal/types"; +import LoadingSchema from "components/LoadingSchema"; +import { DestinationDefinition } from "core/resources/DestinationDefinition"; +import { SourceDefinition } from "core/resources/SourceDefinition"; + +import { equal } from "utils/objects"; +import EnabledControl from "./EnabledControl"; +import { ConnectionNamespaceDefinition } from "core/domain/connection"; +import { useAsyncFn } from "react-use"; + +type IProps = { + onAfterSaveSchema: () => void; + connectionId: string; + frequencyText?: string; + destinationDefinition?: DestinationDefinition; + sourceDefinition?: SourceDefinition; +}; + +const Content = styled.div` + max-width: 1279px; + overflow-x: hidden; + margin: 18px auto; + padding-bottom: 10px; +`; + +const TitleContainer = styled.div<{ hasButton: boolean }>` + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + margin: ${({ hasButton }) => (hasButton ? "-5px 0" : 0)}; +`; + +const TryArrow = styled(FontAwesomeIcon)` + margin: 0 10px -1px 0; + font-size: 14px; +`; + +const Title = styled.div` + display: flex; + justify-content: space-between; + align-items: center; +`; + +const Message = styled.div` + margin: -5px 0 13px; + font-weight: 500; + font-size: 12px; + line-height: 15px; + color: ${({ theme }) => theme.greyColor40}; +`; + +const Note = styled.span` + color: ${({ theme }) => theme.dangerColor}; +`; + +const ReplicationView: React.FC = ({ + onAfterSaveSchema, + connectionId, + frequencyText, + destinationDefinition, + sourceDefinition, +}) => { + const [isModalOpen, setIsUpdateModalOpen] = useState(false); + const [activeUpdatingSchemaMode, setActiveUpdatingSchemaMode] = useState( + false + ); + const [saved, setSaved] = useState(false); + const [currentValues, setCurrentValues] = useState({ + namespaceDefinition: ConnectionNamespaceDefinition.Source, + namespaceFormat: "", + schedule: null, + prefix: "", + syncCatalog: { streams: [] }, + }); + + const { updateConnection, resetConnection } = useConnection(); + + const onReset = () => resetConnection(connectionId); + + const { + connection: initialConnection, + refreshConnectionCatalog, + } = useConnectionLoad(connectionId); + + const [ + { value: connectionWithRefreshCatalog, loading: isRefreshingCatalog }, + refreshCatalog, + ] = useAsyncFn(refreshConnectionCatalog, [connectionId]); + + const connection = activeUpdatingSchemaMode + ? connectionWithRefreshCatalog + : initialConnection; + + const onSubmit = async (values: ValuesProps) => { + const initialSyncSchema = connection?.syncCatalog; + + await updateConnection({ + ...values, + connectionId, + status: initialConnection.status || "", + withRefreshedCatalog: activeUpdatingSchemaMode, + }); + + setSaved(true); + if (!equal(values.syncCatalog, initialSyncSchema)) { + onAfterSaveSchema(); + } + + if (activeUpdatingSchemaMode) { + setActiveUpdatingSchemaMode(false); + } + }; + + const onSubmitResetModal = async () => { + setIsUpdateModalOpen(false); + await onSubmit(currentValues); + }; + + const onSubmitForm = async (values: ValuesProps) => { + if (activeUpdatingSchemaMode) { + setCurrentValues(values); + setIsUpdateModalOpen(true); + } else { + await onSubmit(values); + } + }; + + const onEnterRefreshCatalogMode = async () => { + setActiveUpdatingSchemaMode(true); + await refreshCatalog(); + }; + + const onExitRefreshCatalogMode = () => { + setActiveUpdatingSchemaMode(false); + }; + + const renderUpdateSchemaButton = () => { + if (!activeUpdatingSchemaMode) { + return ( + + ); + } + return ( + + {" "} + + + + + ); + }; + + return ( + + + + {" "} + + + + } + > + {!isRefreshingCatalog && connection ? ( + + } + onCancel={onExitRefreshCatalogMode} + editSchemeMode={activeUpdatingSchemaMode} + additionalSchemaControl={renderUpdateSchemaButton()} + destinationIcon={destinationDefinition?.icon} + sourceIcon={sourceDefinition?.icon} + /> + ) : ( + + )} + + {isModalOpen ? ( + setIsUpdateModalOpen(false)} + onSubmit={onSubmitResetModal} + modalType={ModalTypes.UPDATE_SCHEMA} + /> + ) : null} + + ); +}; + +export default ReplicationView; diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/SettingsView.tsx b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/SettingsView.tsx index d65f57ea035d2..015fffba69cb9 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/SettingsView.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/SettingsView.tsx @@ -1,221 +1,28 @@ -import React, { useState } from "react"; -import { FormattedMessage } from "react-intl"; +import React from "react"; import styled from "styled-components"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { faRedoAlt } from "@fortawesome/free-solid-svg-icons"; -import { Button } from "components"; -import ContentCard from "components/ContentCard"; -import useConnection, { - useConnectionLoad, - ValuesProps, -} from "hooks/services/useConnectionHook"; +import useConnection from "hooks/services/useConnectionHook"; import DeleteBlock from "components/DeleteBlock"; -import ConnectionForm from "views/Connection/ConnectionForm"; -import ResetDataModal from "components/ResetDataModal"; -import { ModalTypes } from "components/ResetDataModal/types"; -import LoadingSchema from "components/LoadingSchema"; -import { DestinationDefinition } from "core/resources/DestinationDefinition"; -import { SourceDefinition } from "core/resources/SourceDefinition"; - -import { equal } from "utils/objects"; -import EnabledControl from "./EnabledControl"; -import { ConnectionNamespaceDefinition } from "core/domain/connection"; -import { useAsyncFn } from "react-use"; type IProps = { - onAfterSaveSchema: () => void; connectionId: string; - frequencyText?: string; - destinationDefinition?: DestinationDefinition; - sourceDefinition?: SourceDefinition; }; const Content = styled.div` - max-width: 1279px; - overflow-x: hidden; + max-width: 647px; + height: 100%; margin: 18px auto; + padding-bottom: 10px; `; -const TitleContainer = styled.div<{ hasButton: boolean }>` - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - margin: ${({ hasButton }) => (hasButton ? "-5px 0" : 0)}; -`; - -const TryArrow = styled(FontAwesomeIcon)` - margin: 0 10px -1px 0; - font-size: 14px; -`; - -const Title = styled.div` - display: flex; - justify-content: space-between; - align-items: center; -`; - -const Message = styled.div` - margin: -5px 0 13px; - font-weight: 500; - font-size: 12px; - line-height: 15px; - color: ${({ theme }) => theme.greyColor40}; -`; - -const Note = styled.span` - color: ${({ theme }) => theme.dangerColor}; -`; - -const SettingsView: React.FC = ({ - onAfterSaveSchema, - connectionId, - frequencyText, - destinationDefinition, - sourceDefinition, -}) => { - const [isModalOpen, setIsUpdateModalOpen] = useState(false); - const [activeUpdatingSchemaMode, setActiveUpdatingSchemaMode] = useState( - false - ); - const [saved, setSaved] = useState(false); - const [currentValues, setCurrentValues] = useState({ - namespaceDefinition: ConnectionNamespaceDefinition.Source, - namespaceFormat: "", - schedule: null, - prefix: "", - syncCatalog: { streams: [] }, - }); - - const { - updateConnection, - deleteConnection, - resetConnection, - } = useConnection(); +const SettingsView: React.FC = ({ connectionId }) => { + const { deleteConnection } = useConnection(); const onDelete = () => deleteConnection({ connectionId }); - const onReset = () => resetConnection(connectionId); - - const { - connection: initialConnection, - refreshConnectionCatalog, - } = useConnectionLoad(connectionId); - - const [ - { value: connectionWithRefreshCatalog, loading: isRefreshingCatalog }, - refreshCatalog, - ] = useAsyncFn(refreshConnectionCatalog, [connectionId]); - - const connection = activeUpdatingSchemaMode - ? connectionWithRefreshCatalog - : initialConnection; - - const onSubmit = async (values: ValuesProps) => { - const initialSyncSchema = connection?.syncCatalog; - - await updateConnection({ - ...values, - connectionId, - status: initialConnection.status || "", - withRefreshedCatalog: activeUpdatingSchemaMode, - }); - - setSaved(true); - if (!equal(values.syncCatalog, initialSyncSchema)) { - onAfterSaveSchema(); - } - - if (activeUpdatingSchemaMode) { - setActiveUpdatingSchemaMode(false); - } - }; - - const onSubmitResetModal = async () => { - setIsUpdateModalOpen(false); - await onSubmit(currentValues); - }; - - const onSubmitForm = async (values: ValuesProps) => { - if (activeUpdatingSchemaMode) { - setCurrentValues(values); - setIsUpdateModalOpen(true); - } else { - await onSubmit(values); - } - }; - - const onEnterRefreshCatalogMode = async () => { - setActiveUpdatingSchemaMode(true); - await refreshCatalog(); - }; - - const onExitRefreshCatalogMode = () => { - setActiveUpdatingSchemaMode(false); - }; - - const renderUpdateSchemaButton = () => { - if (!activeUpdatingSchemaMode) { - return ( - - ); - } - return ( - - {" "} - - - - - ); - }; return ( - - - {" "} - - - - } - > - {!isRefreshingCatalog && connection ? ( - - } - onCancel={onExitRefreshCatalogMode} - editSchemeMode={activeUpdatingSchemaMode} - additionalSchemaControl={renderUpdateSchemaButton()} - destinationIcon={destinationDefinition?.icon} - sourceIcon={sourceDefinition?.icon} - /> - ) : ( - - )} - - {isModalOpen ? ( - setIsUpdateModalOpen(false)} - onSubmit={onSubmitResetModal} - modalType={ModalTypes.UPDATE_SCHEMA} - /> - ) : null} ); }; diff --git a/airbyte-webapp/src/pages/routes.tsx b/airbyte-webapp/src/pages/routes.tsx index 1f7aadc840bef..4158b5bf6d177 100644 --- a/airbyte-webapp/src/pages/routes.tsx +++ b/airbyte-webapp/src/pages/routes.tsx @@ -40,6 +40,7 @@ export enum Routes { SourceNew = "/new-source", DestinationNew = "/new-destination", Settings = "/settings", + Replication = "/replication", Configuration = "/configuration", Notifications = "/notifications", Metrics = "/metrics", From 9bb4075d8a3b7529d6b57d79af2518f70cdf7a5c Mon Sep 17 00:00:00 2001 From: Artem Astapenko Date: Mon, 22 Nov 2021 22:20:33 +0700 Subject: [PATCH 02/43] Fix styles for delete block --- .../src/components/DeleteBlock/DeleteBlock.tsx | 14 +++++++++----- .../src/components/base/Titles/Titles.tsx | 4 ++-- airbyte-webapp/src/locales/en.json | 3 +++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/airbyte-webapp/src/components/DeleteBlock/DeleteBlock.tsx b/airbyte-webapp/src/components/DeleteBlock/DeleteBlock.tsx index 961898989c0b6..916922f331d82 100644 --- a/airbyte-webapp/src/components/DeleteBlock/DeleteBlock.tsx +++ b/airbyte-webapp/src/components/DeleteBlock/DeleteBlock.tsx @@ -3,7 +3,7 @@ import { FormattedMessage } from "react-intl"; import styled from "styled-components"; import ContentCard from "components/ContentCard"; -import { Button } from "components"; +import { Button, H5 } from "components"; import DeleteModal from "./components/DeleteModal"; type IProps = { @@ -13,9 +13,10 @@ type IProps = { const DeleteBlockComponent = styled(ContentCard)` margin-top: 12px; - padding: 29px 28px 27px; + padding: 19px 20px 20px; display: flex; align-items: center; + justify-content: space-between; `; const Text = styled.div` @@ -32,6 +33,12 @@ const DeleteBlock: React.FC = ({ type, onDelete }) => { return ( <> + +
+ +
+ +
- - -
{isModalOpen && ( theme.h5?.fontSize || "15px"}; - line-height: ${({ theme }) => theme.h5?.lineHeight || "18px"}; + font-size: ${({ theme }) => theme.h5?.fontSize || "16px"}; + line-height: ${({ theme }) => theme.h5?.lineHeight || "28px"}; font-weight: normal; `; diff --git a/airbyte-webapp/src/locales/en.json b/airbyte-webapp/src/locales/en.json index 9570a931b904a..f98a0f0bc00d9 100644 --- a/airbyte-webapp/src/locales/en.json +++ b/airbyte-webapp/src/locales/en.json @@ -327,6 +327,9 @@ "tables.sourceDelete": "Delete this source", "tables.destinationDelete": "Delete this destination", "tables.connectionDelete": "Delete this connection", + "tables.sourceDelete.title": "Delete source", + "tables.destinationDelete.title": "Delete destination", + "tables.connectionDelete.title": "Delete connection", "tables.sourceDataDelete": "No data will be deleted from your source.", "tables.destinationDataDelete": "No data will be deleted from your destination.", "tables.connectionDataDelete": "No data will be deleted from your source and destination.\nThis cannot be un-done without a full re-sync", From f6bbda72bf61057cd4748bdd989226d802e99d03 Mon Sep 17 00:00:00 2001 From: Artem Astapenko Date: Thu, 25 Nov 2021 00:06:13 +0700 Subject: [PATCH 03/43] Add transfer form --- airbyte-webapp/src/locales/en.json | 4 + .../ConnectionItemPage/ConnectionItemPage.tsx | 2 - .../components/ReplicationView.tsx | 19 +++-- .../ConnectionForm/ConnectionForm.tsx | 2 +- .../components/EditControls.tsx | 76 ++++++++++++------- 5 files changed, 61 insertions(+), 42 deletions(-) diff --git a/airbyte-webapp/src/locales/en.json b/airbyte-webapp/src/locales/en.json index f98a0f0bc00d9..78973352208c3 100644 --- a/airbyte-webapp/src/locales/en.json +++ b/airbyte-webapp/src/locales/en.json @@ -296,6 +296,10 @@ "connection.noSyncData": "Sync was not started", "connection.refreshSchema": "Refresh schema", "connection.replication": "Replication", + "connection.streams": "Streams", + "connection.transfer": "Transfer", + "connection.replicationFrequency": "Replication frequency*", + "connection.replicationFrequency.subtitle": "Set how often data should sync to the destination", "tables.sourceIsValidating": "Validating the source", "tables.sourceIsValidatingBefore": "before you add a new destination", diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx index 6d9e57086a734..1ac8f94b5d153 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx @@ -98,7 +98,6 @@ const ConnectionItemPage: React.FC = ({ }; const renderStep = () => { - console.log(currentStep); if (currentStep === "status") { return ( = ({ 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 bbdbcd8d8d829..4ce64533fcb46 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx @@ -11,6 +11,7 @@ import useConnection, { ValuesProps, } from "hooks/services/useConnectionHook"; import ConnectionForm from "views/Connection/ConnectionForm"; +import TransferForm from "views/Connection/ConnectionForm/TransferForm"; import ResetDataModal from "components/ResetDataModal"; import { ModalTypes } from "components/ResetDataModal/types"; import LoadingSchema from "components/LoadingSchema"; @@ -18,21 +19,18 @@ import { DestinationDefinition } from "core/resources/DestinationDefinition"; import { SourceDefinition } from "core/resources/SourceDefinition"; import { equal } from "utils/objects"; -import EnabledControl from "./EnabledControl"; import { ConnectionNamespaceDefinition } from "core/domain/connection"; import { useAsyncFn } from "react-use"; type IProps = { onAfterSaveSchema: () => void; connectionId: string; - frequencyText?: string; destinationDefinition?: DestinationDefinition; sourceDefinition?: SourceDefinition; }; const Content = styled.div` max-width: 1279px; - overflow-x: hidden; margin: 18px auto; padding-bottom: 10px; `; @@ -68,10 +66,13 @@ const Note = styled.span` color: ${({ theme }) => theme.dangerColor}; `; +const Card = styled(ContentCard)` + margin-bottom: 10px; +`; + const ReplicationView: React.FC = ({ onAfterSaveSchema, connectionId, - frequencyText, destinationDefinition, sourceDefinition, }) => { @@ -170,17 +171,15 @@ const ReplicationView: React.FC = ({ return ( + }> + + - {" "} + - } > diff --git a/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionForm.tsx b/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionForm.tsx index fb1d00d7b9ed8..0525366619d6d 100644 --- a/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionForm.tsx +++ b/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionForm.tsx @@ -32,7 +32,7 @@ import { Connection, ScheduleProperties } from "core/resources/Connection"; import { FeatureItem, useFeatureService } from "hooks/services/Feature"; const FormContainer = styled(Form)` - padding: 22px 27px 23px 24px; + padding: 22px 27px 15px 24px; `; const EditLaterMessage = styled(Label)` diff --git a/airbyte-webapp/src/views/Connection/ConnectionForm/components/EditControls.tsx b/airbyte-webapp/src/views/Connection/ConnectionForm/components/EditControls.tsx index 85741f99d2acd..dfe777f8b2290 100644 --- a/airbyte-webapp/src/views/Connection/ConnectionForm/components/EditControls.tsx +++ b/airbyte-webapp/src/views/Connection/ConnectionForm/components/EditControls.tsx @@ -11,6 +11,7 @@ type IProps = { successMessage?: React.ReactNode; errorMessage?: React.ReactNode; editSchemeMode?: boolean; + withLine?: boolean; }; const Warning = styled.div` @@ -19,15 +20,19 @@ const Warning = styled.div` font-weight: bold; `; -const Controls = styled.div` - margin-top: 34px; +const Buttons = styled.div` + display: flex; + justify-content: space-between; + align-items: center; + flex-direction: row; + margin-top: 16px; `; -const ButtonContainer = styled.span` +const ControlButton = styled(Button)` margin-left: 10px; `; -const Success = styled(ButtonContainer)` +const Success = styled.span` color: ${({ theme }) => theme.successColor}; font-size: 14px; line-height: 17px; @@ -44,6 +49,13 @@ const SpinnerContainer = styled.div` top: 10px; `; +const Line = styled.div` + min-width: 100%; + height: 1px; + background: ${({ theme }) => theme.greyColor20}; + margin: 16px -27px 0 -24px; +`; + const EditControls: React.FC = ({ isSubmitting, dirty, @@ -51,6 +63,7 @@ const EditControls: React.FC = ({ successMessage, errorMessage, editSchemeMode, + withLine, }) => { const showStatusMessage = () => { if (isSubmitting) { @@ -70,36 +83,41 @@ const EditControls: React.FC = ({ }; return ( - + <> {editSchemeMode && ( )} - - - - - {showStatusMessage()} - + {withLine && } + +
{showStatusMessage()}
+
+ + + {editSchemeMode ? ( + + ) : ( + + )} + +
+
+ ); }; From 437a068a872a0a0b761f95440b827f29b4f73a0f Mon Sep 17 00:00:00 2001 From: Artem Astapenko Date: Thu, 25 Nov 2021 00:06:59 +0700 Subject: [PATCH 04/43] Fix transfer --- .../ConnectionForm/TransferForm.tsx | 132 ++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 airbyte-webapp/src/views/Connection/ConnectionForm/TransferForm.tsx diff --git a/airbyte-webapp/src/views/Connection/ConnectionForm/TransferForm.tsx b/airbyte-webapp/src/views/Connection/ConnectionForm/TransferForm.tsx new file mode 100644 index 0000000000000..f6ee71e316b3e --- /dev/null +++ b/airbyte-webapp/src/views/Connection/ConnectionForm/TransferForm.tsx @@ -0,0 +1,132 @@ +import React, { useCallback, useState } from "react"; +import { useIntl } from "react-intl"; +import styled from "styled-components"; +import { Field, FieldProps, Form, Formik } from "formik"; +import * as yup from "yup"; + +import { ControlLabels, DropDown, DropDownRow } from "components"; + +import { useFrequencyDropdownData } from "./formConfig"; +import { Connection, ScheduleProperties } from "core/resources/Connection"; +import EditControls from "./components/EditControls"; +import { createFormErrorMessage } from "utils/errorStatusMessage"; +import useConnection from "hooks/services/useConnectionHook"; + +const FormContainer = styled(Form)` + padding: 22px 27px 15px 24px; +`; + +const ConnectorLabel = styled(ControlLabels)` + max-width: 328px; + margin-right: 20px; + vertical-align: top; +`; + +type TransferFormProps = { + className?: string; + onDropDownSelect?: (item: DropDownRow.IDataItem) => void; + connection?: Connection; +}; + +const transferFormValidationSchema = yup.object({ + schedule: yup + .object({ + units: yup.number().required("form.empty.error"), + timeUnit: yup.string().required("form.empty.error"), + }) + .nullable() + .defined("form.empty.error"), +}); + +const TransferForm: React.FC = ({ + className, + connection, +}) => { + const { updateConnection } = useConnection(); + + const [submitError, setSubmitError] = useState(null); + const [saved, setSaved] = useState(false); + const formatMessage = useIntl().formatMessage; + + const onFormSubmit = useCallback( + async (values: { schedule: ScheduleProperties | null }) => { + setSubmitError(null); + setSaved(false); + + try { + if (connection) { + await updateConnection({ + schedule: values.schedule, + connectionId: connection.connectionId, + namespaceDefinition: connection.namespaceDefinition, + status: connection.status, + prefix: connection.prefix, + syncCatalog: connection.syncCatalog, + }); + } + setSaved(true); + } catch (e) { + setSubmitError(e); + } + }, + [updateConnection, connection] + ); + + const errorMessage = submitError ? createFormErrorMessage(submitError) : null; + const frequencies = useFrequencyDropdownData(); + const initialValues = { schedule: connection?.schedule || null }; + + return ( + + {({ setFieldValue, isSubmitting, dirty, resetForm, isValid }) => ( + + + {({ field, meta }: FieldProps) => ( + + { + setFieldValue(field.name, item.value); + setSaved(false); + }} + /> + + )} + + + + )} + + ); +}; + +export default TransferForm; From 23c553e4ffc35273e6347878cfd3d9ecd0eb533e Mon Sep 17 00:00:00 2001 From: Artem Astapenko Date: Thu, 25 Nov 2021 02:45:33 +0700 Subject: [PATCH 05/43] Remove source and destination icon and name from connection form --- .../CreateConnectionContent.tsx | 16 ------ .../ConnectionItemPage/ConnectionItemPage.tsx | 2 - .../components/ReplicationView.tsx | 8 --- .../ConnectionForm/ConnectionForm.tsx | 21 +------- .../ConnectionForm/components/Connector.tsx | 52 ------------------- 5 files changed, 1 insertion(+), 98 deletions(-) delete mode 100644 airbyte-webapp/src/views/Connection/ConnectionForm/components/Connector.tsx diff --git a/airbyte-webapp/src/components/CreateConnectionContent/CreateConnectionContent.tsx b/airbyte-webapp/src/components/CreateConnectionContent/CreateConnectionContent.tsx index 149c053e2021d..3e9260335539f 100644 --- a/airbyte-webapp/src/components/CreateConnectionContent/CreateConnectionContent.tsx +++ b/airbyte-webapp/src/components/CreateConnectionContent/CreateConnectionContent.tsx @@ -3,7 +3,6 @@ import { FormattedMessage } from "react-intl"; import styled from "styled-components"; import { faRedoAlt } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { useResource } from "rest-hooks"; import { Button } from "components"; import LoadingSchema from "components/LoadingSchema"; @@ -16,8 +15,6 @@ import { Destination } from "core/resources/Destination"; import useConnection, { ValuesProps } from "hooks/services/useConnectionHook"; import { useDiscoverSchema } from "hooks/services/useSchemaHook"; -import SourceDefinitionResource from "core/resources/SourceDefinition"; -import DestinationDefinitionResource from "core/resources/DestinationDefinition"; import { IDataItem } from "components/base/DropDown/components/Option"; import { useAnalyticsService } from "hooks/services/Analytics/useAnalyticsService"; @@ -53,17 +50,6 @@ const CreateConnectionContent: React.FC = ({ const { createConnection } = useConnection(); const analyticsService = useAnalyticsService(); - const sourceDefinition = useResource(SourceDefinitionResource.detailShape(), { - sourceDefinitionId: source.sourceDefinitionId, - }); - - const destinationDefinition = useResource( - DestinationDefinitionResource.detailShape(), - { - destinationDefinitionId: destination.destinationDefinitionId, - } - ); - const { schema, isLoading, @@ -157,8 +143,6 @@ const CreateConnectionContent: React.FC = ({ } onSubmit={onSubmitConnectionStep} - sourceIcon={sourceDefinition?.icon} - destinationIcon={destinationDefinition?.icon} />
diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx index 1ac8f94b5d153..3365b1941d598 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx @@ -113,8 +113,6 @@ const ConnectionItemPage: React.FC = ({ ); } 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 4ce64533fcb46..472bfeaebaa44 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx @@ -15,8 +15,6 @@ import TransferForm from "views/Connection/ConnectionForm/TransferForm"; import ResetDataModal from "components/ResetDataModal"; import { ModalTypes } from "components/ResetDataModal/types"; import LoadingSchema from "components/LoadingSchema"; -import { DestinationDefinition } from "core/resources/DestinationDefinition"; -import { SourceDefinition } from "core/resources/SourceDefinition"; import { equal } from "utils/objects"; import { ConnectionNamespaceDefinition } from "core/domain/connection"; @@ -25,8 +23,6 @@ import { useAsyncFn } from "react-use"; type IProps = { onAfterSaveSchema: () => void; connectionId: string; - destinationDefinition?: DestinationDefinition; - sourceDefinition?: SourceDefinition; }; const Content = styled.div` @@ -73,8 +69,6 @@ const Card = styled(ContentCard)` const ReplicationView: React.FC = ({ onAfterSaveSchema, connectionId, - destinationDefinition, - sourceDefinition, }) => { const [isModalOpen, setIsUpdateModalOpen] = useState(false); const [activeUpdatingSchemaMode, setActiveUpdatingSchemaMode] = useState( @@ -195,8 +189,6 @@ const ReplicationView: React.FC = ({ onCancel={onExitRefreshCatalogMode} editSchemeMode={activeUpdatingSchemaMode} additionalSchemaControl={renderUpdateSchemaButton()} - destinationIcon={destinationDefinition?.icon} - sourceIcon={sourceDefinition?.icon} /> ) : ( diff --git a/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionForm.tsx b/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionForm.tsx index 0525366619d6d..9e5048e6ec177 100644 --- a/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionForm.tsx +++ b/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionForm.tsx @@ -25,7 +25,6 @@ import { } from "./formConfig"; import SectionTitle from "./components/SectionTitle"; import CreateControls from "./components/CreateControls"; -import Connector from "./components/Connector"; import SchemaField from "./components/SyncCatalogField"; import EditControls from "./components/EditControls"; import { Connection, ScheduleProperties } from "core/resources/Connection"; @@ -62,8 +61,6 @@ type ConnectionFormProps = { editSchemeMode?: boolean; isEditMode?: boolean; additionalSchemaControl?: React.ReactNode; - sourceIcon?: string; - destinationIcon?: string; connection: | Connection @@ -75,8 +72,6 @@ const ConnectionForm: React.FC = ({ onSubmit, onReset, onCancel, - sourceIcon, - destinationIcon, className, onDropDownSelect, isEditMode, @@ -96,7 +91,7 @@ const ConnectionForm: React.FC = ({ const formatMessage = useIntl().formatMessage; const { hasFeature } = useFeatureService(); - const { source, destination, operations } = connection; + const { operations } = connection; const supportsNormalization = destDefinition.supportsNormalization; const supportsTransformations = destDefinition.supportsDbt && hasFeature(FeatureItem.AllowCustomDBT); @@ -167,20 +162,6 @@ const ConnectionForm: React.FC = ({ {({ isSubmitting, setFieldValue, isValid, dirty, resetForm }) => ( - - - - - - {({ field, meta }: FieldProps) => ( theme.greyColor0}; - background: ${({ theme }) => theme.greyColor0}; - color: ${({ theme }) => theme.textColor}; - display: flex; - justify-content: space-between; - align-items: center; -`; - -const Icon = styled(ImageBlock)` - margin-right: 6px; - display: inline-block; - vertical-align: sub; -`; - -const ConnectorName = styled.div` - display: flex; - align-items: center; - flex-direction: row; -`; - -type IProps = { - name: string; - icon?: string; -}; - -const Connector: React.FC = ({ name, icon }) => { - return ( - - - - {name} - - - - ); -}; - -export default Connector; From b81f697b4e7bd5512a85fe41d8df9ea889d3584a Mon Sep 17 00:00:00 2001 From: Artem Astapenko Date: Thu, 25 Nov 2021 02:49:16 +0700 Subject: [PATCH 06/43] Remove frequency field from edit connection form --- .../ConnectionForm/ConnectionForm.tsx | 48 ++++++++++--------- .../ConnectionForm/TransferForm.tsx | 4 +- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionForm.tsx b/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionForm.tsx index 9e5048e6ec177..5f3f3d5220cff 100644 --- a/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionForm.tsx +++ b/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionForm.tsx @@ -161,30 +161,32 @@ const ConnectionForm: React.FC = ({ > {({ isSubmitting, setFieldValue, isValid, dirty, resetForm }) => ( - - - {({ field, meta }: FieldProps) => ( - - + + {({ field, meta }: FieldProps) => ( + { - if (onDropDownSelect) { - onDropDownSelect(item); - } - setFieldValue(field.name, item.value); - }} - /> - - )} - - + label={formatMessage({ + id: "form.frequency", + })} + > + { + if (onDropDownSelect) { + onDropDownSelect(item); + } + setFieldValue(field.name, item.value); + }} + /> + + )} + + + )} {({ field }: FieldProps) => ( diff --git a/airbyte-webapp/src/views/Connection/ConnectionForm/TransferForm.tsx b/airbyte-webapp/src/views/Connection/ConnectionForm/TransferForm.tsx index f6ee71e316b3e..69b2184772a64 100644 --- a/airbyte-webapp/src/views/Connection/ConnectionForm/TransferForm.tsx +++ b/airbyte-webapp/src/views/Connection/ConnectionForm/TransferForm.tsx @@ -114,9 +114,7 @@ const TransferForm: React.FC = ({ isSubmitting={isSubmitting} dirty={dirty} resetForm={resetForm} - successMessage={ - saved && formatMessage({ id: "settings.changeSaved" }) - } + successMessage={saved && formatMessage({ id: "form.changesSaved" })} errorMessage={ errorMessage || !isValid ? formatMessage({ id: "connectionForm.validation.error" }) From dd69ac3ec4f9baa3b617940618275a5a9affc65d Mon Sep 17 00:00:00 2001 From: Artem Astapenko Date: Thu, 25 Nov 2021 03:10:17 +0700 Subject: [PATCH 07/43] Add transformation view --- airbyte-webapp/src/locales/en.json | 2 ++ .../pages/ConnectionPage/ConnectionPage.tsx | 5 ++++ .../ConnectionItemPage/ConnectionItemPage.tsx | 14 ++++++++- .../components/TransformationView.tsx | 30 +++++++++++++++++++ airbyte-webapp/src/pages/routes.tsx | 1 + 5 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/TransformationView.tsx diff --git a/airbyte-webapp/src/locales/en.json b/airbyte-webapp/src/locales/en.json index 78973352208c3..9cb840c8629aa 100644 --- a/airbyte-webapp/src/locales/en.json +++ b/airbyte-webapp/src/locales/en.json @@ -300,6 +300,8 @@ "connection.transfer": "Transfer", "connection.replicationFrequency": "Replication frequency*", "connection.replicationFrequency.subtitle": "Set how often data should sync to the destination", + "connection.normalization": "Normalization", + "connection.customTransformations": "Custom Transformations", "tables.sourceIsValidating": "Validating the source", "tables.sourceIsValidatingBefore": "before you add a new destination", diff --git a/airbyte-webapp/src/pages/ConnectionPage/ConnectionPage.tsx b/airbyte-webapp/src/pages/ConnectionPage/ConnectionPage.tsx index 4923fe4b24131..2a78f14cfb1d1 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/ConnectionPage.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/ConnectionPage.tsx @@ -46,6 +46,11 @@ const ConnectionPage: React.FC = () => {
+ + + + + diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx index 3365b1941d598..d62a616106c6a 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx @@ -7,6 +7,7 @@ import HeadTitle from "components/HeadTitle"; import useRouter from "hooks/useRouter"; import StepsMenu from "components/StepsMenu"; import StatusView from "./components/StatusView"; +import TransformationView from "./components/TransformationView"; import SettingsView from "./components/SettingsView"; import ConnectionResource from "core/resources/Connection"; import LoadingPage from "components/LoadingPage"; @@ -21,7 +22,7 @@ import { useAnalyticsService } from "hooks/services/Analytics/useAnalyticsServic import ReplicationView from "./components/ReplicationView"; type ConnectionItemPageProps = { - currentStep: "status" | "settings" | "replication"; + currentStep: "status" | "settings" | "replication" | "transformation"; }; const ConnectionItemPage: React.FC = ({ @@ -66,6 +67,10 @@ const ConnectionItemPage: React.FC = ({ id: "replication", name: , }, + { + id: "transformation", + name: , + }, { id: "settings", name: , @@ -81,6 +86,10 @@ const ConnectionItemPage: React.FC = ({ push( `${Routes.Connections}/${connection.connectionId}${Routes.Replication}` ); + } else if (id === "transformation") { + push( + `${Routes.Connections}/${connection.connectionId}${Routes.Transformation}` + ); } else { push(`${Routes.Connections}/${connection.connectionId}`); } @@ -116,6 +125,9 @@ const ConnectionItemPage: React.FC = ({ /> ); } + if (currentStep === "transformation") { + return ; + } return ; }; diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/TransformationView.tsx b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/TransformationView.tsx new file mode 100644 index 0000000000000..7f18e53f14993 --- /dev/null +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/TransformationView.tsx @@ -0,0 +1,30 @@ +import React from "react"; +import { FormattedMessage } from "react-intl"; +import styled from "styled-components"; + +import ContentCard from "components/ContentCard"; + +type TransformationViewProps = {}; + +const Content = styled.div` + max-width: 1073px; + margin: 18px auto; + padding-bottom: 10px; +`; + +const Card = styled(ContentCard)` + margin-bottom: 10px; +`; + +const TransformationView: React.FC = () => { + return ( + + } /> + } + /> + + ); +}; + +export default TransformationView; diff --git a/airbyte-webapp/src/pages/routes.tsx b/airbyte-webapp/src/pages/routes.tsx index 3ce5c176c27df..efe864581f811 100644 --- a/airbyte-webapp/src/pages/routes.tsx +++ b/airbyte-webapp/src/pages/routes.tsx @@ -41,6 +41,7 @@ export enum Routes { DestinationNew = "/new-destination", Settings = "/settings", Replication = "/replication", + Transformation = "/transformation", Configuration = "/configuration", Notifications = "/notifications", Metrics = "/metrics", From 4ff018e8bce8b88b9925ebc62bf2f8502a67db5d Mon Sep 17 00:00:00 2001 From: Artem Astapenko Date: Thu, 25 Nov 2021 04:04:05 +0700 Subject: [PATCH 08/43] Update title for connection page --- .../src/components/base/Titles/Titles.tsx | 13 ++- .../src/components/base/Titles/index.tsx | 4 +- airbyte-webapp/src/locales/en.json | 1 + .../ConnectionItemPage/ConnectionItemPage.tsx | 82 ++----------- .../components/ConnectionPageTitle.tsx | 109 ++++++++++++++++++ .../components/ReplicationView.tsx | 2 +- .../components/SettingsView.tsx | 3 +- .../components/StatusView.tsx | 2 +- .../components/TransformationView.tsx | 2 +- 9 files changed, 133 insertions(+), 85 deletions(-) create mode 100644 airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ConnectionPageTitle.tsx diff --git a/airbyte-webapp/src/components/base/Titles/Titles.tsx b/airbyte-webapp/src/components/base/Titles/Titles.tsx index 61c61ed54b851..49f7d66594b7e 100644 --- a/airbyte-webapp/src/components/base/Titles/Titles.tsx +++ b/airbyte-webapp/src/components/base/Titles/Titles.tsx @@ -4,17 +4,18 @@ type IProps = { center?: boolean; bold?: boolean; parentColor?: boolean; + highlighted?: boolean; }; export const H1 = styled.h1` font-size: ${({ theme }) => theme.h1?.fontSize || "28px"}; line-height: ${({ theme }) => theme.h1?.lineHeight || "34px"}; font-style: normal; - font-weight: ${(props) => (props.bold ? 600 : 500)}; + font-weight: ${(props) => (props.bold ? "bold" : 500)}; display: block; text-align: ${(props) => (props.center ? "center" : "left")}; - color: ${({ theme, parentColor }) => - parentColor ? "inherid" : theme.textColor}; + color: ${({ theme, parentColor, highlighted }) => + parentColor ? "inherid" : highlighted ? theme.redColor : theme.textColor}; margin: 0; `; @@ -36,5 +37,9 @@ export const H4 = styled(H1).attrs({ as: "h4" })` export const H5 = styled(H1).attrs({ as: "h5" })` font-size: ${({ theme }) => theme.h5?.fontSize || "16px"}; line-height: ${({ theme }) => theme.h5?.lineHeight || "28px"}; - font-weight: normal; +`; + +export const H6 = styled(H1).attrs({ as: "h6" })` + font-size: ${({ theme }) => theme.h5?.fontSize || "14px"}; + line-height: ${({ theme }) => theme.h5?.lineHeight || "17px"}; `; diff --git a/airbyte-webapp/src/components/base/Titles/index.tsx b/airbyte-webapp/src/components/base/Titles/index.tsx index f1381ac358e1a..5ca271a5fbce3 100644 --- a/airbyte-webapp/src/components/base/Titles/index.tsx +++ b/airbyte-webapp/src/components/base/Titles/index.tsx @@ -1,3 +1,3 @@ -import { H1, H2, H3, H4, H5 } from "./Titles"; +import { H1, H2, H3, H4, H5, H6 } from "./Titles"; -export { H1, H2, H3, H4, H5 }; +export { H1, H2, H3, H4, H5, H6 }; diff --git a/airbyte-webapp/src/locales/en.json b/airbyte-webapp/src/locales/en.json index 9cb840c8629aa..3c981df751e63 100644 --- a/airbyte-webapp/src/locales/en.json +++ b/airbyte-webapp/src/locales/en.json @@ -275,6 +275,7 @@ "syncMode.incremental": "Incremental", "connection.warningUpdateSchema": "WARNING! Updating the schema will delete all the data for this connection in your destination and start syncing from scratch.", + "connection.title": "Connection", "connection.fromTo": "{source} → {destination}", "connection.connectionSettings": "Connection settings", "connection.testsPassed": "All connection tests passed", diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx index d62a616106c6a..086249a59cefb 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx @@ -1,20 +1,16 @@ import React, { Suspense } from "react"; -import { FormattedMessage } from "react-intl"; import { useResource } from "rest-hooks"; -import PageTitle from "components/PageTitle"; import HeadTitle from "components/HeadTitle"; import useRouter from "hooks/useRouter"; -import StepsMenu from "components/StepsMenu"; import StatusView from "./components/StatusView"; import TransformationView from "./components/TransformationView"; import SettingsView from "./components/SettingsView"; +import ConnectionPageTitle from "./components/ConnectionPageTitle"; import ConnectionResource from "core/resources/Connection"; import LoadingPage from "components/LoadingPage"; import MainPageWithScroll from "components/MainPageWithScroll"; import FrequencyConfig from "config/FrequencyConfig.json"; -import Link from "components/Link"; -import { Routes } from "../../../routes"; import DestinationDefinitionResource from "core/resources/DestinationDefinition"; import SourceDefinitionResource from "core/resources/SourceDefinition"; import { equal } from "utils/objects"; @@ -28,7 +24,8 @@ type ConnectionItemPageProps = { const ConnectionItemPage: React.FC = ({ currentStep, }) => { - const { query, push } = useRouter<{ id: string }>(); + const { query } = useRouter<{ id: string }>(); + const analyticsService = useAnalyticsService(); const connection = useResource(ConnectionResource.detailShape(), { connectionId: query.id, @@ -58,43 +55,6 @@ const ConnectionItemPage: React.FC = ({ : null ); - const steps = [ - { - id: "status", - name: , - }, - { - id: "replication", - name: , - }, - { - id: "transformation", - name: , - }, - { - id: "settings", - name: , - }, - ]; - - const onSelectStep = (id: string) => { - if (id === "settings") { - push( - `${Routes.Connections}/${connection.connectionId}${Routes.Settings}` - ); - } else if (id === "replication") { - push( - `${Routes.Connections}/${connection.connectionId}${Routes.Replication}` - ); - } else if (id === "transformation") { - push( - `${Routes.Connections}/${connection.connectionId}${Routes.Transformation}` - ); - } else { - push(`${Routes.Connections}/${connection.connectionId}`); - } - }; - const onAfterSaveSchema = () => { analyticsService.track("Source - Action", { action: "Edit schema", @@ -132,18 +92,6 @@ const ConnectionItemPage: React.FC = ({ return ; }; - const linkToSource = () => ( - - {source.name} - - ); - - const linkToDestination = () => ( - - {destination.name} - - ); - return ( = ({ /> } pageTitle={ - - } - middleComponent={ - - } + } > diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ConnectionPageTitle.tsx b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ConnectionPageTitle.tsx new file mode 100644 index 0000000000000..97ab6000a226f --- /dev/null +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ConnectionPageTitle.tsx @@ -0,0 +1,109 @@ +import React from "react"; +import styled from "styled-components"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faArrowRight } from "@fortawesome/free-solid-svg-icons"; + +import { Source } from "core/resources/Source"; +import { Destination } from "core/resources/Destination"; +import { FormattedMessage } from "react-intl"; +import { H6 } from "components/base"; +import Link from "components/Link"; +import { Routes } from "pages/routes"; +import StepsMenu from "components/StepsMenu"; +import useRouter from "hooks/useRouter"; + +type IProps = { + source: Source; + destination: Destination; + connectionId: string; + currentStep: "status" | "settings" | "replication" | "transformation"; +}; + +const Title = styled.div` + text-align: center; + padding: 21px 0 10px; +`; + +const Links = styled.div` + margin-bottom: 18px; + font-size: 15px; + font-weight: bold; +`; + +const ConnectorsLink = styled(Link)` + font-style: normal; + font-weight: bold; + font-size: 24px; + line-height: 29px; + text-align: center; + display: inline-block; + margin: 0 16px; + color: ${({ theme }) => theme.textColor}; +`; + +const ConnectionPageTitle: React.FC = ({ + source, + destination, + currentStep, + connectionId, +}) => { + const { push } = useRouter<{ id: string }>(); + + const steps = [ + { + id: "status", + name: , + }, + { + id: "replication", + name: , + }, + { + id: "transformation", + name: , + }, + { + id: "settings", + name: , + }, + ]; + + const onSelectStep = (id: string) => { + if (id === "settings") { + push(`${Routes.Connections}/${connectionId}${Routes.Settings}`); + } else if (id === "replication") { + push(`${Routes.Connections}/${connectionId}${Routes.Replication}`); + } else if (id === "transformation") { + push(`${Routes.Connections}/${connectionId}${Routes.Transformation}`); + } else { + push(`${Routes.Connections}/${connectionId}`); + } + }; + + return ( + + <H6 center bold highlighted> + <FormattedMessage id="connection.title" /> + </H6> + <Links> + <ConnectorsLink to={`${Routes.Source}/${source.sourceId}`}> + {source.name} + </ConnectorsLink> + <FontAwesomeIcon icon={faArrowRight} /> + <ConnectorsLink + to={`${Routes.Destination}/${destination.destinationId}`} + > + {destination.name} + </ConnectorsLink> + </Links> + <StepsMenu + lightMode + data={steps} + onSelect={onSelectStep} + activeStep={currentStep} + /> + + ); +}; + +export default ConnectionPageTitle; 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 472bfeaebaa44..0b461d0c9593f 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx @@ -27,7 +27,7 @@ type IProps = { const Content = styled.div` max-width: 1279px; - margin: 18px auto; + margin: 0 auto; padding-bottom: 10px; `; diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/SettingsView.tsx b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/SettingsView.tsx index 015fffba69cb9..a632c7e3f6a2b 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/SettingsView.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/SettingsView.tsx @@ -10,8 +10,7 @@ type IProps = { const Content = styled.div` max-width: 647px; - height: 100%; - margin: 18px auto; + margin: 0 auto; padding-bottom: 10px; `; diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/StatusView.tsx b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/StatusView.tsx index 8b657dc792d3a..cefb52a4e83ed 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/StatusView.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/StatusView.tsx @@ -27,7 +27,7 @@ type IProps = { }; const Content = styled.div` - margin: 18px 10px; + margin: 0 10px; `; const StyledContentCard = styled(ContentCard)` diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/TransformationView.tsx b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/TransformationView.tsx index 7f18e53f14993..cebcfa50903f7 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/TransformationView.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/TransformationView.tsx @@ -8,7 +8,7 @@ type TransformationViewProps = {}; const Content = styled.div` max-width: 1073px; - margin: 18px auto; + margin: 0 auto; padding-bottom: 10px; `; From 2f96d38748c29499669e7248a2bab172af21f62a Mon Sep 17 00:00:00 2001 From: Artem Astapenko Date: Mon, 13 Dec 2021 23:44:21 +0300 Subject: [PATCH 09/43] Hide transformation page --- .../src/pages/ConnectionPage/ConnectionPage.tsx | 10 +++++----- .../components/ConnectionPageTitle.tsx | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/airbyte-webapp/src/pages/ConnectionPage/ConnectionPage.tsx b/airbyte-webapp/src/pages/ConnectionPage/ConnectionPage.tsx index 2a78f14cfb1d1..5abbb9990b5a7 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/ConnectionPage.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/ConnectionPage.tsx @@ -46,11 +46,11 @@ const ConnectionPage: React.FC = () => { - - - - - + {/**/} + {/* */} + {/* */} + {/* */} + {/**/} diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ConnectionPageTitle.tsx b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ConnectionPageTitle.tsx index 97ab6000a226f..7dd0785f6ff37 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ConnectionPageTitle.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ConnectionPageTitle.tsx @@ -58,10 +58,10 @@ const ConnectionPageTitle: React.FC = ({ id: "replication", name: , }, - { - id: "transformation", - name: , - }, + // { + // id: "transformation", + // name: , + // }, { id: "settings", name: , From e17c4f7f0142e76dfd75f074e40f6917b1d1d5bf Mon Sep 17 00:00:00 2001 From: Artem Astapenko Date: Tue, 14 Dec 2021 23:57:48 +0300 Subject: [PATCH 10/43] Edit search in connection form --- .../src/components/base/Button/Button.tsx | 2 +- airbyte-webapp/src/locales/en.json | 6 ++-- .../components/ReplicationView.tsx | 7 ++-- .../ConnectionForm/components/Search.tsx | 14 +------- .../components/SyncCatalogField.tsx | 36 ++++++++++--------- 5 files changed, 27 insertions(+), 38 deletions(-) diff --git a/airbyte-webapp/src/components/base/Button/Button.tsx b/airbyte-webapp/src/components/base/Button/Button.tsx index bbd074363b654..4e5a69cd08f97 100644 --- a/airbyte-webapp/src/components/base/Button/Button.tsx +++ b/airbyte-webapp/src/components/base/Button/Button.tsx @@ -41,7 +41,7 @@ const getTextColor = (props: IStyleProps) => { } return props.theme.primaryColor; } else if (props.secondary || props.iconOnly) { - return props.theme.greyColor60; + return props.theme.darkGreyColor; } return props.theme.whiteColor; diff --git a/airbyte-webapp/src/locales/en.json b/airbyte-webapp/src/locales/en.json index d3d413e63087d..d64ca01051fbc 100644 --- a/airbyte-webapp/src/locales/en.json +++ b/airbyte-webapp/src/locales/en.json @@ -45,7 +45,7 @@ "form.syncSettings": "Sync settings", "form.primaryKey": "Primary key", "form.cursorField": "Cursor field", - "form.dataSync": "Select the data you want to sync", + "form.dataSync": "Activate the streams you want to sync", "form.dataSync.message": "Don’t worry! You’ll be able to change this later on.", "form.cancel": "Cancel", "form.submit": "Submit", @@ -90,7 +90,7 @@ "form.prefix": "Table Prefix", "form.prefix.message": "Prefix to prefix all destination tables created as part of this connection. Useful for identifying tables on a per-connection basis and namespacing streams from different sources so they do not overwrite each other.", "form.prefix.placeholder": "prefix-", - "form.nameSearch": "Search name", + "form.nameSearch": "Search stream name", "form.namespace": "Namespace", "form.noNamespace": "No namespace", "form.sourceConnector": "Source connector", @@ -293,7 +293,7 @@ "connection.destinationTestAgain": "Test destination connection again", "connection.sourceTestAgain": "Test source connection again", "connection.resetData": "Reset your data", - "connection.updateSchema": "Update latest source schema", + "connection.updateSchema": "Refresh source schema", "connection.updateSchemaText": "WARNING! Updating the schema will delete all the data for this connection in your destination and start syncing from scratch. Are you sure you want to do this?", "connection.newConnection": "+ new connection", "connection.newConnectionTitle": "New connection", 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 0b461d0c9593f..3e98bbee8775c 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx @@ -2,7 +2,7 @@ import React, { useState } from "react"; import { FormattedMessage } from "react-intl"; import styled from "styled-components"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { faRedoAlt } from "@fortawesome/free-solid-svg-icons"; +import { faSyncAlt } from "@fortawesome/free-solid-svg-icons"; import { Button } from "components"; import ContentCard from "components/ContentCard"; @@ -51,7 +51,6 @@ const Title = styled.div` `; const Message = styled.div` - margin: -5px 0 13px; font-weight: 500; font-size: 12px; line-height: 15px; @@ -147,8 +146,8 @@ const ReplicationView: React.FC = ({ const renderUpdateSchemaButton = () => { if (!activeUpdatingSchemaMode) { return ( - ); diff --git a/airbyte-webapp/src/views/Connection/ConnectionForm/components/Search.tsx b/airbyte-webapp/src/views/Connection/ConnectionForm/components/Search.tsx index 47abeb0010559..4ef85ba723d32 100644 --- a/airbyte-webapp/src/views/Connection/ConnectionForm/components/Search.tsx +++ b/airbyte-webapp/src/views/Connection/ConnectionForm/components/Search.tsx @@ -1,8 +1,6 @@ import React from "react"; import { useIntl } from "react-intl"; import styled from "styled-components"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { faSearch } from "@fortawesome/free-solid-svg-icons"; import { Input } from "components"; @@ -11,20 +9,11 @@ type SearchProps = { }; const SearchInput = styled(Input)` - padding: 3px 10px 3px 24px; -`; - -const SearchIcon = styled(FontAwesomeIcon)` - position: absolute; - top: 6px; - left: 6px; - font-size: 14px; - color: ${({ theme }) => theme.greyColor40}; + padding: 10px 8px 9px; `; const SearchContent = styled.div` position: relative; - max-width: 270px; width: 100%; &:before { @@ -37,7 +26,6 @@ const Search: React.FC = ({ onSearch }) => { return ( - ({ lighter: true }))` align-items: center; `; -const SearchContent = styled.div` +const FiltersContent = styled.div` + margin: 6px 0 21px; display: flex; - flex-direction: row; - align-items: center; `; const RadioButtonControl = styled(LabeledRadioButton)` margin: 0 0 0 5px; `; +const HeaderBlock = styled.div` + margin: 10px 0 6px; + display: flex; + justify-content: space-between; + align-items: center; + flex-direction: row; + font-weight: 500; + font-size: 14px; + line-height: 17px; +`; + type SchemaViewProps = { additionalControl?: React.ReactNode; destinationSupportedSyncModes: DestinationSyncMode[]; @@ -129,14 +133,12 @@ const SyncCatalogField: React.FC = ({ return ( <> -
- - - + + {additionalControl} -
- - + + + { setFilterMode(value.target.value as SyncCatalogFilters); @@ -164,7 +166,7 @@ const SyncCatalogField: React.FC = ({ checked={filterMode === SyncCatalogFilters.NotSelected} label={} /> - + From 4e9327fc67a4f543f0f09670e9666c364c4235c7 Mon Sep 17 00:00:00 2001 From: Artem Astapenko Date: Fri, 24 Dec 2021 00:55:26 +0300 Subject: [PATCH 11/43] Fix conflicts --- .../ConnectionItemPage/ConnectionItemPage.tsx | 68 +++---------------- .../components/ConnectionPageTitle.tsx | 29 +++----- .../components/StatusMainInfo.tsx | 6 +- .../components/TransformationView.tsx | 2 +- 4 files changed, 26 insertions(+), 79 deletions(-) diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx index bcc9a076c1555..52ac26b84e499 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx @@ -1,12 +1,9 @@ import React, { Suspense } from "react"; import { useResource } from "rest-hooks"; import { Navigate, Route, Routes } from "react-router-dom"; - -import { RoutePaths } from "pages/routes"; -import { Link, LoadingPage, MainPageWithScroll } from "components"; -import PageTitle from "components/PageTitle"; +import { LoadingPage, MainPageWithScroll } from "components"; import HeadTitle from "components/HeadTitle"; -import StepsMenu from "components/StepsMenu";import useRouter from "hooks/useRouter"; +import useRouter from "hooks/useRouter"; import StatusView from "./components/StatusView"; import TransformationView from "./components/TransformationView"; import SettingsView from "./components/SettingsView"; @@ -20,7 +17,7 @@ import { useAnalyticsService } from "hooks/services/Analytics/useAnalyticsServic import ReplicationView from "./components/ReplicationView"; const ConnectionItemPage: React.FC = () => { - const { params, push } = useRouter<{ id: string }>(); + const { params } = useRouter<{ id: string }>(); const { id } = params; const currentStep = params["*"] || "status"; const connection = useResource(ConnectionResource.detailShape(), { @@ -47,25 +44,6 @@ const ConnectionItemPage: React.FC = () => { : null ); - const steps = [ - { - id: "status", - name: , - }, - { - id: "settings", - name: , - }, - ]; - - const onSelectStep = (id: string) => { - if (id === "settings") { - push(`${RoutePaths.Settings}`); - } else { - push(""); - } - }; - const analyticsService = useAnalyticsService(); const frequency = FrequencyConfig.find((item) => @@ -83,32 +61,6 @@ const ConnectionItemPage: React.FC = () => { }); }; - const renderStep = () => { - if (currentStep === "status") { - return ( - - ); - } - if (currentStep === "replication") { - return ( - - ); - } - if (currentStep === "transformation") { - return ; - } - - return ; - }; - return ( { }> { /> } /> + } /> } + />{" "} + } /> } /> diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ConnectionPageTitle.tsx b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ConnectionPageTitle.tsx index 7dd0785f6ff37..4882c2a652a62 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ConnectionPageTitle.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ConnectionPageTitle.tsx @@ -3,12 +3,10 @@ import styled from "styled-components"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faArrowRight } from "@fortawesome/free-solid-svg-icons"; -import { Source } from "core/resources/Source"; -import { Destination } from "core/resources/Destination"; +import { Source, Destination } from "core/domain/connector/types"; import { FormattedMessage } from "react-intl"; -import { H6 } from "components/base"; -import Link from "components/Link"; -import { Routes } from "pages/routes"; +import { H6, Link } from "components"; +import { RoutePaths } from "pages/routes"; import StepsMenu from "components/StepsMenu"; import useRouter from "hooks/useRouter"; @@ -45,18 +43,17 @@ const ConnectionPageTitle: React.FC = ({ source, destination, currentStep, - connectionId, }) => { const { push } = useRouter<{ id: string }>(); const steps = [ { id: "status", - name: , + name: , }, { id: "replication", - name: , + name: , }, // { // id: "transformation", @@ -64,19 +61,15 @@ const ConnectionPageTitle: React.FC = ({ // }, { id: "settings", - name: , + name: , }, ]; const onSelectStep = (id: string) => { - if (id === "settings") { - push(`${Routes.Connections}/${connectionId}${Routes.Settings}`); - } else if (id === "replication") { - push(`${Routes.Connections}/${connectionId}${Routes.Replication}`); - } else if (id === "transformation") { - push(`${Routes.Connections}/${connectionId}${Routes.Transformation}`); + if (id === "status") { + push(""); } else { - push(`${Routes.Connections}/${connectionId}`); + push(id); } }; @@ -86,12 +79,12 @@ const ConnectionPageTitle: React.FC = ({ - + {source.name} {destination.name} diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/StatusMainInfo.tsx b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/StatusMainInfo.tsx index 9d1c8f7429234..24304ba3b0b65 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/StatusMainInfo.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/StatusMainInfo.tsx @@ -2,13 +2,13 @@ import React from "react"; import { FormattedMessage } from "react-intl"; import styled from "styled-components"; -import ContentCard from "components/ContentCard"; -import ImageBlock from "components/ImageBlock"; +import { ContentCard, ImageBlock } from "components"; import { Header, Row, Cell } from "components/SimpleTableComponents"; import EnabledControl from "./EnabledControl"; -import { Connection } from "core/resources/Connection"; import { DestinationDefinition, SourceDefinition } from "core/domain/connector"; +import { Connection } from "core/resources/Connection"; + const MainInfo = styled(ContentCard)` margin-bottom: 14px; padding: 23px 20px 20px 23px; diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/TransformationView.tsx b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/TransformationView.tsx index cebcfa50903f7..571bb47c08f3f 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/TransformationView.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/TransformationView.tsx @@ -2,7 +2,7 @@ import React from "react"; import { FormattedMessage } from "react-intl"; import styled from "styled-components"; -import ContentCard from "components/ContentCard"; +import { ContentCard } from "components"; type TransformationViewProps = {}; From 3d757fd36bca061bb408dec2ac2230fbb97ec286 Mon Sep 17 00:00:00 2001 From: Artem Astapenko Date: Sun, 26 Dec 2021 00:16:23 +0300 Subject: [PATCH 12/43] Add CollapsibleCard, FormCard --- .../pages/ConnectionPage/ConnectionPage.tsx | 2 +- .../ConnectionItemPage/ConnectionItemPage.tsx | 43 ++++-- .../components/ConnectionPageTitle.tsx | 19 +-- .../components/ReplicationView.tsx | 19 +-- .../components/TransformationView.tsx | 30 ---- .../pages/OnboardingPage/OnboardingPage.tsx | 5 +- .../components/ConnectionStep.tsx | 4 +- .../src/views/Connection/CollapsibleCard.tsx | 44 ++++++ .../ConnectionForm/TransferForm.tsx | 130 ------------------ .../ConnectionForm/TransferFormCard.tsx | 96 +++++++++++++ .../components/EditControls.tsx | 19 +-- .../components/NormalizationField.tsx | 4 +- .../components/TransformationField.tsx | 59 ++++---- .../src/views/Connection/FormCard.tsx | 63 +++++++++ .../views/Connection/TransformationView.tsx | 70 ++++++++++ 15 files changed, 357 insertions(+), 250 deletions(-) delete mode 100644 airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/TransformationView.tsx create mode 100644 airbyte-webapp/src/views/Connection/CollapsibleCard.tsx delete mode 100644 airbyte-webapp/src/views/Connection/ConnectionForm/TransferForm.tsx create mode 100644 airbyte-webapp/src/views/Connection/ConnectionForm/TransferFormCard.tsx create mode 100644 airbyte-webapp/src/views/Connection/FormCard.tsx create mode 100644 airbyte-webapp/src/views/Connection/TransformationView.tsx diff --git a/airbyte-webapp/src/pages/ConnectionPage/ConnectionPage.tsx b/airbyte-webapp/src/pages/ConnectionPage/ConnectionPage.tsx index 1e14ddfb8dc98..78d3935b8c060 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/ConnectionPage.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/ConnectionPage.tsx @@ -2,7 +2,7 @@ import React, { Suspense } from "react"; import { Route, Routes } from "react-router-dom"; import { RoutePaths } from "../routes"; -import LoadingPage from "components/LoadingPage"; +import { LoadingPage } from "components"; import ConnectionItemPage from "./pages/ConnectionItemPage"; import CreationFormPage from "./pages/CreationFormPage"; import AllConnectionsPage from "./pages/AllConnectionsPage"; diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx index 52ac26b84e499..df7d0f67b8eb4 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx @@ -1,21 +1,33 @@ import React, { Suspense } from "react"; import { useResource } from "rest-hooks"; import { Navigate, Route, Routes } from "react-router-dom"; + import { LoadingPage, MainPageWithScroll } from "components"; import HeadTitle from "components/HeadTitle"; + import useRouter from "hooks/useRouter"; -import StatusView from "./components/StatusView"; -import TransformationView from "./components/TransformationView"; -import SettingsView from "./components/SettingsView"; -import ConnectionPageTitle from "./components/ConnectionPageTitle"; -import ConnectionResource from "core/resources/Connection"; +import { useAnalyticsService } from "hooks/services/Analytics/useAnalyticsService"; + import FrequencyConfig from "config/FrequencyConfig.json"; + +import ConnectionResource from "core/resources/Connection"; import DestinationDefinitionResource from "core/resources/DestinationDefinition"; import SourceDefinitionResource from "core/resources/SourceDefinition"; import { equal } from "utils/objects"; -import { useAnalyticsService } from "hooks/services/Analytics/useAnalyticsService"; import ReplicationView from "./components/ReplicationView"; +import StatusView from "./components/StatusView"; +import TransformationView from "views/Connection/TransformationView"; +import SettingsView from "./components/SettingsView"; +import ConnectionPageTitle from "./components/ConnectionPageTitle"; + +export const ConnectionSettingsRoutes = { + STATUS: "status", + TRANSFORMATION: "transformation", + REPLICATION: "replication", + SETTINGS: "settings", +} as const; + const ConnectionItemPage: React.FC = () => { const { params } = useRouter<{ id: string }>(); const { id } = params; @@ -82,14 +94,13 @@ const ConnectionItemPage: React.FC = () => { source={source} destination={destination} currentStep={currentStep} - connectionId={connection.connectionId} /> } > }> { /> } /> - } /> } + /> + } - />{" "} + /> } /> - } /> + } + /> diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ConnectionPageTitle.tsx b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ConnectionPageTitle.tsx index 4882c2a652a62..96847f75ec9d4 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ConnectionPageTitle.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ConnectionPageTitle.tsx @@ -2,19 +2,20 @@ import React from "react"; import styled from "styled-components"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faArrowRight } from "@fortawesome/free-solid-svg-icons"; +import { FormattedMessage } from "react-intl"; import { Source, Destination } from "core/domain/connector/types"; -import { FormattedMessage } from "react-intl"; import { H6, Link } from "components"; import { RoutePaths } from "pages/routes"; import StepsMenu from "components/StepsMenu"; import useRouter from "hooks/useRouter"; +import { ConnectionSettingsRoutes } from "../ConnectionItemPage"; + type IProps = { source: Source; destination: Destination; - connectionId: string; - currentStep: "status" | "settings" | "replication" | "transformation"; + currentStep: keyof typeof ConnectionSettingsRoutes; }; const Title = styled.div` @@ -55,10 +56,10 @@ const ConnectionPageTitle: React.FC = ({ id: "replication", name: , }, - // { - // id: "transformation", - // name: , - // }, + { + id: "transformation", + name: , + }, { id: "settings", name: , @@ -79,12 +80,12 @@ const ConnectionPageTitle: React.FC = ({ - + {source.name} {destination.name} 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 3e98bbee8775c..f1cc5d19aa0f7 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx @@ -3,22 +3,22 @@ import { FormattedMessage } from "react-intl"; import styled from "styled-components"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faSyncAlt } from "@fortawesome/free-solid-svg-icons"; +import { useAsyncFn } from "react-use"; import { Button } from "components"; -import ContentCard from "components/ContentCard"; import useConnection, { useConnectionLoad, ValuesProps, } from "hooks/services/useConnectionHook"; import ConnectionForm from "views/Connection/ConnectionForm"; -import TransferForm from "views/Connection/ConnectionForm/TransferForm"; +import TransferFormCard from "views/Connection/ConnectionForm/TransferFormCard"; import ResetDataModal from "components/ResetDataModal"; import { ModalTypes } from "components/ResetDataModal/types"; import LoadingSchema from "components/LoadingSchema"; import { equal } from "utils/objects"; import { ConnectionNamespaceDefinition } from "core/domain/connection"; -import { useAsyncFn } from "react-use"; +import { CollapsibleCard } from "views/Connection/CollapsibleCard"; type IProps = { onAfterSaveSchema: () => void; @@ -61,10 +61,6 @@ const Note = styled.span` color: ${({ theme }) => theme.dangerColor}; `; -const Card = styled(ContentCard)` - margin-bottom: 10px; -`; - const ReplicationView: React.FC = ({ onAfterSaveSchema, connectionId, @@ -164,10 +160,9 @@ const ReplicationView: React.FC = ({ return ( - }> - - - + @@ -192,7 +187,7 @@ const ReplicationView: React.FC = ({ ) : ( )} - + {isModalOpen ? ( setIsUpdateModalOpen(false)} diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/TransformationView.tsx b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/TransformationView.tsx deleted file mode 100644 index 571bb47c08f3f..0000000000000 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/TransformationView.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import React from "react"; -import { FormattedMessage } from "react-intl"; -import styled from "styled-components"; - -import { ContentCard } from "components"; - -type TransformationViewProps = {}; - -const Content = styled.div` - max-width: 1073px; - margin: 0 auto; - padding-bottom: 10px; -`; - -const Card = styled(ContentCard)` - margin-bottom: 10px; -`; - -const TransformationView: React.FC = () => { - return ( - - } /> - } - /> - - ); -}; - -export default TransformationView; diff --git a/airbyte-webapp/src/pages/OnboardingPage/OnboardingPage.tsx b/airbyte-webapp/src/pages/OnboardingPage/OnboardingPage.tsx index 12edd1e3be4a0..929563475bbe9 100644 --- a/airbyte-webapp/src/pages/OnboardingPage/OnboardingPage.tsx +++ b/airbyte-webapp/src/pages/OnboardingPage/OnboardingPage.tsx @@ -156,7 +156,6 @@ const OnboardingPage: React.FC = () => { availableServices={sourceDefinitions} hasSuccess={successRequest} error={errorStatusRequest} - // source={sources.length && !successRequest ? sources[0] : undefined} /> ); } @@ -201,9 +200,6 @@ const OnboardingPage: React.FC = () => { availableServices={destinationDefinitions} hasSuccess={successRequest} error={errorStatusRequest} - // destination={ - // destinations.length && !successRequest ? destinations[0] : undefined - // } /> ); } @@ -243,6 +239,7 @@ const OnboardingPage: React.FC = () => { }>{renderStep()} +