diff --git a/src/@types/parseable/api/about.ts b/src/@types/parseable/api/about.ts index 2149c362..3f3adffe 100644 --- a/src/@types/parseable/api/about.ts +++ b/src/@types/parseable/api/about.ts @@ -14,4 +14,7 @@ export type AboutData = { grpcPort: number; oidcActive: boolean; cache: string; + analytics: { + clarityTag: string; + } }; diff --git a/src/components/Navbar/infoModal.tsx b/src/components/Navbar/infoModal.tsx index 01ddd0df..4a752857 100644 --- a/src/components/Navbar/infoModal.tsx +++ b/src/components/Navbar/infoModal.tsx @@ -16,7 +16,7 @@ const InfoModal: FC = (props) => { const { opened, close } = props; const { getAboutData, getAboutIsError, getAboutIsLoading } = useAbout(); - const [, setAppStore] = useAppStore((_store) => null); + const [analytics, setAppStore] = useAppStore((store) => store.instanceConfig?.analytics); const llmStatus = useMemo(() => { let status = 'LLM API Key not set'; if (getAboutData?.data?.llmActive) { @@ -114,7 +114,9 @@ const InfoModal: FC = (props) => { Store - {getAboutData?.data?.store?.type} + + {getAboutData?.data?.store?.type} + @@ -128,6 +130,10 @@ const InfoModal: FC = (props) => { LLM Status {llmStatus} + + Usage Analytics + {analytics?.clarityTag ? 'Tracking (MS Clarity)' : 'Not Tracking'} + ) : null} diff --git a/src/layouts/MainLayout/index.tsx b/src/layouts/MainLayout/index.tsx index 66c500cf..4c5e498a 100644 --- a/src/layouts/MainLayout/index.tsx +++ b/src/layouts/MainLayout/index.tsx @@ -2,23 +2,29 @@ import { PrimaryHeader } from '@/components/Header'; import Navbar from '@/components/Navbar'; import { NAVBAR_WIDTH, PRIMARY_HEADER_HEIGHT } from '@/constants/theme'; import { Box } from '@mantine/core'; -import { useCallback, useEffect, type FC } from 'react'; +import { useCallback, useEffect, useState, type FC } from 'react'; import { Outlet } from 'react-router-dom'; import { heights } from '@/components/Mantine/sizing'; import { useAppStore, appStoreReducers } from './providers/AppProvider'; +import _ from 'lodash'; const { toggleMaximize } = appStoreReducers; const MainLayout: FC = () => { const [maximized, setAppStore] = useAppStore((store) => store.maximized); + const [analytics] = useAppStore((store) => store.instanceConfig?.analytics); + const [trackingScriptsAdded, setTrackingScriptsAdded] = useState(false); const primaryHeaderHeight = !maximized ? PRIMARY_HEADER_HEIGHT : 0; const navbarWidth = !maximized ? NAVBAR_WIDTH : 0; - const handleEscKeyPress = useCallback((event: KeyboardEvent) => { - if (event.key === 'Escape') { - maximized && setAppStore(toggleMaximize); - } - }, [maximized]); + const handleEscKeyPress = useCallback( + (event: KeyboardEvent) => { + if (event.key === 'Escape') { + maximized && setAppStore(toggleMaximize); + } + }, + [maximized], + ); useEffect(() => { window.addEventListener('keydown', handleEscKeyPress); @@ -27,6 +33,19 @@ const MainLayout: FC = () => { }; }, [maximized]); + useEffect(() => { + if (analytics && _.isString(analytics.clarityTag) && !_.isEmpty(analytics.clarityTag) && !trackingScriptsAdded) { + const script = document.createElement('script'); + script.type = 'text/javascript'; + script.innerHTML = `(function(c,l,a,r,i,t,y){ c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)}; t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i; y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y); })(window, document, "clarity", "script", "${analytics.clarityTag}");`; + document.body.appendChild(script); + setTrackingScriptsAdded(true); + return () => { + document.body.removeChild(script); + }; + } + }, [analytics]); + return ( diff --git a/src/layouts/MainLayout/providers/AppProvider.tsx b/src/layouts/MainLayout/providers/AppProvider.tsx index 5dcc8019..d4a8b225 100644 --- a/src/layouts/MainLayout/providers/AppProvider.tsx +++ b/src/layouts/MainLayout/providers/AppProvider.tsx @@ -29,7 +29,7 @@ type AppStore = { streamSpecificUserAccess: string[] | null; instanceConfig: AboutData | null; isStandAloneMode: boolean | null; - savedFilters: SavedFilterType[] | null; // null to verify whether filters have been fetched or not + savedFilters: SavedFilterType[] | null; // null to verify whether filters have been fetched or not activeSavedFilters: SavedFilterType[]; // stream specific }; diff --git a/src/pages/Login/styles/Login.module.css b/src/pages/Login/styles/Login.module.css index 1a4a7759..2a8f205c 100644 --- a/src/pages/Login/styles/Login.module.css +++ b/src/pages/Login/styles/Login.module.css @@ -4,15 +4,15 @@ width: 30vw; background: radial-gradient(circle at 78.7% 87.8%, #FFFFFF 70%, #E1EAEE 60%); padding: 20px; - } - - @media (max-width: 768px) { +} + +@media (max-width: 768px) { .sideContainer { - display: none; + display: none; } - } - - .container { +} + +.container { position: relative; flex: 1; display: flex; @@ -20,50 +20,55 @@ justify-content: center; background-repeat: no-repeat; background-position: top center; - } - - .formContainer { +} + +.formContainer { position: relative; padding: 24px; border-radius: 4px; box-shadow: 0 0 24px 0 rgba(0, 0, 0, 0.2); border: 1px solid #D4D4D4; - width: 20rem; + width: 22rem; display: flex; flex-direction: column; align-items: center; - } - - .formInput { +} + +.formInput { width: 100%; - } - - .titleStyle { +} + +.titleStyle { color: #10143E; font-weight: 700; font-size: 24px; - } - - .descriptionStyle { +} + +.descriptionStyle { text-align: center; font-size: 14px; color: #828282; - } - - .errorStyle { +} + +.errorStyle { color: #FC466B; - } - - .loginBtnStyle { +} + +.loginBtnStyle { width: 100%; background-color: #545BEB; + &:hover { background-color: #FC466B; } - } +} - .loginBtnStyle:disabled, - .loginBtnStyle:disabled:hover - { +.loginBtnStyle:disabled, +.loginBtnStyle:disabled:hover { background-color: var(--mantine-color-gray-4); - } \ No newline at end of file +} + +.consentDescription { + font-size: 0.66rem; + color: var(--mantine-color-gray-6); +} \ No newline at end of file