diff --git a/src/App.tsx b/src/App.tsx index 05a899cf0..be26909ad 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,6 +1,7 @@ import { AppRouted } from '@/AppRouted'; import { Toaster } from '@/components/ui/sonner'; import { useDatadog } from '@/integrations/datadog/datadog'; +import { useGTM } from '@/integrations/google/gtm'; import { useReo } from '@/integrations/reo/reo'; import { queryClient } from '@/react-query/queryClient'; import { QueryClientProvider } from '@tanstack/react-query'; @@ -9,6 +10,7 @@ import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; export function App() { useReo(); useDatadog(); + useGTM(); return ( <> diff --git a/src/features/cluster/Scaling.tsx b/src/features/cluster/Scaling.tsx index c76057e37..1df534ca2 100644 --- a/src/features/cluster/Scaling.tsx +++ b/src/features/cluster/Scaling.tsx @@ -47,8 +47,7 @@ export function Scaling() {

Here we go!

Your cluster is updating with the latest changes. This includes waiting several minutes to let - traffic drain safely. - + traffic drain safely. We will let you know when we are ready for you to connect! In the meantime, join us on Discord! Get real-time help from our engineers, see feature drops early, and connect with others building on Fabric. diff --git a/src/features/cluster/StartingUp.tsx b/src/features/cluster/StartingUp.tsx index d83d2beab..f220c7f5c 100644 --- a/src/features/cluster/StartingUp.tsx +++ b/src/features/cluster/StartingUp.tsx @@ -91,8 +91,7 @@ export function StartingUp() {

Here we go!

Your cluster is spinning up with the latest changes, including your own DNS records and private - connections. Please wait while we get everything going. - + connections. Please wait while we get everything going. We will let you know when we are ready for you to connect! In the meantime, join us on Discord! Get real-time help from our engineers, see feature drops early, and connect with others building on Fabric. diff --git a/src/features/instance/config/overview/index.tsx b/src/features/instance/config/overview/index.tsx index 3c0ca00ff..078bd1bc1 100644 --- a/src/features/instance/config/overview/index.tsx +++ b/src/features/instance/config/overview/index.tsx @@ -10,12 +10,13 @@ import { InstanceNodeName } from '@/features/instance/config/overview/components import { InstanceURL } from '@/features/instance/config/overview/components/InstanceURL'; import { Instance } from '@/integrations/api/api.patch'; import { getConfigurationQueryOptions } from '@/integrations/api/instance/status/getConfiguration'; -import { getRegistrationInfoQueryOptions } from '@/integrations/api/instance/status/getRegistrationInfo'; +import { getRegistrationInfoQueryOptions, RegistrationInfoResponse } from '@/integrations/api/instance/status/getRegistrationInfo'; import { getUsageLicensesQueryOptions } from '@/integrations/api/instance/status/getUsageLicenses'; import { keyBy } from '@/lib/keyBy'; +import { wasAReleasedBeforeB } from '@/lib/string/wasAReleasedBeforeB'; import Editor from '@monaco-editor/react'; import { useQuery } from '@tanstack/react-query'; -import { useParams, useRouteContext } from '@tanstack/react-router'; +import { useLoaderData, useParams, useRouteContext } from '@tanstack/react-router'; import { ReactNode, useMemo } from 'react'; const LocalStudioOverview = ({ children }: { children: ReactNode }) => { @@ -32,11 +33,14 @@ export function ConfigOverviewIndex() { const targetNoun = (instanceId || isLocalStudio) ? 'Instance' : 'Cluster'; const instanceParams = useInstanceClientIdParams(); + const { version }: RegistrationInfoResponse = useLoaderData({ strict: false }); + const checkUsageLicenses = !isLocalStudio && wasAReleasedBeforeB('4.7.0-alpha.1', version); + const { data: info, isLoading: loadingInstanceInfo } = useQuery( getInstanceInfoQueryOptions({ clusterId, instanceId }), ); const { data: appliedLicenses } = useQuery( - getUsageLicensesQueryOptions(instanceParams), + getUsageLicensesQueryOptions(instanceParams, checkUsageLicenses), ); const clusterInfo = info?.cluster; const instanceInfo = info?.instance; diff --git a/src/features/instance/config/routes.ts b/src/features/instance/config/routes.ts index d67cd5f18..f52625387 100644 --- a/src/features/instance/config/routes.ts +++ b/src/features/instance/config/routes.ts @@ -4,6 +4,7 @@ import { ConfigRolesIndex } from '@/features/instance/config/roles'; import { ConfigSSHKeysIndex } from '@/features/instance/config/sshKeys'; import { ConfigUsersIndex } from '@/features/instance/config/users'; import { createInstanceLayoutRoute } from '@/features/instance/instanceLayoutRoute'; +import { registrationInfoLoader } from '@/features/instance/registrationInfoLoader'; import { createRoute } from '@tanstack/react-router'; export function createConfigRouteTree(instanceLayoutRoute: ReturnType) { @@ -16,6 +17,7 @@ export function createConfigRouteTree(instanceLayoutRoute: ReturnType instanceConfigRoute, path: '/', component: ConfigOverviewIndex, + loader: registrationInfoLoader, }); const instanceConfigRolesRoute = createRoute({ diff --git a/src/features/instance/instanceLayoutRoute.ts b/src/features/instance/instanceLayoutRoute.ts index a9df38c4b..83e9430f4 100644 --- a/src/features/instance/instanceLayoutRoute.ts +++ b/src/features/instance/instanceLayoutRoute.ts @@ -1,5 +1,4 @@ import { getInstanceClient } from '@/config/getInstanceClient'; -import { getInstanceClientIdFromParams } from '@/config/useInstanceClient'; import { AuthenticatedCloudConnection, AuthenticatedConnection, @@ -10,11 +9,10 @@ import { clusterLayoutRoute } from '@/features/cluster/clusterLayoutRoute'; import { InstanceLayout } from '@/features/instance/InstanceLayout'; import { getOrganizationClusterInstancePermissions, getOrganizationClusterPermissions } from '@/hooks/usePermissions'; import { getInstanceUserInfo } from '@/integrations/api/instance/status/getInstanceUserInfo'; -import { getRegistrationInfoQueryOptions } from '@/integrations/api/instance/status/getRegistrationInfo'; import { buildRedirectInSearch } from '@/lib/urls/buildRedirectInSearch'; import { dashboardLayout } from '@/router/dashboardRoute'; -import { QueryClient } from '@tanstack/react-query'; import { createRoute, redirect } from '@tanstack/react-router'; +import { registrationInfoLoader } from './registrationInfoLoader'; export function createInstanceLayoutRoute(mode: 'local' | 'cluster' | 'instance') { switch (mode) { @@ -90,14 +88,3 @@ async function checkClusterInstanceAuthenticationBeforeLoad({ + `/sign-in`; throw redirect({ to, search: buildRedirectInSearch() }); } - -function registrationInfoLoader({ - context, - params, -}: { - context: { queryClient: QueryClient }, - params: { organizationId?: string; clusterId?: string, instanceId?: string }, -}) { - const operationsParams = getInstanceClientIdFromParams(params); - return context.queryClient.ensureQueryData(getRegistrationInfoQueryOptions(operationsParams)); -} diff --git a/src/features/instance/registrationInfoLoader.ts b/src/features/instance/registrationInfoLoader.ts new file mode 100644 index 000000000..5839035d3 --- /dev/null +++ b/src/features/instance/registrationInfoLoader.ts @@ -0,0 +1,14 @@ +import { getInstanceClientIdFromParams } from '@/config/useInstanceClient'; +import { getRegistrationInfoQueryOptions } from '@/integrations/api/instance/status/getRegistrationInfo'; +import { QueryClient } from '@tanstack/react-query'; + +export function registrationInfoLoader({ + context, + params, +}: { + context: { queryClient: QueryClient }, + params: { organizationId?: string; clusterId?: string, instanceId?: string }, +}) { + const operationsParams = getInstanceClientIdFromParams(params); + return context.queryClient.ensureQueryData(getRegistrationInfoQueryOptions(operationsParams)); +} diff --git a/src/integrations/api/instance/status/getUsageLicenses.ts b/src/integrations/api/instance/status/getUsageLicenses.ts index 251f865d8..53158d80b 100644 --- a/src/integrations/api/instance/status/getUsageLicenses.ts +++ b/src/integrations/api/instance/status/getUsageLicenses.ts @@ -1,4 +1,3 @@ -import { isLocalStudio } from '@/config/constants'; import { InstanceClientIdConfig } from '@/config/instanceClientConfig'; import { queryOptions } from '@tanstack/react-query'; @@ -28,10 +27,10 @@ interface UsageLicense { __updatedtime__: string; } -export function getUsageLicensesQueryOptions({ entityId, instanceClient }: InstanceClientIdConfig) { +export function getUsageLicensesQueryOptions({ entityId, instanceClient }: InstanceClientIdConfig, enabled: boolean) { return queryOptions({ queryKey: [entityId, 'get_usage_licenses'] as const, - enabled: !isLocalStudio, + enabled, queryFn: async () => { try { const { data } = await instanceClient.post('/', { diff --git a/src/integrations/google/gtm.ts b/src/integrations/google/gtm.ts new file mode 100644 index 000000000..5b5c6f3ea --- /dev/null +++ b/src/integrations/google/gtm.ts @@ -0,0 +1,30 @@ +import { isLocalStudio } from '@/config/constants'; +import { useEffect } from 'react'; + +let initialized = false; +const enabled = !import.meta.env.DEV && !isLocalStudio; + +export function useGTM() { + useEffect(() => { + if (initialized) { + return; + } + initialized = true; + if (enabled) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (function(w: any, d: any, s, l, i) { + w[l] = w[l] || []; + w[l].push({ + 'gtm.start': + new Date().getTime(), event: 'gtm.js', + }); + const f = d.getElementsByTagName(s)[0]; + const j = d.createElement(s); + const dl = l !== 'dataLayer' ? `&l=${l}` : ''; + j.async = true; + j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl; + f.parentNode.insertBefore(j, f); + })(window, document, 'script', 'dataLayer', 'GTM-5QQX432'); + } + }, []); + }