From 0ceffd75f1227b65e1a712bc4b7cf544f0193582 Mon Sep 17 00:00:00 2001 From: Edmundo Ruiz Ghanem <168664+edmundito@users.noreply.github.com> Date: Thu, 22 Sep 2022 09:40:41 -0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=AA=9F=20=F0=9F=90=9B=20=F0=9F=A7=B9=20Fi?= =?UTF-8?q?x=20workspace=20editing=20issues=20in=20cloud,=20cleanup=20Clou?= =?UTF-8?q?dWorkspacesService=20(#16942)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add validation to WorkspaceSettingsView Use i18n string sin WorkspaceSettingsView buttons * Invalidate the workspace query when updating the workspace in cloud * Rename Cloud WorkspacesService to CloudWorkspacesServices to avoid confusion with WorkspaceService Update functions in CloudWorkspacesServices to include the word Cloud * useInvalidateWorkspaceQuery -> useInvalidateWorkspace * Remove useWorkspaceService import from CloudWorkspacesService * Update var names using CloudWorkspacesService * Rename useGetUsage to useGetCloudWorkspaceUsage * tsx -> ts * Cleanup mutateAsync usage around CloudWorkspacesService hooks * Remove reference to CloudWorkspacesServices in ConnectionFormService test --- .../Connection/ConnectionFormService.test.tsx | 2 +- .../src/packages/cloud/cloudRoutes.tsx | 2 +- ...sService.tsx => CloudWorkspacesService.ts} | 23 ++++++------ .../src/packages/cloud/views/DefaultView.tsx | 2 +- .../CreditsPage/components/CreditsUsage.tsx | 4 +-- .../components/RemainingCredits.tsx | 6 ++-- .../cloud/views/layout/MainView/MainView.tsx | 2 +- .../cloud/views/layout/SideBar/SideBar.tsx | 2 +- .../WorkspacePopout/WorkspacePopout.tsx | 4 +-- .../WorkspaceSettingsView.tsx | 36 ++++++++++++------- .../components/WorkspacesList.tsx | 10 +++--- .../services/workspaces/WorkspacesService.tsx | 9 +++++ 12 files changed, 59 insertions(+), 43 deletions(-) rename airbyte-webapp/src/packages/cloud/services/workspaces/{WorkspacesService.tsx => CloudWorkspacesService.ts} (83%) diff --git a/airbyte-webapp/src/hooks/services/Connection/ConnectionFormService.test.tsx b/airbyte-webapp/src/hooks/services/Connection/ConnectionFormService.test.tsx index 6201cd430016..e6f8abd6985c 100644 --- a/airbyte-webapp/src/hooks/services/Connection/ConnectionFormService.test.tsx +++ b/airbyte-webapp/src/hooks/services/Connection/ConnectionFormService.test.tsx @@ -17,7 +17,7 @@ import { useConnectionFormService, } from "./ConnectionFormService"; -["packages/cloud/services/workspaces/WorkspacesService", "services/workspaces/WorkspacesService"].forEach((s) => +["services/workspaces/WorkspacesService"].forEach((s) => jest.mock(s, () => ({ useCurrentWorkspaceId: () => mockWorkspace.workspaceId, useCurrentWorkspace: () => mockWorkspace, diff --git a/airbyte-webapp/src/packages/cloud/cloudRoutes.tsx b/airbyte-webapp/src/packages/cloud/cloudRoutes.tsx index 14a49bcda8bc..368fe28c4a29 100644 --- a/airbyte-webapp/src/packages/cloud/cloudRoutes.tsx +++ b/airbyte-webapp/src/packages/cloud/cloudRoutes.tsx @@ -27,7 +27,7 @@ import { CompleteOauthRequest } from "views/CompleteOauthRequest"; import { RoutePaths } from "../../pages/routePaths"; import { CreditStatus } from "./lib/domain/cloudWorkspaces/types"; import { LDExperimentServiceProvider } from "./services/thirdParty/launchdarkly"; -import { useGetCloudWorkspace } from "./services/workspaces/WorkspacesService"; +import { useGetCloudWorkspace } from "./services/workspaces/CloudWorkspacesService"; import { DefaultView } from "./views/DefaultView"; import { VerifyEmailAction } from "./views/FirebaseActionRoute"; import { CloudSettingsPage } from "./views/settings/CloudSettingsPage"; diff --git a/airbyte-webapp/src/packages/cloud/services/workspaces/WorkspacesService.tsx b/airbyte-webapp/src/packages/cloud/services/workspaces/CloudWorkspacesService.ts similarity index 83% rename from airbyte-webapp/src/packages/cloud/services/workspaces/WorkspacesService.tsx rename to airbyte-webapp/src/packages/cloud/services/workspaces/CloudWorkspacesService.ts index 77f11904a525..c35342bb3db2 100644 --- a/airbyte-webapp/src/packages/cloud/services/workspaces/WorkspacesService.tsx +++ b/airbyte-webapp/src/packages/cloud/services/workspaces/CloudWorkspacesService.ts @@ -5,12 +5,11 @@ import { CloudWorkspacesService } from "packages/cloud/lib/domain/cloudWorkspace import { CloudWorkspace, CloudWorkspaceUsage } from "packages/cloud/lib/domain/cloudWorkspaces/types"; import { useCurrentUser } from "packages/cloud/services/auth/AuthService"; import { useConfig } from "packages/cloud/services/config"; +import { useSuspenseQuery } from "services/connector/useSuspenseQuery"; import { SCOPE_USER } from "services/Scope"; import { useDefaultRequestMiddlewares } from "services/useDefaultRequestMiddlewares"; import { useInitService } from "services/useInitService"; -import { useSuspenseQuery } from "../../../../services/connector/useSuspenseQuery"; - export const workspaceKeys = { all: [SCOPE_USER, "cloud_workspaces"] as const, lists: () => [...workspaceKeys.all, "list"] as const, @@ -45,7 +44,7 @@ export function useListCloudWorkspacesAsync(): QueryObserverResult(workspaceKeys.lists(), () => service.listByUser(user.userId)); } -export function useCreateWorkspace() { +export function useCreateCloudWorkspace() { const service = useGetWorkspaceService(); const queryClient = useQueryClient(); const user = useCurrentUser(); @@ -54,10 +53,10 @@ export function useCreateWorkspace() { onSuccess: (result) => { queryClient.setQueryData(workspaceKeys.lists(), (old) => [...(old ?? []), result]); }, - }).mutateAsync; + }); } -export function useUpdateWorkspace() { +export function useUpdateCloudWorkspace() { const service = useGetWorkspaceService(); const queryClient = useQueryClient(); @@ -81,7 +80,7 @@ export function useUpdateWorkspace() { return [...list.slice(0, index), result, ...list.slice(index + 1)]; }); - queryClient.setQueryData([workspaceKeys.detail(result.workspaceId)], (old) => { + queryClient.setQueryData(workspaceKeys.detail(result.workspaceId), (old) => { return { ...old, ...result, @@ -92,7 +91,7 @@ export function useUpdateWorkspace() { ); } -export function useRemoveWorkspace() { +export function useRemoveCloudWorkspace() { const service = useGetWorkspaceService(); const queryClient = useQueryClient(); @@ -108,22 +107,20 @@ export function useRemoveWorkspace() { export function useGetCloudWorkspace(workspaceId: string): CloudWorkspace { const service = useGetWorkspaceService(); - return useSuspenseQuery([workspaceKeys.detail(workspaceId)], () => service.get(workspaceId)); + return useSuspenseQuery(workspaceKeys.detail(workspaceId), () => service.get(workspaceId)); } export function useInvalidateCloudWorkspace(workspaceId: string): () => Promise { const queryClient = useQueryClient(); return useCallback( - () => queryClient.invalidateQueries([workspaceKeys.detail(workspaceId)]), + () => queryClient.invalidateQueries(workspaceKeys.detail(workspaceId)), [queryClient, workspaceId] ); } -export function useGetUsage(workspaceId: string): CloudWorkspaceUsage { +export function useGetCloudWorkspaceUsage(workspaceId: string): CloudWorkspaceUsage { const service = useGetWorkspaceService(); - return useSuspenseQuery([workspaceKeys.usage(workspaceId)], () => service.getUsage(workspaceId)); + return useSuspenseQuery(workspaceKeys.usage(workspaceId), () => service.getUsage(workspaceId)); } - -export { useWorkspaceService } from "services/workspaces/WorkspacesService"; diff --git a/airbyte-webapp/src/packages/cloud/views/DefaultView.tsx b/airbyte-webapp/src/packages/cloud/views/DefaultView.tsx index 26714faadd4a..2df567ec51b5 100644 --- a/airbyte-webapp/src/packages/cloud/views/DefaultView.tsx +++ b/airbyte-webapp/src/packages/cloud/views/DefaultView.tsx @@ -2,7 +2,7 @@ import { Navigate } from "react-router-dom"; import { RoutePaths } from "../../../pages/routePaths"; import { CloudRoutes } from "../cloudRoutes"; -import { useListCloudWorkspaces } from "../services/workspaces/WorkspacesService"; +import { useListCloudWorkspaces } from "../services/workspaces/CloudWorkspacesService"; export const DefaultView: React.FC = () => { const workspaces = useListCloudWorkspaces(); diff --git a/airbyte-webapp/src/packages/cloud/views/credits/CreditsPage/components/CreditsUsage.tsx b/airbyte-webapp/src/packages/cloud/views/credits/CreditsPage/components/CreditsUsage.tsx index ed1ebc44925c..0f1d5ff2f20e 100644 --- a/airbyte-webapp/src/packages/cloud/views/credits/CreditsPage/components/CreditsUsage.tsx +++ b/airbyte-webapp/src/packages/cloud/views/credits/CreditsPage/components/CreditsUsage.tsx @@ -6,7 +6,7 @@ import BarChart from "components/BarChart"; import { Card } from "components/base/Card"; import { useCurrentWorkspace } from "hooks/services/useWorkspace"; -import { useGetUsage } from "packages/cloud/services/workspaces/WorkspacesService"; +import { useGetCloudWorkspaceUsage } from "packages/cloud/services/workspaces/CloudWorkspacesService"; import UsagePerConnectionTable from "./UsagePerConnectionTable"; @@ -35,7 +35,7 @@ const CreditsUsage: React.FC = () => { const { formatMessage, formatDate } = useIntl(); const { workspaceId } = useCurrentWorkspace(); - const data = useGetUsage(workspaceId); + const data = useGetCloudWorkspaceUsage(workspaceId); const chartData = useMemo( () => diff --git a/airbyte-webapp/src/packages/cloud/views/credits/CreditsPage/components/RemainingCredits.tsx b/airbyte-webapp/src/packages/cloud/views/credits/CreditsPage/components/RemainingCredits.tsx index b8fc8cdc9751..d8af4b013c33 100644 --- a/airbyte-webapp/src/packages/cloud/views/credits/CreditsPage/components/RemainingCredits.tsx +++ b/airbyte-webapp/src/packages/cloud/views/credits/CreditsPage/components/RemainingCredits.tsx @@ -15,7 +15,7 @@ import { useStripeCheckout } from "packages/cloud/services/stripe/StripeService" import { useGetCloudWorkspace, useInvalidateCloudWorkspace, -} from "packages/cloud/services/workspaces/WorkspacesService"; +} from "packages/cloud/services/workspaces/CloudWorkspacesService"; interface Props { selfServiceCheckoutEnabled: boolean; @@ -62,7 +62,7 @@ const RemainingCredits: React.FC = ({ selfServiceCheckoutEnabled }) => { const currentWorkspace = useCurrentWorkspace(); const cloudWorkspace = useGetCloudWorkspace(currentWorkspace.workspaceId); const [searchParams, setSearchParams] = useSearchParams(); - const invalidateWorkspace = useInvalidateCloudWorkspace(currentWorkspace.workspaceId); + const invalidateCloudWorkspace = useInvalidateCloudWorkspace(currentWorkspace.workspaceId); const { isLoading, mutateAsync: createCheckout } = useStripeCheckout(); const analytics = useAnalyticsService(); const [isWaitingForCredits, setIsWaitingForCredits] = useState(false); @@ -79,7 +79,7 @@ const RemainingCredits: React.FC = ({ selfServiceCheckoutEnabled }) => { if (!hasRecentCreditIncrease(cloudWorkspace)) { setIsWaitingForCredits(true); retryIntervalId.current = window.setInterval(() => { - invalidateWorkspace(); + invalidateCloudWorkspace(); }, 3000); } } diff --git a/airbyte-webapp/src/packages/cloud/views/layout/MainView/MainView.tsx b/airbyte-webapp/src/packages/cloud/views/layout/MainView/MainView.tsx index 9217d92ee9ca..a4c3f2b666ca 100644 --- a/airbyte-webapp/src/packages/cloud/views/layout/MainView/MainView.tsx +++ b/airbyte-webapp/src/packages/cloud/views/layout/MainView/MainView.tsx @@ -8,7 +8,7 @@ import { AlertBanner } from "components/base/Banner/AlertBanner"; import { CloudRoutes } from "packages/cloud/cloudRoutes"; import { CreditStatus } from "packages/cloud/lib/domain/cloudWorkspaces/types"; -import { useGetCloudWorkspace } from "packages/cloud/services/workspaces/WorkspacesService"; +import { useGetCloudWorkspace } from "packages/cloud/services/workspaces/CloudWorkspacesService"; import SideBar from "packages/cloud/views/layout/SideBar"; import { useCurrentWorkspace } from "services/workspaces/WorkspacesService"; import { ResourceNotFoundErrorBoundary } from "views/common/ResorceNotFoundErrorBoundary"; diff --git a/airbyte-webapp/src/packages/cloud/views/layout/SideBar/SideBar.tsx b/airbyte-webapp/src/packages/cloud/views/layout/SideBar/SideBar.tsx index 1a20d46e6041..887bd0438fbb 100644 --- a/airbyte-webapp/src/packages/cloud/views/layout/SideBar/SideBar.tsx +++ b/airbyte-webapp/src/packages/cloud/views/layout/SideBar/SideBar.tsx @@ -12,7 +12,7 @@ import { FeatureItem, IfFeatureEnabled } from "hooks/services/Feature"; import { useCurrentWorkspace } from "hooks/services/useWorkspace"; import { CloudRoutes } from "packages/cloud/cloudRoutes"; import { useIntercom } from "packages/cloud/services/thirdParty/intercom"; -import { useGetCloudWorkspace } from "packages/cloud/services/workspaces/WorkspacesService"; +import { useGetCloudWorkspace } from "packages/cloud/services/workspaces/CloudWorkspacesService"; import { WorkspacePopout } from "packages/cloud/views/workspaces/WorkspacePopout"; import ChatIcon from "views/layout/SideBar/components/ChatIcon"; import ConnectionsIcon from "views/layout/SideBar/components/ConnectionsIcon"; diff --git a/airbyte-webapp/src/packages/cloud/views/workspaces/WorkspacePopout/WorkspacePopout.tsx b/airbyte-webapp/src/packages/cloud/views/workspaces/WorkspacePopout/WorkspacePopout.tsx index ab93946b949f..87834316cc64 100644 --- a/airbyte-webapp/src/packages/cloud/views/workspaces/WorkspacePopout/WorkspacePopout.tsx +++ b/airbyte-webapp/src/packages/cloud/views/workspaces/WorkspacePopout/WorkspacePopout.tsx @@ -6,8 +6,8 @@ import styled from "styled-components"; import { Popout } from "components"; import { IDataItem } from "components/base/DropDown/components/Option"; -import { useWorkspaceService, useListCloudWorkspacesAsync } from "packages/cloud/services/workspaces/WorkspacesService"; -import { useCurrentWorkspace } from "services/workspaces/WorkspacesService"; +import { useListCloudWorkspacesAsync } from "packages/cloud/services/workspaces/CloudWorkspacesService"; +import { useCurrentWorkspace, useWorkspaceService } from "services/workspaces/WorkspacesService"; import ExitIcon from "./components/ExitIcon"; diff --git a/airbyte-webapp/src/packages/cloud/views/workspaces/WorkspaceSettingsView/WorkspaceSettingsView.tsx b/airbyte-webapp/src/packages/cloud/views/workspaces/WorkspaceSettingsView/WorkspaceSettingsView.tsx index 7f804a66e322..619a976c576f 100644 --- a/airbyte-webapp/src/packages/cloud/views/workspaces/WorkspaceSettingsView/WorkspaceSettingsView.tsx +++ b/airbyte-webapp/src/packages/cloud/views/workspaces/WorkspaceSettingsView/WorkspaceSettingsView.tsx @@ -2,6 +2,7 @@ import classNames from "classnames"; import { Field, FieldProps, Form, Formik } from "formik"; import React from "react"; import { FormattedMessage, useIntl } from "react-intl"; +import * as yup from "yup"; import { Button, Label, LabeledInput, LabeledSwitch, LoadingButton } from "components"; import { InfoTooltip } from "components/base/Tooltip"; @@ -10,11 +11,11 @@ import { useTrackPage, PageTrackingCodes } from "hooks/services/Analytics"; import { useAdvancedModeSetting } from "hooks/services/useAdvancedModeSetting"; import { useCurrentWorkspace } from "hooks/services/useWorkspace"; import { - useRemoveWorkspace, - useUpdateWorkspace, - useWorkspaceService, -} from "packages/cloud/services/workspaces/WorkspacesService"; + useRemoveCloudWorkspace, + useUpdateCloudWorkspace, +} from "packages/cloud/services/workspaces/CloudWorkspacesService"; import { Content, SettingsCard } from "pages/SettingsPage/pages/SettingsComponents"; +import { useInvalidateWorkspace, useWorkspaceService } from "services/workspaces/WorkspacesService"; import styles from "./WorkspaceSettingsView.module.scss"; @@ -27,13 +28,18 @@ const AdvancedModeSwitchLabel = () => ( ); +const ValidationSchema = yup.object().shape({ + name: yup.string().required("form.empty.error"), +}); + export const WorkspaceSettingsView: React.FC = () => { const { formatMessage } = useIntl(); useTrackPage(PageTrackingCodes.SETTINGS_WORKSPACE); const { exitWorkspace } = useWorkspaceService(); const workspace = useCurrentWorkspace(); - const removeWorkspace = useRemoveWorkspace(); - const updateWorkspace = useUpdateWorkspace(); + const { mutateAsync: removeCloudWorkspace, isLoading: isRemovingCloudWorkspace } = useRemoveCloudWorkspace(); + const { mutateAsync: updateCloudWorkspace } = useUpdateCloudWorkspace(); + const invalidateWorkspace = useInvalidateWorkspace(workspace.workspaceId); const [isAdvancedMode, setAdvancedMode] = useAdvancedModeSetting(); return ( @@ -54,12 +60,16 @@ export const WorkspaceSettingsView: React.FC = () => { advancedMode: isAdvancedMode, }} onSubmit={async (payload) => { + const { workspaceId } = workspace; setAdvancedMode(payload.advancedMode); - return updateWorkspace.mutateAsync({ - workspaceId: workspace.workspaceId, + await updateCloudWorkspace({ + workspaceId, name: payload.name, }); + await invalidateWorkspace(); }} + enableReinitialize + validationSchema={ValidationSchema} > {({ dirty, isSubmitting, resetForm, isValid, setFieldValue }) => (
@@ -93,10 +103,10 @@ export const WorkspaceSettingsView: React.FC = () => {
- - save changes + +
@@ -109,9 +119,9 @@ export const WorkspaceSettingsView: React.FC = () => {
removeWorkspace.mutateAsync(workspace.workspaceId)} + onClick={() => removeCloudWorkspace(workspace.workspaceId)} > diff --git a/airbyte-webapp/src/packages/cloud/views/workspaces/WorkspacesPage/components/WorkspacesList.tsx b/airbyte-webapp/src/packages/cloud/views/workspaces/WorkspacesPage/components/WorkspacesList.tsx index d11a5664786d..a07ccc011168 100644 --- a/airbyte-webapp/src/packages/cloud/views/workspaces/WorkspacesPage/components/WorkspacesList.tsx +++ b/airbyte-webapp/src/packages/cloud/views/workspaces/WorkspacesPage/components/WorkspacesList.tsx @@ -2,10 +2,10 @@ import React from "react"; import styled from "styled-components"; import { - useCreateWorkspace, + useCreateCloudWorkspace, useListCloudWorkspaces, - useWorkspaceService, -} from "packages/cloud/services/workspaces/WorkspacesService"; +} from "packages/cloud/services/workspaces/CloudWorkspacesService"; +import { useWorkspaceService } from "services/workspaces/WorkspacesService"; import WorkspaceItem from "./WorkspaceItem"; import WorkspacesControl from "./WorkspacesControl"; @@ -20,7 +20,7 @@ const Content = styled.div` const WorkspacesList: React.FC = () => { const workspaces = useListCloudWorkspaces(); const { selectWorkspace } = useWorkspaceService(); - const createWorkspace = useCreateWorkspace(); + const { mutateAsync: createCloudWorkspace } = useCreateCloudWorkspace(); return ( @@ -29,7 +29,7 @@ const WorkspacesList: React.FC = () => { {workspace.name} ))} - + ); }; diff --git a/airbyte-webapp/src/services/workspaces/WorkspacesService.tsx b/airbyte-webapp/src/services/workspaces/WorkspacesService.tsx index ab448c9d1ec3..ebde26c29202 100644 --- a/airbyte-webapp/src/services/workspaces/WorkspacesService.tsx +++ b/airbyte-webapp/src/services/workspaces/WorkspacesService.tsx @@ -127,3 +127,12 @@ export const useUpdateWorkspace = () => { }, }); }; + +export const useInvalidateWorkspace = (workspaceId: string) => { + const queryClient = useQueryClient(); + + return useCallback( + () => queryClient.invalidateQueries(workspaceKeys.detail(workspaceId)), + [queryClient, workspaceId] + ); +};