feat: route to the onboarding flow when clicking the sending logs in case of no logs (#4600)

* feat: refactor onboarding flow to add path params when selecting any module

* feat: added re-route to the onboarding flow in case of no logs and no traces

* chore: remove console logs

* chore: increase type safety

* chore: updated tab names

* chore: remove development conditions

* chore: handle cloud user

* feat: handle aws monitoring cases

* fix: apm framework not getting selected

* fix: apm framework not getting selected

* fix: apm framework not getting selected
This commit is contained in:
Vikrant Gupta 2024-03-07 14:23:28 +05:30 committed by GitHub
parent 7af4ba34af
commit 4cd40391c5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 131 additions and 41 deletions

View File

@ -4,6 +4,10 @@
"SERVICE_METRICS": "SigNoz | Service Metrics", "SERVICE_METRICS": "SigNoz | Service Metrics",
"SERVICE_MAP": "SigNoz | Service Map", "SERVICE_MAP": "SigNoz | Service Map",
"GET_STARTED": "SigNoz | Get Started", "GET_STARTED": "SigNoz | Get Started",
"GET_STARTED_APPLICATION_MONITORING": "SigNoz | Get Started | APM",
"GET_STARTED_LOGS_MANAGEMENT": "SigNoz | Get Started | Logs",
"GET_STARTED_INFRASTRUCTURE_MONITORING": "SigNoz | Get Started | Infrastructure",
"GET_STARTED_AWS_MONITORING": "SigNoz | Get Started | AWS",
"TRACE": "SigNoz | Trace", "TRACE": "SigNoz | Trace",
"TRACE_DETAIL": "SigNoz | Trace Detail", "TRACE_DETAIL": "SigNoz | Trace Detail",
"TRACES_EXPLORER": "SigNoz | Traces Explorer", "TRACES_EXPLORER": "SigNoz | Traces Explorer",

View File

@ -59,7 +59,7 @@ const routes: AppRoutes[] = [
}, },
{ {
path: ROUTES.GET_STARTED, path: ROUTES.GET_STARTED,
exact: true, exact: false,
component: Onboarding, component: Onboarding,
isPrivate: true, isPrivate: true,
key: 'GET_STARTED', key: 'GET_STARTED',

View File

@ -7,6 +7,11 @@ const ROUTES = {
TRACE_DETAIL: '/trace/:id', TRACE_DETAIL: '/trace/:id',
TRACES_EXPLORER: '/traces-explorer', TRACES_EXPLORER: '/traces-explorer',
GET_STARTED: '/get-started', GET_STARTED: '/get-started',
GET_STARTED_APPLICATION_MONITORING: '/get-started/application-monitoring',
GET_STARTED_LOGS_MANAGEMENT: '/get-started/logs-management',
GET_STARTED_INFRASTRUCTURE_MONITORING:
'/get-started/infrastructure-monitoring',
GET_STARTED_AWS_MONITORING: '/get-started/aws-monitoring',
USAGE_EXPLORER: '/usage-explorer', USAGE_EXPLORER: '/usage-explorer',
APPLICATION: '/services', APPLICATION: '/services',
ALL_DASHBOARD: '/dashboard', ALL_DASHBOARD: '/dashboard',

View File

@ -231,7 +231,12 @@ function AppLayout(props: AppLayoutProps): JSX.Element {
const routeKey = useMemo(() => getRouteKey(pathname), [pathname]); const routeKey = useMemo(() => getRouteKey(pathname), [pathname]);
const pageTitle = t(routeKey); const pageTitle = t(routeKey);
const renderFullScreen = const renderFullScreen =
pathname === ROUTES.GET_STARTED || pathname === ROUTES.WORKSPACE_LOCKED; pathname === ROUTES.GET_STARTED ||
pathname === ROUTES.WORKSPACE_LOCKED ||
pathname === ROUTES.GET_STARTED_APPLICATION_MONITORING ||
pathname === ROUTES.GET_STARTED_INFRASTRUCTURE_MONITORING ||
pathname === ROUTES.GET_STARTED_LOGS_MANAGEMENT ||
pathname === ROUTES.GET_STARTED_AWS_MONITORING;
const [showTrialExpiryBanner, setShowTrialExpiryBanner] = useState(false); const [showTrialExpiryBanner, setShowTrialExpiryBanner] = useState(false);

View File

@ -1,14 +1,34 @@
import './NoLogs.styles.scss'; import './NoLogs.styles.scss';
import { Typography } from 'antd'; import { Typography } from 'antd';
import ROUTES from 'constants/routes';
import history from 'lib/history';
import { ArrowUpRight } from 'lucide-react'; import { ArrowUpRight } from 'lucide-react';
import { DataSource } from 'types/common/queryBuilder'; import { DataSource } from 'types/common/queryBuilder';
import { isCloudUser } from 'utils/app';
export default function NoLogs({ export default function NoLogs({
dataSource, dataSource,
}: { }: {
dataSource: DataSource; dataSource: DataSource;
}): JSX.Element { }): JSX.Element {
const cloudUser = isCloudUser();
const handleLinkClick = (
e: React.MouseEvent<HTMLAnchorElement, MouseEvent>,
): void => {
e.preventDefault();
e.stopPropagation();
if (cloudUser) {
history.push(
dataSource === 'traces'
? ROUTES.GET_STARTED_APPLICATION_MONITORING
: ROUTES.GET_STARTED_LOGS_MANAGEMENT,
);
} else {
window.open(`https://signoz.io/docs/userguide/${dataSource}/`, '_blank');
}
};
return ( return (
<div className="no-logs-container"> <div className="no-logs-container">
<div className="no-logs-container-content"> <div className="no-logs-container-content">
@ -21,11 +41,7 @@ export default function NoLogs({
</span> </span>
</Typography> </Typography>
<Typography.Link <Typography.Link className="send-logs-link" onClick={handleLinkClick}>
className="send-logs-link"
href={`https://signoz.io/docs/userguide/${dataSource}/`}
target="_blank"
>
Sending {dataSource} to SigNoz <ArrowUpRight size={16} /> Sending {dataSource} to SigNoz <ArrowUpRight size={16} />
</Typography.Link> </Typography.Link>
</div> </div>

View File

@ -6,9 +6,11 @@ import { ArrowRightOutlined } from '@ant-design/icons';
import { Button, Card, Typography } from 'antd'; import { Button, Card, Typography } from 'antd';
import getIngestionData from 'api/settings/getIngestionData'; import getIngestionData from 'api/settings/getIngestionData';
import cx from 'classnames'; import cx from 'classnames';
import ROUTES from 'constants/routes';
import FullScreenHeader from 'container/FullScreenHeader/FullScreenHeader'; import FullScreenHeader from 'container/FullScreenHeader/FullScreenHeader';
import useAnalytics from 'hooks/analytics/useAnalytics'; import useAnalytics from 'hooks/analytics/useAnalytics';
import { useIsDarkMode } from 'hooks/useDarkMode'; import { useIsDarkMode } from 'hooks/useDarkMode';
import history from 'lib/history';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { useQuery } from 'react-query'; import { useQuery } from 'react-query';
import { useEffectOnce } from 'react-use'; import { useEffectOnce } from 'react-use';
@ -21,9 +23,11 @@ import {
} from './context/OnboardingContext'; } from './context/OnboardingContext';
import { DataSourceType } from './Steps/DataSource/DataSource'; import { DataSourceType } from './Steps/DataSource/DataSource';
import { import {
defaultApplicationDataSource,
defaultAwsServices, defaultAwsServices,
defaultInfraMetricsType, defaultInfraMetricsType,
defaultLogsType, defaultLogsType,
moduleRouteMap,
} from './utils/dataSourceUtils'; } from './utils/dataSourceUtils';
import { import {
APM_STEPS, APM_STEPS,
@ -89,6 +93,7 @@ export default function Onboarding(): JSX.Element {
const [current, setCurrent] = useState(0); const [current, setCurrent] = useState(0);
const isDarkMode = useIsDarkMode(); const isDarkMode = useIsDarkMode();
const { trackEvent } = useAnalytics(); const { trackEvent } = useAnalytics();
const { location } = history;
const { const {
selectedDataSource, selectedDataSource,
@ -191,12 +196,13 @@ export default function Onboarding(): JSX.Element {
} }
} else if (selectedModule?.id === ModulesMap.APM) { } else if (selectedModule?.id === ModulesMap.APM) {
handleAPMSteps(); handleAPMSteps();
updateSelectedDataSource(defaultApplicationDataSource);
} }
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedModule, selectedDataSource, selectedEnvironment, selectedMethod]); }, [selectedModule, selectedDataSource, selectedEnvironment, selectedMethod]);
const handleNext = (): void => { const handleNextStep = (): void => {
if (activeStep <= 3) { if (activeStep <= 3) {
const nextStep = activeStep + 1; const nextStep = activeStep + 1;
@ -217,12 +223,36 @@ export default function Onboarding(): JSX.Element {
} }
}; };
const handleNext = (): void => {
if (activeStep <= 3) {
handleNextStep();
history.replace(moduleRouteMap[selectedModule.id as ModulesMap]);
}
};
const handleModuleSelect = (module: ModuleProps): void => { const handleModuleSelect = (module: ModuleProps): void => {
setSelectedModule(module); setSelectedModule(module);
updateSelectedModule(module); updateSelectedModule(module);
updateSelectedDataSource(null); updateSelectedDataSource(null);
}; };
useEffect(() => {
if (location.pathname === ROUTES.GET_STARTED_APPLICATION_MONITORING) {
handleModuleSelect(useCases.APM);
updateSelectedDataSource(defaultApplicationDataSource);
handleNextStep();
} else if (
location.pathname === ROUTES.GET_STARTED_INFRASTRUCTURE_MONITORING
) {
handleModuleSelect(useCases.InfrastructureMonitoring);
handleNextStep();
} else if (location.pathname === ROUTES.GET_STARTED_LOGS_MANAGEMENT) {
handleModuleSelect(useCases.LogsManagement);
handleNextStep();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return ( return (
<div className={cx('container', isDarkMode ? 'darkMode' : 'lightMode')}> <div className={cx('container', isDarkMode ? 'darkMode' : 'lightMode')}>
{activeStep === 1 && ( {activeStep === 1 && (
@ -285,6 +315,7 @@ export default function Onboarding(): JSX.Element {
setActiveStep(activeStep - 1); setActiveStep(activeStep - 1);
setSelectedModule(useCases.APM); setSelectedModule(useCases.APM);
resetProgress(); resetProgress();
history.push(ROUTES.GET_STARTED);
}} }}
selectedModule={selectedModule} selectedModule={selectedModule}
selectedModuleSteps={selectedModuleSteps} selectedModuleSteps={selectedModuleSteps}

View File

@ -1,6 +1,15 @@
import { ModuleProps, ModulesMap } from '../OnboardingContainer'; import ROUTES from 'constants/routes';
import { ModuleProps } from '../OnboardingContainer';
import { DataSourceType } from '../Steps/DataSource/DataSource'; import { DataSourceType } from '../Steps/DataSource/DataSource';
export enum ModulesMap {
APM = 'APM',
LogsManagement = 'LogsManagement',
InfrastructureMonitoring = 'InfrastructureMonitoring',
AwsMonitoring = 'AwsMonitoring',
}
export const frameworksMap = { export const frameworksMap = {
APM: { APM: {
java: [ java: [
@ -81,174 +90,174 @@ const supportedLanguages = [
{ {
name: 'java', name: 'java',
id: 'java', id: 'java',
imgURL: `Logos/java.png`, imgURL: `/Logos/java.png`,
}, },
{ {
name: 'python', name: 'python',
id: 'python', id: 'python',
imgURL: `Logos/python.png`, imgURL: `/Logos/python.png`,
}, },
{ {
name: 'go', name: 'go',
id: 'go', id: 'go',
imgURL: `Logos/go.png`, imgURL: `/Logos/go.png`,
}, },
{ {
name: 'javascript', name: 'javascript',
id: 'javascript', id: 'javascript',
imgURL: `Logos/javascript.png`, imgURL: `/Logos/javascript.png`,
}, },
{ {
name: 'rails', name: 'rails',
id: 'rails', id: 'rails',
imgURL: `Logos/rails.png`, imgURL: `/Logos/rails.png`,
}, },
{ {
name: '.NET', name: '.NET',
id: 'dotnet', id: 'dotnet',
imgURL: `Logos/dotnet.png`, imgURL: `/Logos/dotnet.png`,
}, },
{ {
name: 'rust', name: 'rust',
id: 'rust', id: 'rust',
imgURL: `Logos/rust.png`, imgURL: `/Logos/rust.png`,
}, },
{ {
name: 'elixir', name: 'elixir',
id: 'elixir', id: 'elixir',
imgURL: `Logos/elixir.png`, imgURL: `/Logos/elixir.png`,
}, },
{ {
name: 'swift', name: 'swift',
id: 'swift', id: 'swift',
imgURL: `Logos/swift.png`, imgURL: `/Logos/swift.png`,
}, },
]; ];
export const defaultLogsType = { export const defaultLogsType = {
name: 'Kubernetes Pod Logs', name: 'Kubernetes Pod Logs',
id: 'kubernetes', id: 'kubernetes',
imgURL: `Logos/kubernetes.svg`, imgURL: `/Logos/kubernetes.svg`,
}; };
const supportedLogsTypes = [ const supportedLogsTypes = [
{ {
name: 'Kubernetes Pod Logs', name: 'Kubernetes Pod Logs',
id: 'kubernetes', id: 'kubernetes',
imgURL: `Logos/kubernetes.svg`, imgURL: `/Logos/kubernetes.svg`,
}, },
{ {
name: 'Docker Container Logs', name: 'Docker Container Logs',
id: 'docker', id: 'docker',
imgURL: `Logos/docker.svg`, imgURL: `/Logos/docker.svg`,
}, },
{ {
name: 'SysLogs', name: 'SysLogs',
id: 'syslogs', id: 'syslogs',
imgURL: `Logos/syslogs.svg`, imgURL: `/Logos/syslogs.svg`,
}, },
{ {
name: 'Application Logs', name: 'Application Logs',
id: 'application_logs', id: 'application_logs',
imgURL: `Logos/software-window.svg`, imgURL: `/Logos/software-window.svg`,
}, },
{ {
name: 'FluentBit', name: 'FluentBit',
id: 'fluentBit', id: 'fluentBit',
imgURL: `Logos/fluent-bit.png`, imgURL: `/Logos/fluent-bit.png`,
}, },
{ {
name: 'FluentD', name: 'FluentD',
id: 'fluentD', id: 'fluentD',
imgURL: `Logos/fluentd.png`, imgURL: `/Logos/fluentd.png`,
}, },
{ {
name: 'LogStash', name: 'LogStash',
id: 'logStash', id: 'logStash',
imgURL: `Logos/logstash.svg`, imgURL: `/Logos/logstash.svg`,
}, },
{ {
name: 'Heroku', name: 'Heroku',
id: 'heroku', id: 'heroku',
imgURL: `Logos/heroku.png`, imgURL: `/Logos/heroku.png`,
}, },
{ {
name: 'Vercel', name: 'Vercel',
id: 'vercel', id: 'vercel',
imgURL: `Logos/vercel.png`, imgURL: `/Logos/vercel.png`,
}, },
{ {
name: 'HTTP', name: 'HTTP',
id: 'http', id: 'http',
imgURL: `Logos/http.png`, imgURL: `/Logos/http.png`,
}, },
{ {
name: 'Cloudwatch', name: 'Cloudwatch',
id: 'cloudwatch', id: 'cloudwatch',
imgURL: `Logos/cloudwatch.png`, imgURL: `/Logos/cloudwatch.png`,
}, },
]; ];
export const defaultInfraMetricsType = { export const defaultInfraMetricsType = {
name: 'Kubernetes Infra Metrics', name: 'Kubernetes Infra Metrics',
id: 'kubernetesInfraMetrics', id: 'kubernetesInfraMetrics',
imgURL: `Logos/kubernetes.svg`, imgURL: `/Logos/kubernetes.svg`,
}; };
const supportedInfraMetrics = [ const supportedInfraMetrics = [
{ {
name: 'Kubernetes Infra Metrics', name: 'Kubernetes Infra Metrics',
id: 'kubernetesInfraMetrics', id: 'kubernetesInfraMetrics',
imgURL: `Logos/kubernetes.svg`, imgURL: `/Logos/kubernetes.svg`,
}, },
{ {
name: 'HostMetrics', name: 'HostMetrics',
id: 'hostMetrics', id: 'hostMetrics',
imgURL: `Logos/software-window.svg`, imgURL: `/Logos/software-window.svg`,
}, },
{ {
name: 'Other Metrics', name: 'Other Metrics',
id: 'otherMetrics', id: 'otherMetrics',
imgURL: `Logos/cmd-terminal.svg`, imgURL: `/Logos/cmd-terminal.svg`,
}, },
]; ];
export const defaultAwsServices = { export const defaultAwsServices = {
name: 'EC2 - Application Logs', name: 'EC2 - Application Logs',
id: 'awsEc2ApplicationLogs', id: 'awsEc2ApplicationLogs',
imgURL: `Logos/ec2.svg`, imgURL: `/Logos/ec2.svg`,
}; };
const supportedAwsServices = [ const supportedAwsServices = [
{ {
name: 'EC2 - App/Server Logs', name: 'EC2 - App/Server Logs',
id: 'awsEc2ApplicationLogs', id: 'awsEc2ApplicationLogs',
imgURL: `Logos/ec2.svg`, imgURL: `/Logos/ec2.svg`,
}, },
{ {
name: 'EC2 - Infra Metrics', name: 'EC2 - Infra Metrics',
id: 'awsEc2InfrastructureMetrics', id: 'awsEc2InfrastructureMetrics',
imgURL: `Logos/ec2.svg`, imgURL: `/Logos/ec2.svg`,
}, },
{ {
name: 'ECS - EC2', name: 'ECS - EC2',
id: 'awsEcsEc2', id: 'awsEcsEc2',
imgURL: `Logos/ecs.svg`, imgURL: `/Logos/ecs.svg`,
}, },
{ {
name: 'ECS - Fargate', name: 'ECS - Fargate',
id: 'awsEcsFargate', id: 'awsEcsFargate',
imgURL: `Logos/ecs.svg`, imgURL: `/Logos/ecs.svg`,
}, },
{ {
name: 'ECS - External', name: 'ECS - External',
id: 'awsEcsExternal', id: 'awsEcsExternal',
imgURL: `Logos/ecs.svg`, imgURL: `/Logos/ecs.svg`,
}, },
{ {
name: 'EKS', name: 'EKS',
id: 'awsEks', id: 'awsEks',
imgURL: `Logos/eks.svg`, imgURL: `/Logos/eks.svg`,
}, },
]; ];
@ -320,3 +329,11 @@ export const hasFrameworks = ({
return true; return true;
}; };
export const moduleRouteMap = {
[ModulesMap.APM]: ROUTES.GET_STARTED_APPLICATION_MONITORING,
[ModulesMap.LogsManagement]: ROUTES.GET_STARTED_LOGS_MANAGEMENT,
[ModulesMap.InfrastructureMonitoring]:
ROUTES.GET_STARTED_INFRASTRUCTURE_MONITORING,
[ModulesMap.AwsMonitoring]: ROUTES.GET_STARTED_AWS_MONITORING,
};

View File

@ -81,6 +81,10 @@ export const routesToSkip = [
ROUTES.ALL_CHANNELS, ROUTES.ALL_CHANNELS,
ROUTES.USAGE_EXPLORER, ROUTES.USAGE_EXPLORER,
ROUTES.GET_STARTED, ROUTES.GET_STARTED,
ROUTES.GET_STARTED_APPLICATION_MONITORING,
ROUTES.GET_STARTED_INFRASTRUCTURE_MONITORING,
ROUTES.GET_STARTED_LOGS_MANAGEMENT,
ROUTES.GET_STARTED_AWS_MONITORING,
ROUTES.VERSION, ROUTES.VERSION,
ROUTES.ALL_DASHBOARD, ROUTES.ALL_DASHBOARD,
ROUTES.ORG_SETTINGS, ROUTES.ORG_SETTINGS,

View File

@ -117,6 +117,10 @@ export const routesToSkip = [
ROUTES.ALL_CHANNELS, ROUTES.ALL_CHANNELS,
ROUTES.USAGE_EXPLORER, ROUTES.USAGE_EXPLORER,
ROUTES.GET_STARTED, ROUTES.GET_STARTED,
ROUTES.GET_STARTED_APPLICATION_MONITORING,
ROUTES.GET_STARTED_INFRASTRUCTURE_MONITORING,
ROUTES.GET_STARTED_LOGS_MANAGEMENT,
ROUTES.GET_STARTED_AWS_MONITORING,
ROUTES.VERSION, ROUTES.VERSION,
ROUTES.ALL_DASHBOARD, ROUTES.ALL_DASHBOARD,
ROUTES.ORG_SETTINGS, ROUTES.ORG_SETTINGS,

View File

@ -82,6 +82,10 @@ export const routePermission: Record<keyof typeof ROUTES, ROLES[]> = {
LOGS_PIPELINES: ['ADMIN', 'EDITOR', 'VIEWER'], LOGS_PIPELINES: ['ADMIN', 'EDITOR', 'VIEWER'],
TRACE_EXPLORER: ['ADMIN', 'EDITOR', 'VIEWER'], TRACE_EXPLORER: ['ADMIN', 'EDITOR', 'VIEWER'],
GET_STARTED: ['ADMIN', 'EDITOR', 'VIEWER'], GET_STARTED: ['ADMIN', 'EDITOR', 'VIEWER'],
GET_STARTED_APPLICATION_MONITORING: ['ADMIN', 'EDITOR', 'VIEWER'],
GET_STARTED_INFRASTRUCTURE_MONITORING: ['ADMIN', 'EDITOR', 'VIEWER'],
GET_STARTED_LOGS_MANAGEMENT: ['ADMIN', 'EDITOR', 'VIEWER'],
GET_STARTED_AWS_MONITORING: ['ADMIN', 'EDITOR', 'VIEWER'],
WORKSPACE_LOCKED: ['ADMIN', 'EDITOR', 'VIEWER'], WORKSPACE_LOCKED: ['ADMIN', 'EDITOR', 'VIEWER'],
BILLING: ['ADMIN', 'EDITOR', 'VIEWER'], BILLING: ['ADMIN', 'EDITOR', 'VIEWER'],
SUPPORT: ['ADMIN', 'EDITOR', 'VIEWER'], SUPPORT: ['ADMIN', 'EDITOR', 'VIEWER'],