Skip to content

Commit

Permalink
design: configuration change modal redesign (#13052)
Browse files Browse the repository at this point in the history
Co-authored-by: Vladimir <[email protected]>
  • Loading branch information
teallarson and dizel852 committed Jul 29, 2024
1 parent 056b6f4 commit 3961026
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { getTestId } from "utils/selectors";

const resetModalSaveButton = "[data-testid='resetModal-save']";
const successResult = "div[data-id='success-result']";
const resetModalResetCheckbox = "[data-testid='resetModal-reset-checkbox']";
const resetModalResetRadio = "[data-testid='radio-button-tile-shouldClear-saveWithClear']";
const saveStreamChangesButton = "button[data-testid='resetModal-save']";
const schemaChangesDetectedBanner = "[data-testid='schemaChangesDetected']";
const schemaChangesReviewButton = "[data-testid='schemaChangesDetected-button']";
Expand Down Expand Up @@ -58,7 +58,7 @@ export const checkSuccessResult = () => cy.get(successResult).should("exist");

export const confirmStreamConfigurationChangedPopup = ({ reset = false } = {}) => {
if (!reset) {
cy.get(resetModalResetCheckbox).click({ force: true });
cy.get(resetModalResetRadio).click({ force: true });
}
cy.get(saveStreamChangesButton).click();
};
Expand Down
19 changes: 13 additions & 6 deletions airbyte-webapp/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -543,14 +543,21 @@
"connection.onboarding.addDestination": "Connect a source in order to send data to {destination}",
"connection.onboarding.moreDestinations": "Connect a source in order to send data to any of Airbyte’s {count, plural, =0 {} other {{count}+}} destinations",
"connection.onboarding.demoInstance": "or play around in our <demoLnk>demo instance</demoLnk>.",
"connection.streamConfigurationChanged": "Stream configuration changed",
"connection.clearDataHint": "Due to changes in the stream configuration, we recommend clearing the data from your destination. Clearing data will delete data in the destination of the affected streams.",
"connection.clearDataHint.emphasized": "You will need to trigger a re-sync after this operation to bring your data up to date. Skipping these steps are discouraged and might lead to unexpected behavior.",

"connection.refreshDataRecommended": "Refresh streams recommended",
"connection.saveWithRefresh": "Save configuration and refresh streams (recommended)",
"connection.refreshDataHint": "Due to changes in the stream configuration, we recommend refreshing the affected streams.",
"connection.saveWithoutRefresh": "Save configuration without refreshing streams",
"connection.saveWithoutRefresh.description": "Note: If you do not refresh the affected streams, unexpected behavior may occur",

"connection.clearDataRecommended": "Clear streams recommended",
"connection.clearDataHint": "Due to changes in the stream configuration, we recommend clearing the affected streams. This will delete data in the destination for those streams. Please sync after clearing to bring your data up to date.",
"connection.saveWithDataClear": "Clear data from affected streams (recommended)",
"connection.saveWithFullDataClear": "Clear all data (recommended)",
"connection.saveWithRefresh": "Refresh your data (recommended)",
"connection.refreshDataHint": "Due to changes in your stream configuration, we recommend refreshing the data in your destination. Your connection could sync incorrectly if a refresh is not performed.",
"connection.refreshDataHint.description": "A refresh pulls all historical data from the source. During the refresh, all existing sync schedules will be paused until the refresh is complete, which means your data may become stale. It will also sync all enabled streams in this connection. This can incur additional costs.",
"connection.saveWithClear": "Save configuration and clear streams (recommended)",
"connection.saveWithoutClear": "Save configuration without clearing streams",
"connection.saveWithoutClear.description": "Note: If you do not clear data from the affected streams, unexpected behavior may occur",
"connection.refreshDataHint.description": "A refresh pulls all historical data from the source. During the refresh, all existing sync schedules will be paused until the refresh is complete. It will also sync all enabled streams in this connection. This can incur additional costs.",
"connection.save": "Save connection",
"connection.title": "Connection",
"connection.fromTo": "{source} → {destination}",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { FormattedMessage } from "react-intl";

import { LabeledSwitch } from "components";
import { RadioButtonTiles } from "components/connection/CreateConnection/RadioButtonTiles";
import { Box } from "components/ui/Box";
import { Button } from "components/ui/Button";
import { ModalBody, ModalFooter } from "components/ui/Modal";
Expand All @@ -15,44 +15,50 @@ interface ResetWarningModalProps {
stateType: ConnectionStateType;
}

export const ClearDataWarningModal: React.FC<ResetWarningModalProps> = ({ onCancel, onComplete, stateType }) => {
const { formatMessage } = useIntl();
const [withReset, setWithReset] = useState(true);
const requireFullReset = stateType === ConnectionStateType.legacy;

const checkboxLabel = requireFullReset ? "connection.saveWithFullDataClear" : "connection.saveWithDataClear";
export const ClearDataWarningModal: React.FC<ResetWarningModalProps> = ({ onCancel, onComplete }) => {
const [shouldClear, setShouldClear] = useState("true");

return (
<>
<ModalBody>
<Text>
<Text size="lg">
<FormattedMessage id="connection.clearDataHint" />
</Text>
<Box pt="md">
<Text italicized>
<FormattedMessage id="connection.clearDataHint.emphasized" />
</Text>
</Box>

<p>
<LabeledSwitch
name="reset"
checked={withReset}
onChange={(ev) => setWithReset(ev.target.checked)}
label={formatMessage({
id: checkboxLabel,
})}
checkbox
<Box pt="lg">
<RadioButtonTiles
light
direction="column"
options={[
{
value: "saveWithClear",
label: <FormattedMessage id="connection.saveWithClear" />,
description: "",
},
{
value: "saveWithoutClear",
label: <FormattedMessage id="connection.saveWithoutClear" />,
description: (
<Text color="grey400" italicized>
<FormattedMessage id="connection.saveWithoutClear.description" />
</Text>
),
},
]}
selectedValue={shouldClear}
onSelectRadioButton={(value) => {
setShouldClear(value);
}}
name="shouldClear"
data-testid="resetModal-reset-checkbox"
/>
</p>
</Box>
</ModalBody>
<ModalFooter>
<Button onClick={onCancel} variant="secondary" data-testid="resetModal-cancel">
<FormattedMessage id="form.cancel" />
</Button>
<Button onClick={() => onComplete(withReset)} data-testid="resetModal-save">
<FormattedMessage id="connection.save" />
<Button onClick={() => onComplete(shouldClear === "saveWithClear")} data-testid="resetModal-save">
<FormattedMessage id="form.submit" />
</Button>
</ModalFooter>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,15 +143,15 @@ export const ConnectionReplicationPage: React.FC = () => {
// recommend clearing data
const stateType = await getStateType(connection.connectionId);
const result = await openModal<boolean>({
title: formatMessage({ id: "connection.streamConfigurationChanged" }),
title: formatMessage({ id: "connection.clearDataRecommended" }),
size: "md",
content: (props) => <ClearDataWarningModal {...props} stateType={stateType} />,
});
await handleModalResult(result, values, saveConnection);
} else {
// recommend refreshing data
const result = await openModal<boolean>({
title: formatMessage({ id: "connection.streamConfigurationChanged" }),
title: formatMessage({ id: "connection.refreshDataRecommended" }),
size: "md",
content: ({ onCancel, onComplete }) => (
<RecommendRefreshModal onCancel={onCancel} onComplete={onComplete} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { FormattedMessage } from "react-intl";

import { LabeledSwitch } from "components";
import { RadioButtonTiles } from "components/connection/CreateConnection/RadioButtonTiles";
import { Box } from "components/ui/Box";
import { Button } from "components/ui/Button";
import { ModalBody, ModalFooter } from "components/ui/Modal";
Expand All @@ -12,37 +12,48 @@ interface RecommendedRefreshWarningProps {
onComplete: (withRefresh: boolean) => void;
}
export const RecommendRefreshModal: React.FC<RecommendedRefreshWarningProps> = ({ onCancel, onComplete }) => {
const [withRefresh, setWithRefresh] = useState(true);
const { formatMessage } = useIntl();
const [shouldRefresh, setShouldRefresh] = useState("saveWithRefresh");

return (
<>
<ModalBody>
<Text>
<FormattedMessage id="connection.refreshDataHint" />
</Text>
<Box pt="md">
<Text color="grey400" size="sm">
<FormattedMessage id="connection.refreshDataHint.description" />
</Text>
</Box>
<p>
<LabeledSwitch
name="refresh"
checked={withRefresh}
onChange={(ev) => setWithRefresh(ev.target.checked)}
label={formatMessage({
id: "connection.saveWithRefresh",
})}
checkbox
data-testid="refreshModal-refresh-checkbox"
<Box pt="lg">
<RadioButtonTiles
light
direction="column"
options={[
{
value: "saveWithRefresh",
label: <FormattedMessage id="connection.saveWithRefresh" />,
description: "",
"data-testid": "resetModal-reset-checkbox",
},
{
value: "saveWithoutRefresh",
label: <FormattedMessage id="connection.saveWithoutRefresh" />,
description: (
<Text color="grey400" italicized>
<FormattedMessage id="connection.saveWithoutRefresh.description" />
</Text>
),
},
]}
selectedValue={shouldRefresh}
onSelectRadioButton={(value) => {
setShouldRefresh(value);
}}
name="shouldRefresh"
/>
</p>
</Box>
</ModalBody>
<ModalFooter>
<Button onClick={onCancel} variant="secondary" data-testid="refreshModal-cancel">
<FormattedMessage id="form.cancel" />
</Button>
<Button onClick={() => onComplete(withRefresh)} data-testid="refreshModal-save">
<Button onClick={() => onComplete(shouldRefresh === "saveWithRefresh")} data-testid="refreshModal-save">
<FormattedMessage id="connection.save" />
</Button>
</ModalFooter>
Expand Down

0 comments on commit 3961026

Please sign in to comment.