diff --git a/airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts b/airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts index 1c47973ccdb3..ec9fb8f93635 100644 --- a/airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts +++ b/airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts @@ -7,7 +7,7 @@ const destinationNamespaceCustom = "div[data-testid='namespaceDefinition-customf const destinationNamespaceSource = "div[data-testid='namespaceDefinition-source']"; const destinationNamespaceCustomInput = "input[data-testid='input']"; const syncModeDropdown = "div[data-testid='syncSettingsDropdown'] input"; -const successResult = "span[data-id='success-result']"; +const successResult = "div[data-id='success-result']"; const saveStreamChangesButton = "button[data-testid='resetModal-save']"; const connectionNameInput = "input[data-testid='connectionName']"; diff --git a/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionForm.tsx b/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionForm.tsx index 89147975a657..40169ef03bc4 100644 --- a/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionForm.tsx +++ b/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionForm.tsx @@ -185,6 +185,9 @@ export const ConnectionForm: React.FC = ({ ); const errorMessage = submitError ? generateMessageFromError(submitError) : null; + const determineErrorMessage = (isValid: boolean) => { + return errorMessage ?? (!isValid ? formatMessage({ id: "connectionForm.validation.error" }) : null); + }; return ( = ({ onCancel?.(); }} successMessage={successMessage} - errorMessage={errorMessage || !isValid ? formatMessage({ id: "connectionForm.validation.error" }) : null} + errorMessage={determineErrorMessage(isValid)} enableControls={canSubmitUntouchedForm} /> )} @@ -336,9 +339,7 @@ export const ConnectionForm: React.FC = ({ )} diff --git a/airbyte-webapp/src/views/Connection/ConnectionForm/components/EditControls.module.scss b/airbyte-webapp/src/views/Connection/ConnectionForm/components/EditControls.module.scss new file mode 100644 index 000000000000..5bb1f4ed4dad --- /dev/null +++ b/airbyte-webapp/src/views/Connection/ConnectionForm/components/EditControls.module.scss @@ -0,0 +1,25 @@ +@use "../../../../scss/colors"; +@use "../../../../scss/variables"; + +.content { + display: flex; + justify-content: flex-end; + align-items: center; + flex-direction: row; + margin-top: variables.$spacing-lg; + gap: variables.$spacing-lg; + padding: variables.$spacing-sm; +} + +.controlButton { + margin-left: variables.$spacing-md; +} + +// currently only implemented on transformation view form card, margins are specific to that implementation +// todo: standardize the margin sizes here +.line { + min-width: 100%; + height: variables.$border-thin; + background: colors.$grey; + margin: variables.$spacing-lg -27px 0 -24px; +} diff --git a/airbyte-webapp/src/views/Connection/ConnectionForm/components/EditControls.tsx b/airbyte-webapp/src/views/Connection/ConnectionForm/components/EditControls.tsx index 8fb8b4d83eb9..395d3ef468a5 100644 --- a/airbyte-webapp/src/views/Connection/ConnectionForm/components/EditControls.tsx +++ b/airbyte-webapp/src/views/Connection/ConnectionForm/components/EditControls.tsx @@ -1,9 +1,11 @@ import React from "react"; import { FormattedMessage } from "react-intl"; -import styled from "styled-components"; import { Button, LoadingButton } from "components"; +import styles from "./EditControls.module.scss"; +import { ResponseMessage } from "./ResponseMessage"; + interface EditControlProps { isSubmitting: boolean; dirty: boolean; @@ -15,35 +17,6 @@ interface EditControlProps { withLine?: boolean; } -const Buttons = styled.div` - display: flex; - justify-content: space-between; - align-items: center; - flex-direction: row; - margin-top: 16px; -`; - -const ControlButton = styled(LoadingButton)` - margin-left: 10px; -`; - -const Success = styled.span` - color: ${({ theme }) => theme.successColor}; - font-size: 14px; - line-height: 17px; -`; - -const Error = styled(Success)` - color: ${({ theme }) => theme.dangerColor}; -`; - -const Line = styled.div` - min-width: 100%; - height: 1px; - background: ${({ theme }) => theme.greyColor20}; - margin: 16px -27px 0 -24px; -`; - const EditControls: React.FC = ({ isSubmitting, dirty, @@ -54,34 +27,25 @@ const EditControls: React.FC = ({ enableControls, withLine, }) => { - const showStatusMessage = () => { - if (errorMessage) { - return {errorMessage}; - } - if (successMessage && !dirty) { - return {successMessage}; - } - return null; - }; - return ( <> - {withLine && } - -
{showStatusMessage()}
+ {withLine &&
} +
+
- - +
- +
); }; diff --git a/airbyte-webapp/src/views/Connection/ConnectionForm/components/ResponseMessage.module.scss b/airbyte-webapp/src/views/Connection/ConnectionForm/components/ResponseMessage.module.scss new file mode 100644 index 000000000000..c25439ef2ed5 --- /dev/null +++ b/airbyte-webapp/src/views/Connection/ConnectionForm/components/ResponseMessage.module.scss @@ -0,0 +1,16 @@ +@use "../../../../scss/colors"; + +.message { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + flex: 1; +} + +.success { + color: colors.$green; +} + +.error { + color: colors.$red; +} diff --git a/airbyte-webapp/src/views/Connection/ConnectionForm/components/ResponseMessage.tsx b/airbyte-webapp/src/views/Connection/ConnectionForm/components/ResponseMessage.tsx new file mode 100644 index 000000000000..fc6ecc62b44e --- /dev/null +++ b/airbyte-webapp/src/views/Connection/ConnectionForm/components/ResponseMessage.tsx @@ -0,0 +1,33 @@ +import classnames from "classnames"; + +import { Text } from "components/base/Text"; + +import styles from "./ResponseMessage.module.scss"; + +interface ResponseMessageProps { + successMessage?: React.ReactNode; + errorMessage?: React.ReactNode; + dirty: boolean; +} +export const ResponseMessage: React.FC = ({ successMessage, errorMessage, dirty }) => { + const messageStyle = classnames(styles.message, { + [styles.success]: successMessage, + [styles.error]: errorMessage, + }); + if (errorMessage) { + return ( + + {errorMessage} + + ); + } + + if (successMessage && !dirty) { + return ( + + {successMessage} + + ); + } + return null; +};