diff --git a/airbyte-webapp/src/App.tsx b/airbyte-webapp/src/App.tsx index b1571d79984e3..6d59fe351f8c1 100644 --- a/airbyte-webapp/src/App.tsx +++ b/airbyte-webapp/src/App.tsx @@ -12,11 +12,8 @@ import { Routing } from "./pages/routes"; import LoadingPage from "./components/LoadingPage"; import ApiErrorBoundary from "./components/ApiErrorBoundary"; import NotificationService from "hooks/services/Notification"; -import { AnalyticsInitializer } from "views/common/AnalyticsInitializer"; -import { - useCurrentWorkspace, - usePickFirstWorkspace, -} from "hooks/services/useWorkspace"; +import { AnalyticsProvider } from "views/common/AnalyticsProvider"; +import { usePickFirstWorkspace } from "hooks/services/useWorkspace"; import { Feature, FeatureItem, FeatureService } from "hooks/services/Feature"; import { OnboardingServiceProvider } from "hooks/services/Onboarding"; import { ServicesProvider } from "core/servicesProvider"; @@ -29,12 +26,6 @@ import { ValueProvider, } from "./config"; -function useCustomerIdProvider() { - const workspace = useCurrentWorkspace(); - - return workspace.customerId; -} - const Features: Feature[] = [ { id: FeatureItem.AllowUploadCustomImage, @@ -75,7 +66,6 @@ const configProviders: ValueProvider = [ const services = { currentWorkspaceProvider: usePickFirstWorkspace, - useCustomerIdProvider: useCustomerIdProvider, }; const AppServices: React.FC = ({ children }) => ( @@ -100,19 +90,19 @@ const App: React.FC = () => { defaultConfig={defaultConfig} providers={configProviders} > - - - - - + + + + + - - - - - + + + + + diff --git a/airbyte-webapp/src/components/CreateConnectionContent/CreateConnectionContent.tsx b/airbyte-webapp/src/components/CreateConnectionContent/CreateConnectionContent.tsx index 531f96cd230dc..149c053e2021d 100644 --- a/airbyte-webapp/src/components/CreateConnectionContent/CreateConnectionContent.tsx +++ b/airbyte-webapp/src/components/CreateConnectionContent/CreateConnectionContent.tsx @@ -19,7 +19,7 @@ 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 { useAnalytics } from "hooks/useAnalytics"; +import { useAnalyticsService } from "hooks/services/Analytics/useAnalyticsService"; const SkipButton = styled.div` margin-top: 6px; @@ -51,7 +51,7 @@ const CreateConnectionContent: React.FC = ({ noTitles, }) => { const { createConnection } = useConnection(); - const analyticsService = useAnalytics(); + const analyticsService = useAnalyticsService(); const sourceDefinition = useResource(SourceDefinitionResource.detailShape(), { sourceDefinitionId: source.sourceDefinitionId, diff --git a/airbyte-webapp/src/components/EntityTable/hooks.tsx b/airbyte-webapp/src/components/EntityTable/hooks.tsx index 4feab8e90386a..9f17e5a13a97a 100644 --- a/airbyte-webapp/src/components/EntityTable/hooks.tsx +++ b/airbyte-webapp/src/components/EntityTable/hooks.tsx @@ -4,7 +4,7 @@ import FrequencyConfig from "config/FrequencyConfig.json"; import ConnectionResource, { Connection } from "core/resources/Connection"; import useConnection from "hooks/services/useConnectionHook"; import { Status } from "./types"; -import { useAnalytics } from "hooks/useAnalytics"; +import { useAnalyticsService } from "hooks/services/Analytics/useAnalyticsService"; const useSyncActions = (): { changeStatus: (connection: Connection) => Promise; @@ -12,7 +12,7 @@ const useSyncActions = (): { } => { const { updateConnection } = useConnection(); const SyncConnection = useFetcher(ConnectionResource.syncShape()); - const analyticsService = useAnalytics(); + const analyticsService = useAnalyticsService(); const changeStatus = async (connection: Connection) => { await updateConnection({ diff --git a/airbyte-webapp/src/core/analytics/AnalyticsService.ts b/airbyte-webapp/src/core/analytics/AnalyticsService.ts index 1960f478ca4c9..c67ed0da115f6 100644 --- a/airbyte-webapp/src/core/analytics/AnalyticsService.ts +++ b/airbyte-webapp/src/core/analytics/AnalyticsService.ts @@ -1,7 +1,10 @@ import { SegmentAnalytics } from "./types"; export class AnalyticsService { - constructor(private userId?: string, private version?: string) {} + constructor( + private context: Record, + private version?: string + ) {} private getSegmentAnalytics = (): SegmentAnalytics | undefined => window.analytics; @@ -14,8 +17,8 @@ export class AnalyticsService { track = (name: string, properties: Record): void => this.getSegmentAnalytics()?.track?.(name, { - user_id: this.userId, ...properties, + ...this.context, airbyte_version: this.version, environment: this.version === "dev" ? "dev" : "prod", }); diff --git a/airbyte-webapp/src/hooks/services/Analytics/TrackPageAnalytics.tsx b/airbyte-webapp/src/hooks/services/Analytics/TrackPageAnalytics.tsx new file mode 100644 index 0000000000000..4d13737175d81 --- /dev/null +++ b/airbyte-webapp/src/hooks/services/Analytics/TrackPageAnalytics.tsx @@ -0,0 +1,19 @@ +import React, { useEffect } from "react"; + +import useRouter from "hooks/useRouter"; + +import { useAnalyticsService } from "./useAnalyticsService"; +import { getPageName } from "./pageNameUtils"; + +export const TrackPageAnalytics: React.FC = () => { + const { pathname } = useRouter(); + const analyticsService = useAnalyticsService(); + useEffect(() => { + const pageName = getPageName(pathname); + if (pageName) { + analyticsService.page(pageName); + } + }, [analyticsService, pathname]); + + return null; +}; diff --git a/airbyte-webapp/src/hooks/services/Analytics/index.tsx b/airbyte-webapp/src/hooks/services/Analytics/index.tsx new file mode 100644 index 0000000000000..22f927a305370 --- /dev/null +++ b/airbyte-webapp/src/hooks/services/Analytics/index.tsx @@ -0,0 +1,2 @@ +export * from "./TrackPageAnalytics"; +export * from "./useAnalyticsService"; diff --git a/airbyte-webapp/src/pages/withPageAnalytics.tsx b/airbyte-webapp/src/hooks/services/Analytics/pageNameUtils.tsx similarity index 76% rename from airbyte-webapp/src/pages/withPageAnalytics.tsx rename to airbyte-webapp/src/hooks/services/Analytics/pageNameUtils.tsx index bc9fc928ecf56..cb8934d7d2697 100644 --- a/airbyte-webapp/src/pages/withPageAnalytics.tsx +++ b/airbyte-webapp/src/hooks/services/Analytics/pageNameUtils.tsx @@ -1,10 +1,6 @@ -import React, { useEffect } from "react"; +import { Routes } from "pages/routes"; -import useRouter from "hooks/useRouter"; -import { useAnalytics } from "hooks/useAnalytics"; -import { Routes } from "./routes"; - -const getPageName = (pathname: string) => { +const getPageName = (pathname: string): string => { const itemSourcePageRegex = new RegExp(`${Routes.Source}/.*`); const itemDestinationPageRegex = new RegExp(`${Routes.Destination}/.*`); const itemSourceToDestinationPageRegex = new RegExp( @@ -60,15 +56,4 @@ const getPageName = (pathname: string) => { return ""; }; -export const WithPageAnalytics: React.FC = () => { - const { pathname } = useRouter(); - const analyticsService = useAnalytics(); - useEffect(() => { - const pageName = getPageName(pathname); - if (pageName) { - analyticsService.page(pageName); - } - }, [analyticsService, pathname]); - - return null; -}; +export { getPageName }; diff --git a/airbyte-webapp/src/hooks/services/Analytics/useAnalyticsService.tsx b/airbyte-webapp/src/hooks/services/Analytics/useAnalyticsService.tsx new file mode 100644 index 0000000000000..b3a377f322676 --- /dev/null +++ b/airbyte-webapp/src/hooks/services/Analytics/useAnalyticsService.tsx @@ -0,0 +1,101 @@ +import React, { useContext, useEffect, useMemo } from "react"; +import { useMap } from "react-use"; + +import { AnalyticsService } from "core/analytics/AnalyticsService"; + +type AnalyticsContext = Record; + +export type AnalyticsServiceProviderValue = { + analyticsContext: AnalyticsContext; + setContext: (ctx: AnalyticsContext) => void; + addContextProps: (props: AnalyticsContext) => void; + removeContextProps: (props: string[]) => void; + service: AnalyticsService; +}; + +const analyticsServiceContext = React.createContext( + null +); + +function AnalyticsServiceProvider({ + children, + version, + initialContext = {}, +}: { + children: React.ReactNode; + version?: string; + initialContext?: AnalyticsContext; +}) { + const [analyticsContext, { set, setAll, remove }] = useMap(initialContext); + + const analyticsService: AnalyticsService = useMemo( + () => new AnalyticsService(analyticsContext, version), + [version, analyticsContext] + ); + + const handleAddContextProps = (props: AnalyticsContext) => { + Object.entries(props).forEach((value) => set(...value)); + }; + + const handleRemoveContextProps = (props: string[]) => props.forEach(remove); + + return ( + + {children} + + ); +} + +export const useAnalyticsService = (): AnalyticsService => { + const analyticsService = useAnalytics(); + + return analyticsService.service; +}; + +export const useAnalytics = (): AnalyticsServiceProviderValue => { + const analyticsContext = useContext(analyticsServiceContext); + + if (!analyticsContext) { + throw new Error( + "analyticsContext must be used within a AnalyticsServiceProvider." + ); + } + + return analyticsContext; +}; + +export const useAnalyticsIdentifyUser = (userId?: string): void => { + const analyticsService = useAnalyticsService(); + + useEffect(() => { + if (userId) { + analyticsService.identify(userId); + } + }, [userId]); +}; + +export const useAnalyticsRegisterValues = ( + props?: AnalyticsContext | null +): void => { + const { addContextProps, removeContextProps } = useAnalytics(); + + useEffect(() => { + if (props) { + addContextProps(props); + + return () => removeContextProps(Object.keys(props)); + } + + return; + }, [props]); +}; + +export default React.memo(AnalyticsServiceProvider); diff --git a/airbyte-webapp/src/hooks/services/Notification/index.tsx b/airbyte-webapp/src/hooks/services/Notification/index.tsx index bb7507c061adf..87cec15fbe3e2 100644 --- a/airbyte-webapp/src/hooks/services/Notification/index.tsx +++ b/airbyte-webapp/src/hooks/services/Notification/index.tsx @@ -1,4 +1,6 @@ -import NotificationService from "./NotificationService"; +import NotificationService, { + useNotificationService, +} from "./NotificationService"; export default NotificationService; -export { NotificationService }; +export { NotificationService, useNotificationService }; diff --git a/airbyte-webapp/src/hooks/services/useConnectionHook.tsx b/airbyte-webapp/src/hooks/services/useConnectionHook.tsx index b8a7870aaa0cb..f7e6bc68f1695 100644 --- a/airbyte-webapp/src/hooks/services/useConnectionHook.tsx +++ b/airbyte-webapp/src/hooks/services/useConnectionHook.tsx @@ -20,7 +20,7 @@ import { Routes } from "pages/routes"; import { Destination } from "core/resources/Destination"; import useWorkspace from "./useWorkspace"; import { Operation } from "core/domain/connection/operation"; -import { useAnalytics } from "hooks/useAnalytics"; +import { useAnalyticsService } from "hooks/services/Analytics/useAnalyticsService"; import useRouter from "hooks/useRouter"; import { useGetService } from "core/servicesProvider"; import { RequestMiddleware } from "core/request/RequestMiddleware"; @@ -108,7 +108,7 @@ const useConnection = (): { } => { const { push } = useRouter(); const { workspace } = useWorkspace(); - const analyticsService = useAnalytics(); + const analyticsService = useAnalyticsService(); const createConnectionResource = useFetcher(ConnectionResource.createShape()); const updateConnectionResource = useFetcher(ConnectionResource.updateShape()); diff --git a/airbyte-webapp/src/hooks/services/useDestinationHook.tsx b/airbyte-webapp/src/hooks/services/useDestinationHook.tsx index 2143502621745..0836e5bd24b92 100644 --- a/airbyte-webapp/src/hooks/services/useDestinationHook.tsx +++ b/airbyte-webapp/src/hooks/services/useDestinationHook.tsx @@ -10,7 +10,7 @@ import DestinationDefinitionSpecificationResource from "core/resources/Destinati import SchedulerResource, { Scheduler } from "core/resources/Scheduler"; import { ConnectionConfiguration } from "core/domain/connection"; import useWorkspace from "./useWorkspace"; -import { useAnalytics } from "hooks/useAnalytics"; +import { useAnalyticsService } from "hooks/services/Analytics/useAnalyticsService"; import { DestinationDefinitionSpecification } from "core/domain/connector"; type ValuesProps = { @@ -102,7 +102,7 @@ type DestinationService = { const useDestination = (): DestinationService => { const { push } = useRouter(); const { workspace } = useWorkspace(); - const analyticsService = useAnalytics(); + const analyticsService = useAnalyticsService(); const createDestinationsImplementation = useFetcher( DestinationResource.createShape() ); diff --git a/airbyte-webapp/src/hooks/services/useRequestConnector.tsx b/airbyte-webapp/src/hooks/services/useRequestConnector.tsx index b579c5e59065c..f7e6f3412be06 100644 --- a/airbyte-webapp/src/hooks/services/useRequestConnector.tsx +++ b/airbyte-webapp/src/hooks/services/useRequestConnector.tsx @@ -1,4 +1,4 @@ -import { useAnalytics } from "hooks/useAnalytics"; +import { useAnalyticsService } from "hooks/services/Analytics/useAnalyticsService"; type Values = { connectorType: string; @@ -10,7 +10,7 @@ type Values = { const useRequestConnector = (): { requestConnector: (conn: Values) => void; } => { - const analyticsService = useAnalytics(); + const analyticsService = useAnalyticsService(); const requestConnector = (values: Values) => { analyticsService.track("Request a Connector", { diff --git a/airbyte-webapp/src/hooks/services/useSourceHook.tsx b/airbyte-webapp/src/hooks/services/useSourceHook.tsx index 402e44a435404..fbb920eb1a089 100644 --- a/airbyte-webapp/src/hooks/services/useSourceHook.tsx +++ b/airbyte-webapp/src/hooks/services/useSourceHook.tsx @@ -11,7 +11,7 @@ import { ConnectionConfiguration } from "core/domain/connection"; import useWorkspace from "./useWorkspace"; import useRouter from "hooks/useRouter"; -import { useAnalytics } from "hooks/useAnalytics"; +import { useAnalyticsService } from "hooks/services/Analytics/useAnalyticsService"; import { SourceDefinitionSpecification } from "core/domain/connector"; type ValuesProps = { @@ -73,7 +73,7 @@ const useSource = (): SourceService => { const { push } = useRouter(); const { workspace } = useWorkspace(); const createSourcesImplementation = useFetcher(SourceResource.createShape()); - const analyticsService = useAnalytics(); + const analyticsService = useAnalyticsService(); const sourceCheckConnectionShape = useFetcher( SchedulerResource.sourceCheckConnectionShape() diff --git a/airbyte-webapp/src/hooks/services/useWorkspace.tsx b/airbyte-webapp/src/hooks/services/useWorkspace.tsx index 1f1ca3ea33e98..d1eea9077d0d0 100644 --- a/airbyte-webapp/src/hooks/services/useWorkspace.tsx +++ b/airbyte-webapp/src/hooks/services/useWorkspace.tsx @@ -5,7 +5,7 @@ import NotificationsResource, { Notifications, } from "core/resources/Notifications"; import { useGetService } from "core/servicesProvider"; -import { useAnalytics } from "../useAnalytics"; +import { useAnalyticsService } from "./Analytics/useAnalyticsService"; import { Source } from "core/resources/Source"; import { Destination } from "core/resources/Destination"; @@ -60,7 +60,7 @@ const useWorkspace = (): { const tryWebhookUrl = useFetcher(NotificationsResource.tryShape()); const workspace = useCurrentWorkspace(); - const analyticsService = useAnalytics(); + const analyticsService = useAnalyticsService(); const finishOnboarding = async (skipStep?: string) => { if (skipStep) { diff --git a/airbyte-webapp/src/hooks/useAnalytics.tsx b/airbyte-webapp/src/hooks/useAnalytics.tsx deleted file mode 100644 index ff266e2116431..0000000000000 --- a/airbyte-webapp/src/hooks/useAnalytics.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import React, { useContext, useMemo } from "react"; -import { AnalyticsService } from "core/analytics/AnalyticsService"; - -const analyticsServiceContext = React.createContext( - null -); - -function AnalyticsServiceProvider({ - children, - userId, - version, -}: { - children: React.ReactNode; - version?: string; - userId?: string; -}) { - const analyticsService: AnalyticsService = useMemo( - () => new AnalyticsService(userId, version), - [version, userId] - ); - return ( - - {children} - - ); -} - -export const useAnalytics = (): AnalyticsService => { - const analyticsService = useContext(analyticsServiceContext); - - if (!analyticsService) { - throw new Error( - "analyticsService must be used within a AnalyticsServiceProvider." - ); - } - - return analyticsService; -}; - -export default React.memo(AnalyticsServiceProvider); diff --git a/airbyte-webapp/src/packages/cloud/App.tsx b/airbyte-webapp/src/packages/cloud/App.tsx index 93439370d9b5f..dc59bf6fd74e2 100644 --- a/airbyte-webapp/src/packages/cloud/App.tsx +++ b/airbyte-webapp/src/packages/cloud/App.tsx @@ -13,11 +13,11 @@ import { Routing } from "packages/cloud/routes"; import LoadingPage from "components/LoadingPage"; import ApiErrorBoundary from "components/ApiErrorBoundary"; import NotificationServiceProvider from "hooks/services/Notification"; -import { AnalyticsInitializer } from "views/common/AnalyticsInitializer"; +import { AnalyticsProvider } from "views/common/AnalyticsProvider"; import { Feature, FeatureItem, FeatureService } from "hooks/services/Feature"; import { AuthenticationProvider } from "packages/cloud/services/auth/AuthService"; import { AppServicesProvider } from "./services/AppServicesProvider"; -import { IntercomProvider } from "./services/IntercomProvider"; +import { IntercomProvider } from "./services/thirdParty/intercom/IntercomProvider"; import { ConfigProvider } from "./services/ConfigProvider"; const messages = Object.assign({}, en, cloudLocales); @@ -57,21 +57,21 @@ const App: React.FC = () => { }> - - - - - - - + + + + + + + - - - - - - - + + + + + + + diff --git a/airbyte-webapp/src/packages/cloud/routes.tsx b/airbyte-webapp/src/packages/cloud/routes.tsx index b55135afe2d5b..213bee6b50d18 100644 --- a/airbyte-webapp/src/packages/cloud/routes.tsx +++ b/airbyte-webapp/src/packages/cloud/routes.tsx @@ -5,19 +5,10 @@ import { Route, Switch, } from "react-router-dom"; -import { FormattedMessage } from "react-intl"; -import { useAsync } from "react-use"; import SourcesPage from "pages/SourcesPage"; import DestinationPage from "pages/DestinationPage"; -import { - DestinationsPage as SettingsDestinationPage, - SourcesPage as SettingsSourcesPage, -} from "pages/SettingsPage/pages/ConnectorsPage"; import ConnectionPage from "pages/ConnectionPage"; -import SettingsPage from "pages/SettingsPage"; -import ConfigurationsPage from "pages/SettingsPage/pages/ConfigurationsPage"; -import NotificationPage from "pages/SettingsPage/pages/NotificationPage"; import LoadingPage from "components/LoadingPage"; import MainView from "packages/cloud/views/layout/MainView"; @@ -25,28 +16,28 @@ import { WorkspacesPage } from "packages/cloud/views/workspaces"; import { useApiHealthPoll } from "hooks/services/Health"; import { Auth } from "packages/cloud/views/auth"; import { useAuthService } from "packages/cloud/services/auth/AuthService"; -import { useIntercom } from "packages/cloud/services/useIntercom"; -import useConnector from "hooks/services/useConnector"; +import { useIntercom } from "packages/cloud/services/thirdParty/intercom/useIntercom"; import { useGetWorkspace, useWorkspaceService, WorkspaceServiceProvider, } from "packages/cloud/services/workspaces/WorkspacesService"; -import { PageConfig } from "pages/SettingsPage/SettingsPage"; -import { WorkspaceSettingsView } from "./views/workspaces/WorkspaceSettingsView"; -import { UsersSettingsView } from "packages/cloud/views/users/UsersSettingsView/UsersSettingsView"; -import { AccountSettingsView } from "packages/cloud/views/users/AccountSettingsView/AccountSettingsView"; import OnboardingPage from "pages/OnboardingPage"; import { CreditsPage } from "packages/cloud/views/credits"; import { ConfirmEmailPage } from "./views/auth/ConfirmEmailPage"; -import useRouter from "hooks/useRouter"; -import { WithPageAnalytics } from "pages/withPageAnalytics"; -import useWorkspace from "../../hooks/services/useWorkspace"; -import { CompleteOauthRequest } from "../../pages/CompleteOauthRequest"; +import { TrackPageAnalytics } from "hooks/services/Analytics/TrackPageAnalytics"; +import useWorkspace from "hooks/services/useWorkspace"; +import { CompleteOauthRequest } from "views/CompleteOauthRequest"; import { OnboardingServiceProvider } from "hooks/services/Onboarding"; import { useConfig } from "./services/config"; -import useFullStory from "./services/useFullStory"; +import useFullStory from "./services/thirdParty/fullstory/useFullStory"; +import { + useAnalyticsIdentifyUser, + useAnalyticsRegisterValues, +} from "hooks/services/Analytics/useAnalyticsService"; +import { CloudSettingsPage } from "./views/CloudSettingsPage"; +import { VerifyEmailAction } from "./views/FirebaseActionRoute"; export enum Routes { Preferences = "/preferences", @@ -84,75 +75,24 @@ export enum Routes { FirebaseAction = "/verify-email", } -export enum FirebaseActionMode { - VERIFY_EMAIL = "verifyEmail", - RESET_PASSWORD = "resetPassword", -} - const MainRoutes: React.FC<{ currentWorkspaceId: string }> = ({ currentWorkspaceId, }) => { useGetWorkspace(currentWorkspaceId); - const { countNewSourceVersion, countNewDestinationVersion } = useConnector(); const { workspace } = useWorkspace(); - const mainRedirect = workspace.displaySetupWizard - ? Routes.Onboarding - : Routes.Connections; - const pageConfig = useMemo( + const analyticsContext = useMemo( () => ({ - menuConfig: [ - { - category: , - routes: [ - { - path: `${Routes.Settings}${Routes.Account}`, - name: , - component: AccountSettingsView, - }, - ], - }, - { - category: , - routes: [ - { - path: `${Routes.Settings}${Routes.Workspace}`, - name: , - component: WorkspaceSettingsView, - }, - { - path: `${Routes.Settings}${Routes.Source}`, - name: , - indicatorCount: countNewSourceVersion, - component: SettingsSourcesPage, - }, - { - path: `${Routes.Settings}${Routes.Destination}`, - name: , - indicatorCount: countNewDestinationVersion, - component: SettingsDestinationPage, - }, - { - path: `${Routes.Settings}${Routes.Configuration}`, - name: , - component: ConfigurationsPage, - }, - { - path: `${Routes.Settings}${Routes.AccessManagement}`, - name: , - component: UsersSettingsView, - }, - { - path: `${Routes.Settings}${Routes.Notifications}`, - name: , - component: NotificationPage, - }, - ], - }, - ], + workspaceId: workspace.workspaceId, + customerId: workspace.customerId, }), - [countNewSourceVersion, countNewDestinationVersion] + [workspace] ); + useAnalyticsRegisterValues(analyticsContext); + + const mainRedirect = workspace.displaySetupWizard + ? Routes.Onboarding + : Routes.Connections; return ( @@ -166,7 +106,9 @@ const MainRoutes: React.FC<{ currentWorkspaceId: string }> = ({ - + + + @@ -216,23 +158,26 @@ const MainViewRoutes = () => { ); }; -const FirebaseActionRoute: React.FC = () => { - const { query } = useRouter<{ oobCode: string }>(); - const { verifyEmail } = useAuthService(); - - useAsync(async () => await verifyEmail(query.oobCode), []); - - return ; -}; - export const Routing: React.FC = () => { const { user, inited, emailVerified } = useAuthService(); const config = useConfig(); useFullStory(config.fullstory, config.fullstory.enabled); + const analyticsContext = useMemo( + () => + user + ? { + cloud_user_id: user.userId, + } + : null, + [user] + ); + useAnalyticsRegisterValues(analyticsContext); + useAnalyticsIdentifyUser(user?.userId); + return ( - + }> {inited ? ( <> @@ -244,7 +189,7 @@ export const Routing: React.FC = () => { {user && !emailVerified && ( - + diff --git a/airbyte-webapp/src/packages/cloud/services/AppServicesProvider.tsx b/airbyte-webapp/src/packages/cloud/services/AppServicesProvider.tsx index c21d6e1a734bb..9574921636fbe 100644 --- a/airbyte-webapp/src/packages/cloud/services/AppServicesProvider.tsx +++ b/airbyte-webapp/src/packages/cloud/services/AppServicesProvider.tsx @@ -12,7 +12,6 @@ import { useApiServices } from "core/defaultServices"; import { FirebaseSdkProvider } from "./FirebaseSdkProvider"; import { useWorkspaceService } from "./workspaces/WorkspacesService"; -import { useAuthService } from "./auth/AuthService"; import WorkspaceResource, { Workspace } from "core/resources/Workspace"; import { RequestAuthMiddleware } from "packages/cloud/lib/auth/RequestAuthMiddleware"; import { useConfig } from "./config"; @@ -20,12 +19,7 @@ import { UserService } from "packages/cloud/lib/domain/users"; import { RequestMiddleware } from "core/request/RequestMiddleware"; import { LoadingPage } from "components"; -export const useCustomerIdProvider = (): string => { - const { user } = useAuthService(); - return user?.userId ?? ""; -}; - -export const useCurrentWorkspaceProvider = (): Workspace => { +const useCurrentWorkspaceProvider = (): Workspace => { const { currentWorkspaceId } = useWorkspaceService(); const workspace = useResource(WorkspaceResource.detailShape(), { workspaceId: currentWorkspaceId || null, @@ -34,19 +28,16 @@ export const useCurrentWorkspaceProvider = (): Workspace => { return workspace; }; +const services = { + currentWorkspaceProvider: useCurrentWorkspaceProvider, +}; + /** * This Provider is main services entrypoint * It initializes all required services for app to work * and also adds all overrides of hooks/services */ const AppServicesProvider: React.FC = ({ children }) => { - const services = useMemo( - () => ({ - currentWorkspaceProvider: useCurrentWorkspaceProvider, - useCustomerIdProvider: useCustomerIdProvider, - }), - [] - ); return ( diff --git a/airbyte-webapp/src/packages/cloud/services/config/configProviders.ts b/airbyte-webapp/src/packages/cloud/services/config/configProviders.ts index 9329319933a7c..b20ed25467953 100644 --- a/airbyte-webapp/src/packages/cloud/services/config/configProviders.ts +++ b/airbyte-webapp/src/packages/cloud/services/config/configProviders.ts @@ -1,6 +1,6 @@ -import { ConfigProvider } from "config/types"; -import { CloudConfig } from "./types"; -import { isDefined } from "../../../../utils/common"; +import type { ConfigProvider } from "config/types"; +import type { CloudConfig } from "./types"; +import { isDefined } from "utils/common"; const CONFIG_PATH = "/config.json"; diff --git a/airbyte-webapp/src/packages/cloud/services/useFullStory.tsx b/airbyte-webapp/src/packages/cloud/services/thirdParty/fullstory/useFullStory.tsx similarity index 100% rename from airbyte-webapp/src/packages/cloud/services/useFullStory.tsx rename to airbyte-webapp/src/packages/cloud/services/thirdParty/fullstory/useFullStory.tsx diff --git a/airbyte-webapp/src/packages/cloud/services/IntercomProvider.tsx b/airbyte-webapp/src/packages/cloud/services/thirdParty/intercom/IntercomProvider.tsx similarity index 100% rename from airbyte-webapp/src/packages/cloud/services/IntercomProvider.tsx rename to airbyte-webapp/src/packages/cloud/services/thirdParty/intercom/IntercomProvider.tsx diff --git a/airbyte-webapp/src/packages/cloud/services/useIntercom.ts b/airbyte-webapp/src/packages/cloud/services/thirdParty/intercom/useIntercom.ts similarity index 85% rename from airbyte-webapp/src/packages/cloud/services/useIntercom.ts rename to airbyte-webapp/src/packages/cloud/services/thirdParty/intercom/useIntercom.ts index 0c93efc39ec4b..f60243dd91e5a 100644 --- a/airbyte-webapp/src/packages/cloud/services/useIntercom.ts +++ b/airbyte-webapp/src/packages/cloud/services/thirdParty/intercom/useIntercom.ts @@ -1,7 +1,7 @@ import { useEffect } from "react"; import { useIntercom as useIntercomProvider } from "react-use-intercom"; -import { useCurrentUser } from "./auth/AuthService"; +import { useCurrentUser } from "packages/cloud/services/auth/AuthService"; export const useIntercom = (): void => { const user = useCurrentUser(); diff --git a/airbyte-webapp/src/packages/cloud/views/CloudSettingsPage.tsx b/airbyte-webapp/src/packages/cloud/views/CloudSettingsPage.tsx new file mode 100644 index 0000000000000..17a973d513b35 --- /dev/null +++ b/airbyte-webapp/src/packages/cloud/views/CloudSettingsPage.tsx @@ -0,0 +1,77 @@ +import React, { useMemo } from "react"; +import { FormattedMessage } from "react-intl"; + +import useConnector from "hooks/services/useConnector"; +import { PageConfig } from "pages/SettingsPage/SettingsPage"; +import { + DestinationsPage as SettingsDestinationPage, + SourcesPage as SettingsSourcesPage, +} from "pages/SettingsPage/pages/ConnectorsPage"; +import SettingsPage from "pages/SettingsPage"; +import ConfigurationsPage from "pages/SettingsPage/pages/ConfigurationsPage"; +import NotificationPage from "pages/SettingsPage/pages/NotificationPage"; +import { Routes } from "../routes"; +import { AccountSettingsView } from "./users/AccountSettingsView"; +import { WorkspaceSettingsView } from "./workspaces/WorkspaceSettingsView"; +import { UsersSettingsView } from "./users/UsersSettingsView"; + +export const CloudSettingsPage: React.FC = () => { + const { countNewSourceVersion, countNewDestinationVersion } = useConnector(); + + const pageConfig = useMemo( + () => ({ + menuConfig: [ + { + category: , + routes: [ + { + path: `${Routes.Settings}${Routes.Account}`, + name: , + component: AccountSettingsView, + }, + ], + }, + { + category: , + routes: [ + { + path: `${Routes.Settings}${Routes.Workspace}`, + name: , + component: WorkspaceSettingsView, + }, + { + path: `${Routes.Settings}${Routes.Source}`, + name: , + indicatorCount: countNewSourceVersion, + component: SettingsSourcesPage, + }, + { + path: `${Routes.Settings}${Routes.Destination}`, + name: , + indicatorCount: countNewDestinationVersion, + component: SettingsDestinationPage, + }, + { + path: `${Routes.Settings}${Routes.Configuration}`, + name: , + component: ConfigurationsPage, + }, + { + path: `${Routes.Settings}${Routes.AccessManagement}`, + name: , + component: UsersSettingsView, + }, + { + path: `${Routes.Settings}${Routes.Notifications}`, + name: , + component: NotificationPage, + }, + ], + }, + ], + }), + [countNewSourceVersion, countNewDestinationVersion] + ); + + return ; +}; diff --git a/airbyte-webapp/src/packages/cloud/views/FirebaseActionRoute.tsx b/airbyte-webapp/src/packages/cloud/views/FirebaseActionRoute.tsx new file mode 100644 index 0000000000000..4fa4c2f8dd3d4 --- /dev/null +++ b/airbyte-webapp/src/packages/cloud/views/FirebaseActionRoute.tsx @@ -0,0 +1,31 @@ +import React from "react"; +import { useAsync } from "react-use"; + +import useRouter from "hooks/useRouter"; +import LoadingPage from "components/LoadingPage"; + +import { useAuthService } from "packages/cloud/services/auth/AuthService"; +import { ResetPasswordConfirmPage } from "./auth/ConfirmPasswordResetPage"; + +export enum FirebaseActionMode { + VERIFY_EMAIL = "verifyEmail", + RESET_PASSWORD = "resetPassword", +} + +export const VerifyEmailAction: React.FC = () => { + const { query } = useRouter<{ oobCode: string }>(); + const { verifyEmail } = useAuthService(); + + useAsync(async () => await verifyEmail(query.oobCode), []); + + return ; +}; + +export const ResetPasswordAction: React.FC = () => { + const { query } = useRouter<{ mode: string }>(); + + if (query.mode === FirebaseActionMode.RESET_PASSWORD) { + return ; + } + return ; +}; diff --git a/airbyte-webapp/src/packages/cloud/views/auth/Auth.tsx b/airbyte-webapp/src/packages/cloud/views/auth/Auth.tsx index 4c49b08c2aba5..00f60d30be423 100644 --- a/airbyte-webapp/src/packages/cloud/views/auth/Auth.tsx +++ b/airbyte-webapp/src/packages/cloud/views/auth/Auth.tsx @@ -7,12 +7,12 @@ import useRouter from "hooks/useRouter"; import FormContent from "./components/FormContent"; import News from "./components/News"; -import { FirebaseActionMode, Routes } from "packages/cloud/routes"; +import { Routes } from "packages/cloud/routes"; import { LoginPage } from "./LoginPage"; import { SignupPage } from "./SignupPage"; import { ResetPasswordPage } from "./ResetPasswordPage"; -import { ResetPasswordConfirmPage } from "./ConfirmPasswordResetPage"; +import { ResetPasswordAction } from "packages/cloud/views/FirebaseActionRoute"; const Content = styled.div` width: 100%; @@ -37,15 +37,6 @@ const NewsPart = styled(Part)` justify-content: space-between; `; -const FirebaseActionRoute: React.FC = () => { - const { query } = useRouter<{ mode: string }>(); - - if (query.mode === FirebaseActionMode.RESET_PASSWORD) { - return ; - } - return ; -}; - const Auth: React.FC = () => { const { pathname } = useRouter(); @@ -67,7 +58,7 @@ const Auth: React.FC = () => { - + 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 1e10c0f04c3eb..aaf8237550606 100644 --- a/airbyte-webapp/src/packages/cloud/views/layout/SideBar/SideBar.tsx +++ b/airbyte-webapp/src/packages/cloud/views/layout/SideBar/SideBar.tsx @@ -194,7 +194,9 @@ const SideBar: React.FC = () => { location.pathname.startsWith(Routes.Settings) } > - + + + diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx index d2a8e456a4fb4..1193a8128a2ce 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/ConnectionItemPage.tsx @@ -17,7 +17,7 @@ import { Routes } from "../../../routes"; import DestinationDefinitionResource from "core/resources/DestinationDefinition"; import SourceDefinitionResource from "core/resources/SourceDefinition"; import { equal } from "utils/objects"; -import { useAnalytics } from "hooks/useAnalytics"; +import { useAnalyticsService } from "hooks/services/Analytics/useAnalyticsService"; type ConnectionItemPageProps = { currentStep: "status" | "settings"; @@ -27,7 +27,7 @@ const ConnectionItemPage: React.FC = ({ currentStep, }) => { const { query, push } = useRouter<{ id: string }>(); - const analyticsService = useAnalytics(); + const analyticsService = useAnalyticsService(); const connection = useResource(ConnectionResource.detailShape(), { connectionId: query.id, }); diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/EnabledControl.tsx b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/EnabledControl.tsx index 73f7fcd2e9658..95dceeb58f08f 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/EnabledControl.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/EnabledControl.tsx @@ -6,7 +6,7 @@ import { Toggle } from "components"; import { Connection } from "core/resources/Connection"; import useConnection from "hooks/services/useConnectionHook"; import { Status } from "components/EntityTable/types"; -import { useAnalytics } from "hooks/useAnalytics"; +import { useAnalyticsService } from "hooks/services/Analytics/useAnalyticsService"; const ToggleLabel = styled.label` text-transform: uppercase; @@ -37,7 +37,7 @@ const EnabledControl: React.FC = ({ frequencyText, }) => { const { updateConnection } = useConnection(); - const analyticsService = useAnalytics(); + const analyticsService = useAnalyticsService(); const onChangeStatus = async () => { await updateConnection({ 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 32e7f15444264..8b657dc792d3a 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/StatusView.tsx +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/StatusView.tsx @@ -17,7 +17,7 @@ import useConnection from "hooks/services/useConnectionHook"; import useLoadingState from "hooks/useLoadingState"; import { DestinationDefinition } from "core/resources/DestinationDefinition"; import { SourceDefinition } from "core/resources/SourceDefinition"; -import { useAnalytics } from "hooks/useAnalytics"; +import { useAnalyticsService } from "hooks/services/Analytics/useAnalyticsService"; type IProps = { connection: Connection; @@ -61,7 +61,7 @@ const StatusView: React.FC = ({ }) => { const [isModalOpen, setIsModalOpen] = useState(false); const { isLoading, showFeedback, startAction } = useLoadingState(); - const analyticsService = useAnalytics(); + const analyticsService = useAnalyticsService(); const { jobs } = useResource(JobResource.listShape(), { configId: connection.connectionId, configTypes: ["sync", "reset_connection"], diff --git a/airbyte-webapp/src/pages/DestinationPage/pages/CreateDestinationPage/components/DestinationForm.tsx b/airbyte-webapp/src/pages/DestinationPage/pages/CreateDestinationPage/components/DestinationForm.tsx index 283ec9743668d..93472030774ca 100644 --- a/airbyte-webapp/src/pages/DestinationPage/pages/CreateDestinationPage/components/DestinationForm.tsx +++ b/airbyte-webapp/src/pages/DestinationPage/pages/CreateDestinationPage/components/DestinationForm.tsx @@ -10,7 +10,7 @@ import { JobsLogItem } from "components/JobItem"; import { createFormErrorMessage } from "utils/errorStatusMessage"; import { ConnectionConfiguration } from "core/domain/connection"; import { DestinationDefinition } from "core/resources/DestinationDefinition"; -import { useAnalytics } from "hooks/useAnalytics"; +import { useAnalyticsService } from "hooks/services/Analytics/useAnalyticsService"; type IProps = { onSubmit: (values: { @@ -35,7 +35,7 @@ const DestinationForm: React.FC = ({ afterSelectConnector, }) => { const { location } = useRouter(); - const analyticsService = useAnalytics(); + const analyticsService = useAnalyticsService(); const [destinationDefinitionId, setDestinationDefinitionId] = useState( location.state?.destinationDefinitionId || "" diff --git a/airbyte-webapp/src/pages/OnboardingPage/OnboardingPage.tsx b/airbyte-webapp/src/pages/OnboardingPage/OnboardingPage.tsx index 2e86bfd12f946..84bbf03477b69 100644 --- a/airbyte-webapp/src/pages/OnboardingPage/OnboardingPage.tsx +++ b/airbyte-webapp/src/pages/OnboardingPage/OnboardingPage.tsx @@ -23,7 +23,7 @@ import WelcomeStep from "./components/WelcomeStep"; import FinalStep from "./components/FinalStep"; import LetterLine from "./components/LetterLine"; import { StepType } from "./types"; -import { useAnalytics } from "hooks/useAnalytics"; +import { useAnalyticsService } from "hooks/services/Analytics/useAnalyticsService"; import StepsCounter from "./components/StepsCounter"; import LoadingPage from "components/LoadingPage"; import useWorkspace from "hooks/services/useWorkspace"; @@ -60,7 +60,7 @@ const ScreenContent = styled.div` `; const OnboardingPage: React.FC = () => { - const analyticsService = useAnalytics(); + const analyticsService = useAnalyticsService(); const { push } = useRouterHook(); useEffect(() => { diff --git a/airbyte-webapp/src/pages/OnboardingPage/components/DestinationStep.tsx b/airbyte-webapp/src/pages/OnboardingPage/components/DestinationStep.tsx index 078587f558fbe..37548c2a479c2 100644 --- a/airbyte-webapp/src/pages/OnboardingPage/components/DestinationStep.tsx +++ b/airbyte-webapp/src/pages/OnboardingPage/components/DestinationStep.tsx @@ -13,7 +13,7 @@ import { DestinationDefinition } from "core/resources/DestinationDefinition"; import TitlesBlock from "./TitlesBlock"; import HighlightedText from "./HighlightedText"; -import { useAnalytics } from "hooks/useAnalytics"; +import { useAnalyticsService } from "hooks/services/Analytics/useAnalyticsService"; type IProps = { availableServices: DestinationDefinition[]; @@ -43,7 +43,7 @@ const DestinationStep: React.FC = ({ isLoading, } = useDestinationDefinitionSpecificationLoad(destinationDefinitionId); - const analyticsService = useAnalytics(); + const analyticsService = useAnalyticsService(); const onDropDownSelect = (destinationDefinition: string) => { const destinationConnector = availableServices.find( diff --git a/airbyte-webapp/src/pages/OnboardingPage/components/SourceStep.tsx b/airbyte-webapp/src/pages/OnboardingPage/components/SourceStep.tsx index 0fb98a2bd74ec..2dd269eaf0fd4 100644 --- a/airbyte-webapp/src/pages/OnboardingPage/components/SourceStep.tsx +++ b/airbyte-webapp/src/pages/OnboardingPage/components/SourceStep.tsx @@ -12,7 +12,7 @@ import { JobsLogItem } from "components/JobItem"; import { useSourceDefinitionSpecificationLoad } from "hooks/services/useSourceHook"; import { createFormErrorMessage } from "utils/errorStatusMessage"; -import { useAnalytics } from "hooks/useAnalytics"; +import { useAnalyticsService } from "hooks/services/Analytics/useAnalyticsService"; import HighlightedText from "./HighlightedText"; import TitlesBlock from "./TitlesBlock"; @@ -39,7 +39,7 @@ const SourceStep: React.FC = ({ afterSelectConnector, }) => { const [sourceDefinitionId, setSourceDefinitionId] = useState(""); - const analyticsService = useAnalytics(); + const analyticsService = useAnalyticsService(); const { sourceDefinitionSpecification, diff --git a/airbyte-webapp/src/pages/PreferencesPage/PreferencesPage.tsx b/airbyte-webapp/src/pages/PreferencesPage/PreferencesPage.tsx index 47bcf47e0fd57..395f56cc28a8f 100644 --- a/airbyte-webapp/src/pages/PreferencesPage/PreferencesPage.tsx +++ b/airbyte-webapp/src/pages/PreferencesPage/PreferencesPage.tsx @@ -6,7 +6,7 @@ import { PageViewContainer } from "components/CenteredPageComponents"; import { H1 } from "components"; import { PreferencesForm } from "views/Settings/PreferencesForm"; import HeadTitle from "components/HeadTitle"; -import { useAnalytics } from "hooks/useAnalytics"; +import { useAnalyticsService } from "hooks/services/Analytics/useAnalyticsService"; import useWorkspace from "hooks/services/useWorkspace"; const Title = styled(H1)` @@ -14,7 +14,7 @@ const Title = styled(H1)` `; const PreferencesPage: React.FC = () => { - const analyticsService = useAnalytics(); + const analyticsService = useAnalyticsService(); useEffect(() => analyticsService.page("Preferences Page"), [ analyticsService, ]); diff --git a/airbyte-webapp/src/pages/SourcesPage/pages/CreateSourcePage/components/SourceForm.tsx b/airbyte-webapp/src/pages/SourcesPage/pages/CreateSourcePage/components/SourceForm.tsx index b7c783381db4d..dba54c37f9e6e 100644 --- a/airbyte-webapp/src/pages/SourcesPage/pages/CreateSourcePage/components/SourceForm.tsx +++ b/airbyte-webapp/src/pages/SourcesPage/pages/CreateSourcePage/components/SourceForm.tsx @@ -10,7 +10,7 @@ import { JobsLogItem } from "components/JobItem"; import { createFormErrorMessage } from "utils/errorStatusMessage"; import { ConnectionConfiguration } from "core/domain/connection"; import { SourceDefinition } from "core/resources/SourceDefinition"; -import { useAnalytics } from "hooks/useAnalytics"; +import { useAnalyticsService } from "hooks/services/Analytics/useAnalyticsService"; type IProps = { onSubmit: (values: { @@ -35,7 +35,7 @@ const SourceForm: React.FC = ({ afterSelectConnector, }) => { const { location } = useRouter(); - const analyticsService = useAnalytics(); + const analyticsService = useAnalyticsService(); const [sourceDefinitionId, setSourceDefinitionId] = useState( location.state?.sourceDefinitionId || "" diff --git a/airbyte-webapp/src/pages/routes.tsx b/airbyte-webapp/src/pages/routes.tsx index 20f14dd2b333c..1f7aadc840bef 100644 --- a/airbyte-webapp/src/pages/routes.tsx +++ b/airbyte-webapp/src/pages/routes.tsx @@ -17,12 +17,16 @@ import ConnectionPage from "./ConnectionPage"; import SettingsPage from "./SettingsPage"; import LoadingPage from "components/LoadingPage"; import MainView from "views/layout/MainView"; +import { CompleteOauthRequest } from "views/CompleteOauthRequest"; import { useWorkspace } from "hooks/services/useWorkspace"; -import { useNotificationService } from "hooks/services/Notification/NotificationService"; +import { useNotificationService } from "hooks/services/Notification"; import { useApiHealthPoll } from "hooks/services/Health"; -import { WithPageAnalytics } from "./withPageAnalytics"; -import { CompleteOauthRequest } from "./CompleteOauthRequest"; +import { + useAnalyticsIdentifyUser, + useAnalyticsRegisterValues, + TrackPageAnalytics, +} from "hooks/services/Analytics"; export enum Routes { Preferences = "/preferences", @@ -116,6 +120,16 @@ export const Routing: React.FC = () => { const { workspace } = useWorkspace(); + const analyticsContext = useMemo( + () => ({ + workspaceId: workspace.workspaceId, + customerId: workspace.customerId, + }), + [workspace.workspaceId, workspace.customerId] + ); + useAnalyticsRegisterValues(analyticsContext); + useAnalyticsIdentifyUser(workspace.workspaceId); + return ( }> @@ -123,7 +137,7 @@ export const Routing: React.FC = () => { ) : ( <> - + )} diff --git a/airbyte-webapp/src/pages/CompleteOauthRequest.tsx b/airbyte-webapp/src/views/CompleteOauthRequest.tsx similarity index 100% rename from airbyte-webapp/src/pages/CompleteOauthRequest.tsx rename to airbyte-webapp/src/views/CompleteOauthRequest.tsx diff --git a/airbyte-webapp/src/views/common/AnalyticsInitializer.tsx b/airbyte-webapp/src/views/common/AnalyticsInitializer.tsx deleted file mode 100644 index c54a4f1374019..0000000000000 --- a/airbyte-webapp/src/views/common/AnalyticsInitializer.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import React, { useEffect } from "react"; - -import { useConfig } from "config"; -import AnalyticsServiceProvider, { useAnalytics } from "hooks/useAnalytics"; -import useSegment from "hooks/useSegment"; -import { useGetService } from "core/servicesProvider"; - -function WithAnalytics({ - customerId, -}: { - customerId: string; - workspaceId?: string; -}) { - const config = useConfig(); - - // segment section - useSegment(config.segment.enabled ? config.segment.token : ""); - const analyticsService = useAnalytics(); - useEffect(() => { - analyticsService.identify(customerId); - }, [analyticsService, customerId]); - - return null; -} - -const AnalyticsInitializer: React.FC<{ - children: React.ReactNode; -}> = ({ children }) => { - const customerIdProvider = useGetService<() => string>( - "useCustomerIdProvider" - ); - const customerId = customerIdProvider(); - const config = useConfig(); - - return ( - - - {children} - - ); -}; - -export { AnalyticsInitializer }; diff --git a/airbyte-webapp/src/views/common/AnalyticsProvider.tsx b/airbyte-webapp/src/views/common/AnalyticsProvider.tsx new file mode 100644 index 0000000000000..ca7c1fab6ccae --- /dev/null +++ b/airbyte-webapp/src/views/common/AnalyticsProvider.tsx @@ -0,0 +1,18 @@ +import React from "react"; + +import { useConfig } from "config"; +import AnalyticsServiceProvider from "hooks/services/Analytics/useAnalyticsService"; +import useSegment from "hooks/useSegment"; + +const AnalyticsProvider: React.FC = ({ children }) => { + const config = useConfig(); + useSegment(config.segment.enabled ? config.segment.token : ""); + + return ( + + {children} + + ); +}; + +export { AnalyticsProvider };