signoz/frontend/src/container/OnboardingContainer/OnboardingContainer.tsx
CheetoDa 8ff392bc96
feat: azure monitoring docs (#5159)
* feat: azure monitoring docs

* chore: mapped paths

* chore: fixed instructions

* fix: added central collector steps

* fix: handle default azure steps, card alignment and reload issues

* fix: removed return true

---------

Co-authored-by: YounixM <myounis.ar@live.com>
2024-06-21 15:05:37 +05:30

354 lines
9.8 KiB
TypeScript

/* eslint-disable jsx-a11y/no-static-element-interactions */
/* eslint-disable jsx-a11y/click-events-have-key-events */
import './Onboarding.styles.scss';
import { ArrowRightOutlined } from '@ant-design/icons';
import { Button, Card, Typography } from 'antd';
import getIngestionData from 'api/settings/getIngestionData';
import cx from 'classnames';
import ROUTES from 'constants/routes';
import FullScreenHeader from 'container/FullScreenHeader/FullScreenHeader';
import useAnalytics from 'hooks/analytics/useAnalytics';
import { useIsDarkMode } from 'hooks/useDarkMode';
import history from 'lib/history';
import { useEffect, useState } from 'react';
import { useQuery } from 'react-query';
import { useEffectOnce } from 'react-use';
import ModuleStepsContainer from './common/ModuleStepsContainer/ModuleStepsContainer';
import { stepsMap } from './constants/stepsConfig';
import {
OnboardingMethods,
useOnboardingContext,
} from './context/OnboardingContext';
import { DataSourceType } from './Steps/DataSource/DataSource';
import {
defaultApplicationDataSource,
defaultAwsServices,
defaultAzureServices,
defaultInfraMetricsType,
defaultLogsType,
moduleRouteMap,
} from './utils/dataSourceUtils';
import {
APM_STEPS,
AWS_MONITORING_STEPS,
AZURE_MONITORING_STEPS,
getSteps,
INFRASTRUCTURE_MONITORING_STEPS,
LOGS_MANAGEMENT_STEPS,
} from './utils/getSteps';
export enum ModulesMap {
APM = 'APM',
LogsManagement = 'LogsManagement',
InfrastructureMonitoring = 'InfrastructureMonitoring',
AwsMonitoring = 'AwsMonitoring',
AzureMonitoring = 'AzureMonitoring',
}
export interface ModuleProps {
id: string;
title: string;
desc: string;
}
export interface SelectedModuleStepProps {
id: string;
title: string;
component: any;
}
export const useCases = {
APM: {
id: ModulesMap.APM,
title: 'Application Monitoring',
desc:
'Monitor application metrics like p99 latency, error rates, external API calls, and db calls.',
},
LogsManagement: {
id: ModulesMap.LogsManagement,
title: 'Logs Management',
desc:
'Easily filter and query logs, build dashboards and alerts based on attributes in logs',
},
InfrastructureMonitoring: {
id: ModulesMap.InfrastructureMonitoring,
title: 'Infrastructure Monitoring',
desc:
'Monitor Kubernetes infrastructure metrics, hostmetrics, or metrics of any third-party integration',
},
AwsMonitoring: {
id: ModulesMap.AwsMonitoring,
title: 'AWS Monitoring',
desc:
'Monitor your traces, logs and metrics for AWS services like EC2, ECS, EKS etc.',
},
AzureMonitoring: {
id: ModulesMap.AzureMonitoring,
title: 'Azure Monitoring',
desc:
'Monitor your traces, logs and metrics for Azure services like AKS, Container Apps, App Service etc.',
},
};
export default function Onboarding(): JSX.Element {
const [selectedModule, setSelectedModule] = useState<ModuleProps>(
useCases.APM,
);
const [selectedModuleSteps, setSelectedModuleSteps] = useState(APM_STEPS);
const [activeStep, setActiveStep] = useState(1);
const [current, setCurrent] = useState(0);
const isDarkMode = useIsDarkMode();
const { trackEvent } = useAnalytics();
const { location } = history;
const {
selectedDataSource,
selectedEnvironment,
selectedMethod,
updateSelectedModule,
updateSelectedDataSource,
resetProgress,
updateActiveStep,
updateIngestionData,
} = useOnboardingContext();
useEffectOnce(() => {
trackEvent('Onboarding V2 Started');
});
const { status, data: ingestionData } = useQuery({
queryFn: () => getIngestionData(),
});
useEffect(() => {
if (
status === 'success' &&
ingestionData &&
ingestionData &&
Array.isArray(ingestionData.payload)
) {
const payload = ingestionData.payload[0] || {
ingestionKey: '',
dataRegion: '',
};
updateIngestionData({
SIGNOZ_INGESTION_KEY: payload?.ingestionKey,
REGION: payload?.dataRegion,
});
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [status, ingestionData?.payload]);
const setModuleStepsBasedOnSelectedDataSource = (
selectedDataSource: DataSourceType | null,
): void => {
if (selectedDataSource) {
let steps: SelectedModuleStepProps[] = [];
steps = getSteps({
selectedDataSource,
});
setSelectedModuleSteps(steps);
}
};
const removeStep = (
stepToRemove: string,
steps: SelectedModuleStepProps[],
): SelectedModuleStepProps[] =>
steps.filter((step) => step.id !== stepToRemove);
const handleAPMSteps = (): void => {
if (selectedEnvironment === 'kubernetes') {
const updatedSteps = removeStep(stepsMap.selectMethod, APM_STEPS);
setSelectedModuleSteps(updatedSteps);
return;
}
if (selectedMethod === OnboardingMethods.QUICK_START) {
const updatedSteps = removeStep(stepsMap.setupOtelCollector, APM_STEPS);
setSelectedModuleSteps(updatedSteps);
return;
}
setSelectedModuleSteps(APM_STEPS);
};
// eslint-disable-next-line sonarjs/cognitive-complexity
useEffect(() => {
if (selectedModule?.id === ModulesMap.InfrastructureMonitoring) {
if (selectedDataSource) {
setModuleStepsBasedOnSelectedDataSource(selectedDataSource);
} else {
setSelectedModuleSteps(INFRASTRUCTURE_MONITORING_STEPS);
updateSelectedDataSource(defaultInfraMetricsType);
}
} else if (selectedModule?.id === ModulesMap.LogsManagement) {
if (selectedDataSource) {
setModuleStepsBasedOnSelectedDataSource(selectedDataSource);
} else {
setSelectedModuleSteps(LOGS_MANAGEMENT_STEPS);
updateSelectedDataSource(defaultLogsType);
}
} else if (selectedModule?.id === ModulesMap.AwsMonitoring) {
if (selectedDataSource) {
setModuleStepsBasedOnSelectedDataSource(selectedDataSource);
} else {
setSelectedModuleSteps(AWS_MONITORING_STEPS);
updateSelectedDataSource(defaultAwsServices);
}
} else if (selectedModule?.id === ModulesMap.AzureMonitoring) {
if (selectedDataSource) {
setModuleStepsBasedOnSelectedDataSource(selectedDataSource);
} else {
setSelectedModuleSteps(AZURE_MONITORING_STEPS);
updateSelectedDataSource(defaultAzureServices);
}
} else if (selectedModule?.id === ModulesMap.APM) {
handleAPMSteps();
if (!selectedDataSource) {
updateSelectedDataSource(defaultApplicationDataSource);
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedModule, selectedDataSource, selectedEnvironment, selectedMethod]);
const handleNextStep = (): void => {
if (activeStep <= 3) {
const nextStep = activeStep + 1;
// on next
trackEvent('Onboarding V2: Get Started', {
selectedModule: selectedModule.id,
nextStepId: nextStep,
});
setActiveStep(nextStep);
setCurrent(current + 1);
// set the active step info
updateActiveStep({
module: selectedModule,
step: selectedModuleSteps[current],
});
}
};
const handleNext = (): void => {
if (activeStep <= 3) {
handleNextStep();
history.replace(moduleRouteMap[selectedModule.id as ModulesMap]);
}
};
const handleModuleSelect = (module: ModuleProps): void => {
setSelectedModule(module);
updateSelectedModule(module);
updateSelectedDataSource(null);
};
useEffect(() => {
const { pathname } = location;
if (pathname === ROUTES.GET_STARTED_APPLICATION_MONITORING) {
handleModuleSelect(useCases.APM);
updateSelectedDataSource(defaultApplicationDataSource);
handleNextStep();
} else if (pathname === ROUTES.GET_STARTED_INFRASTRUCTURE_MONITORING) {
handleModuleSelect(useCases.InfrastructureMonitoring);
handleNextStep();
} else if (pathname === ROUTES.GET_STARTED_LOGS_MANAGEMENT) {
handleModuleSelect(useCases.LogsManagement);
handleNextStep();
} else if (pathname === ROUTES.GET_STARTED_AWS_MONITORING) {
handleModuleSelect(useCases.AwsMonitoring);
handleNextStep();
} else if (pathname === ROUTES.GET_STARTED_AZURE_MONITORING) {
handleModuleSelect(useCases.AzureMonitoring);
handleNextStep();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<div className={cx('container', isDarkMode ? 'darkMode' : 'lightMode')}>
{activeStep === 1 && (
<>
<FullScreenHeader />
<div className="onboardingHeader">
<h1> Select a use-case to get started</h1>
</div>
<div className="modulesContainer">
<div className="moduleContainerRowStyles">
{Object.keys(ModulesMap).map((module) => {
const selectedUseCase = (useCases as any)[module];
return (
<Card
className={cx(
'moduleStyles',
selectedModule.id === selectedUseCase.id ? 'selected' : '',
)}
style={{
backgroundColor: isDarkMode ? '#000' : '#FFF',
}}
key={selectedUseCase.id}
onClick={(): void => handleModuleSelect(selectedUseCase)}
>
<Typography.Title
className="moduleTitleStyle"
level={4}
style={{
borderBottom: isDarkMode ? '1px solid #303030' : '1px solid #ddd',
backgroundColor: isDarkMode ? '#141414' : '#FFF',
}}
>
{selectedUseCase.title}
</Typography.Title>
<Typography.Paragraph
className="moduleDesc"
style={{ backgroundColor: isDarkMode ? '#000' : '#FFF' }}
>
{selectedUseCase.desc}
</Typography.Paragraph>
</Card>
);
})}
</div>
</div>
<div className="continue-to-next-step">
<Button type="primary" icon={<ArrowRightOutlined />} onClick={handleNext}>
Get Started
</Button>
</div>
</>
)}
{activeStep > 1 && (
<div className="stepsContainer">
<ModuleStepsContainer
onReselectModule={(): void => {
setCurrent(current - 1);
setActiveStep(activeStep - 1);
setSelectedModule(useCases.APM);
resetProgress();
history.push(ROUTES.GET_STARTED);
}}
selectedModule={selectedModule}
selectedModuleSteps={selectedModuleSteps}
/>
</div>
)}
</div>
);
}