Skip to content

Commit 81eac50

Browse files
lmossmanTim Roes
andauthored
🪟 🎉 remove sub-1 hour frequency options (#15708)
* remove sub-1-hour frequency options, and add current connection frequency to dropdown * fix e2e test * add additional frequency to end of options instead of beginning * use better jest expect methods * refactor getFrequencyConfig util function to just use connection schedule values * move frequencyConfig to a TS file and remove unnecessary type field * use named export Co-authored-by: Tim Roes <[email protected]>
1 parent 5776dcc commit 81eac50

File tree

11 files changed

+108
-117
lines changed

11 files changed

+108
-117
lines changed

airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ describe("Connection main actions", () => {
2828
cy.get("div[data-id='replication-step']").click();
2929

3030
cy.get("div[data-testid='schedule']").click();
31-
cy.get("div[data-testid='Every 5 minutes']").click();
31+
cy.get("div[data-testid='Every hour']").click();
3232
cy.get("button[type=submit]").first().click();
3333
cy.wait("@updateConnection");
3434
cy.get("span[data-id='success-result']").should("exist");

airbyte-webapp/src/components/EntityTable/hooks.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { getFrequencyConfig } from "config/utils";
1+
import { getFrequencyType } from "config/utils";
22
import { Action, Namespace } from "core/analytics";
33
import { buildConnectionUpdate } from "core/domain/connection";
44
import { useAnalyticsService } from "hooks/services/Analytics";
@@ -21,14 +21,12 @@ const useSyncActions = (): {
2121
})
2222
);
2323

24-
const frequency = getFrequencyConfig(connection.schedule);
25-
2624
const enabledStreams = connection.syncCatalog.streams.filter((stream) => stream.config?.selected).length;
2725

2826
const trackableAction = connection.status === ConnectionStatus.active ? Action.DISABLE : Action.REENABLE;
2927

3028
analyticsService.track(Namespace.CONNECTION, trackableAction, {
31-
frequency: frequency?.type,
29+
frequency: getFrequencyType(connection.schedule),
3230
connector_source: connection.source?.sourceName,
3331
connector_source_definition_id: connection.source?.sourceDefinitionId,
3432
connector_destination: connection.destination?.destinationName,

airbyte-webapp/src/config/FrequencyConfig.json

Lines changed: 0 additions & 76 deletions
This file was deleted.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { ConnectionSchedule } from "core/request/AirbyteClient";
2+
3+
export const frequencyConfig: Array<ConnectionSchedule | null> = [
4+
null, // manual
5+
{
6+
units: 1,
7+
timeUnit: "hours",
8+
},
9+
{
10+
units: 2,
11+
timeUnit: "hours",
12+
},
13+
{
14+
units: 3,
15+
timeUnit: "hours",
16+
},
17+
{
18+
units: 6,
19+
timeUnit: "hours",
20+
},
21+
{
22+
units: 8,
23+
timeUnit: "hours",
24+
},
25+
{
26+
units: 12,
27+
timeUnit: "hours",
28+
},
29+
{
30+
units: 24,
31+
timeUnit: "hours",
32+
},
33+
];

airbyte-webapp/src/config/utils.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import FrequencyConfig from "config/FrequencyConfig.json";
21
import { ConnectionSchedule } from "core/request/AirbyteClient";
3-
import { equal } from "utils/objects";
42

5-
export const getFrequencyConfig = (schedule?: ConnectionSchedule) =>
6-
FrequencyConfig.find((item) => (!schedule && !item.config) || equal(item.config, schedule));
3+
export const getFrequencyType = (schedule?: ConnectionSchedule) =>
4+
schedule ? `${schedule.units} ${schedule.timeUnit}` : "manual";

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

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { QueryClient, useMutation, useQueryClient } from "react-query";
22

3-
import { getFrequencyConfig } from "config/utils";
3+
import { getFrequencyType } from "config/utils";
44
import { Action, Namespace } from "core/analytics";
55
import { SyncSchema } from "core/domain/catalog";
66
import { WebBackendConnectionService } from "core/domain/connection";
@@ -92,15 +92,13 @@ export const useSyncConnection = () => {
9292
const analyticsService = useAnalyticsService();
9393

9494
return useMutation((connection: WebBackendConnectionRead) => {
95-
const frequency = getFrequencyConfig(connection.schedule);
96-
9795
analyticsService.track(Namespace.CONNECTION, Action.SYNC, {
9896
actionDescription: "Manual triggered sync",
9997
connector_source: connection.source?.sourceName,
10098
connector_source_definition_id: connection.source?.sourceDefinitionId,
10199
connector_destination: connection.destination?.destinationName,
102100
connector_destination_definition_id: connection.destination?.destinationDefinitionId,
103-
frequency: frequency?.type,
101+
frequency: getFrequencyType(connection.schedule),
104102
});
105103

106104
return service.sync(connection.connectionId);
@@ -143,11 +141,9 @@ const useCreateConnection = () => {
143141

144142
const enabledStreams = values.syncCatalog.streams.filter((stream) => stream.config?.selected).length;
145143

146-
const frequencyData = getFrequencyConfig(values.schedule);
147-
148144
analyticsService.track(Namespace.CONNECTION, Action.CREATE, {
149145
actionDescription: "New connection created",
150-
frequency: frequencyData?.type || "",
146+
frequency: getFrequencyType(values.schedule),
151147
connector_source_definition: source?.sourceName,
152148
connector_source_definition_id: sourceDefinition?.sourceDefinitionId,
153149
connector_destination_definition: destination?.destinationName,

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Navigate, Route, Routes, useParams } from "react-router-dom";
44
import { LoadingPage, MainPageWithScroll } from "components";
55
import HeadTitle from "components/HeadTitle";
66

7-
import { getFrequencyConfig } from "config/utils";
7+
import { getFrequencyType } from "config/utils";
88
import { Action, Namespace } from "core/analytics";
99
import { ConnectionStatus } from "core/request/AirbyteClient";
1010
import { useAnalyticsService } from "hooks/services/Analytics";
@@ -30,16 +30,14 @@ const ConnectionItemPage: React.FC = () => {
3030

3131
const { source, destination } = connection;
3232

33-
const frequency = getFrequencyConfig(connection.schedule);
34-
3533
const onAfterSaveSchema = () => {
3634
analyticsService.track(Namespace.CONNECTION, Action.EDIT_SCHEMA, {
3735
actionDescription: "Connection saved with catalog changes",
3836
connector_source: source.sourceName,
3937
connector_source_definition_id: source.sourceDefinitionId,
4038
connector_destination: destination.destinationName,
4139
connector_destination_definition_id: destination.destinationDefinitionId,
42-
frequency: frequency?.type,
40+
frequency: getFrequencyType(connection.schedule),
4341
});
4442
};
4543

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { Link } from "react-router-dom";
55

66
import ConnectorCard from "components/ConnectorCard";
77

8-
import { getFrequencyConfig } from "config/utils";
8+
import { getFrequencyType } from "config/utils";
99
import { ConnectionStatus, SourceRead, DestinationRead, WebBackendConnectionRead } from "core/request/AirbyteClient";
1010
import { FeatureItem, useFeature } from "hooks/services/Feature";
1111
import { RoutePaths } from "pages/routePaths";
@@ -32,7 +32,6 @@ export const StatusMainInfo: React.FC<StatusMainInfoProps> = ({
3232
const destinationDefinition = useDestinationDefinition(destination.destinationDefinitionId);
3333

3434
const allowSync = useFeature(FeatureItem.AllowSync);
35-
const frequency = getFrequencyConfig(connection.schedule);
3635

3736
const sourceConnectionPath = `../../${RoutePaths.Source}/${source.sourceId}`;
3837
const destinationConnectionPath = `../../${RoutePaths.Destination}/${destination.destinationId}`;
@@ -64,7 +63,7 @@ export const StatusMainInfo: React.FC<StatusMainInfoProps> = ({
6463
onStatusUpdating={onStatusUpdating}
6564
disabled={!allowSync}
6665
connection={connection}
67-
frequencyType={frequency?.type}
66+
frequencyType={getFrequencyType(connection.schedule)}
6867
/>
6968
</div>
7069
)}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ const ConnectionForm: React.FC<ConnectionFormProps> = ({
185185
);
186186

187187
const errorMessage = submitError ? createFormErrorMessage(submitError) : null;
188-
const frequencies = useFrequencyDropdownData();
188+
const frequencies = useFrequencyDropdownData(connection.schedule);
189189

190190
return (
191191
<Formik
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { renderHook } from "@testing-library/react-hooks";
2+
3+
import { frequencyConfig } from "config/frequencyConfig";
4+
import { ConnectionScheduleTimeUnit } from "core/request/AirbyteClient";
5+
import { TestWrapper as wrapper } from "utils/testutils";
6+
7+
import { useFrequencyDropdownData } from "./formConfig";
8+
9+
describe("useFrequencyDropdownData", () => {
10+
it("should return only default frequencies when no additional frequency is provided", () => {
11+
const { result } = renderHook(() => useFrequencyDropdownData(undefined), { wrapper });
12+
expect(result.current.map((item) => item.value)).toEqual(frequencyConfig);
13+
});
14+
15+
it("should return only default frequencies when additional frequency is already present", () => {
16+
const additionalFrequency = {
17+
units: 1,
18+
timeUnit: ConnectionScheduleTimeUnit["hours"],
19+
};
20+
const { result } = renderHook(() => useFrequencyDropdownData(additionalFrequency), { wrapper });
21+
expect(result.current.map((item) => item.value)).toEqual(frequencyConfig);
22+
});
23+
24+
it("should include additional frequency when provided and unique", () => {
25+
const additionalFrequency = {
26+
units: 7,
27+
timeUnit: ConnectionScheduleTimeUnit["minutes"],
28+
};
29+
const { result } = renderHook(() => useFrequencyDropdownData(additionalFrequency), { wrapper });
30+
31+
expect(result.current.length).toEqual(frequencyConfig.length + 1);
32+
expect(result.current).toContainEqual({ label: "Every 7 minutes", value: { units: 7, timeUnit: "minutes" } });
33+
});
34+
});

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

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import * as yup from "yup";
44

55
import { DropDownRow } from "components";
66

7-
import FrequencyConfig from "config/FrequencyConfig.json";
7+
import { frequencyConfig } from "config/frequencyConfig";
88
import { SyncSchema } from "core/domain/catalog";
99
import {
1010
isDbtTransformation,
@@ -254,24 +254,35 @@ const useInitialValues = (
254254
}, [initialSchema, connection, isEditMode, destDefinition]);
255255
};
256256

257-
const useFrequencyDropdownData = (): DropDownRow.IDataItem[] => {
257+
const useFrequencyDropdownData = (
258+
additionalFrequency: WebBackendConnectionRead["schedule"]
259+
): DropDownRow.IDataItem[] => {
258260
const { formatMessage } = useIntl();
259261

260-
return useMemo(
261-
() =>
262-
FrequencyConfig.map((item) => ({
263-
value: item.config,
264-
label: item.config
265-
? formatMessage(
266-
{
267-
id: `form.every.${item.config.timeUnit}`,
268-
},
269-
{ value: item.config.units }
270-
)
271-
: formatMessage({ id: "frequency.manual" }),
272-
})),
273-
[formatMessage]
274-
);
262+
return useMemo(() => {
263+
const frequencies = [...frequencyConfig];
264+
if (additionalFrequency) {
265+
const additionalFreqAlreadyPresent = frequencies.some(
266+
(frequency) =>
267+
frequency?.timeUnit === additionalFrequency.timeUnit && frequency?.units === additionalFrequency.units
268+
);
269+
if (!additionalFreqAlreadyPresent) {
270+
frequencies.push(additionalFrequency);
271+
}
272+
}
273+
274+
return frequencies.map((frequency) => ({
275+
value: frequency,
276+
label: frequency
277+
? formatMessage(
278+
{
279+
id: `form.every.${frequency.timeUnit}`,
280+
},
281+
{ value: frequency.units }
282+
)
283+
: formatMessage({ id: "frequency.manual" }),
284+
}));
285+
}, [formatMessage, additionalFrequency]);
275286
};
276287

277288
export type { ConnectionFormValues, FormikConnectionFormValues };

0 commit comments

Comments
 (0)