import {Fragment, useCallback, useEffect, useMemo, useState} from 'react';
import {browserHistory} from 'react-router';
import styled from '@emotion/styled';
import {motion} from 'framer-motion';
import {loadDocs} from 'sentry/actionCreators/projects';
import {Alert} from 'sentry/components/alert';
import LoadingError from 'sentry/components/loadingError';
import {DocumentationWrapper} from 'sentry/components/onboarding/documentationWrapper';
import {
migratedDocs,
SdkDocumentation,
} from 'sentry/components/onboarding/gettingStartedDoc/sdkDocumentation';
import {MissingExampleWarning} from 'sentry/components/onboarding/missingExampleWarning';
import {ProductSolution} from 'sentry/components/onboarding/productSelection';
import {PlatformKey} from 'sentry/data/platformCategories';
import platforms from 'sentry/data/platforms';
import {t} from 'sentry/locale';
import {space} from 'sentry/styles/space';
import {Organization, Project} from 'sentry/types';
import {OnboardingPlatformDoc} from 'sentry/types/onboarding';
import {trackAnalytics} from 'sentry/utils/analytics';
import getDynamicText from 'sentry/utils/getDynamicText';
import {platformToIntegrationMap} from 'sentry/utils/integrationUtil';
import useApi from 'sentry/utils/useApi';
import useOrganization from 'sentry/utils/useOrganization';
import SetupIntroduction from 'sentry/views/onboarding/components/setupIntroduction';
import {SetupDocsLoader} from 'sentry/views/onboarding/setupDocsLoader';
import FirstEventFooter from './components/firstEventFooter';
import IntegrationSetup from './integrationSetup';
import {StepProps} from './types';
function ProjectDocs(props: {
hasError: boolean;
onRetry: () => void;
organization: Organization;
platform: PlatformKey | null;
platformDocs: OnboardingPlatformDoc | null;
project: Project;
}) {
const currentPlatform = props.platform ?? props.project?.platform ?? 'other';
return (
p.id === currentPlatform)?.name ?? ''
)}
platform={currentPlatform}
/>
{getDynamicText({
value: !props.hasError ? (
props.platformDocs !== null && (
)
) : (
),
fixed: (
Platform documentation is not rendered in for tests in CI
),
})}
);
}
function SetupDocs({location, recentCreatedProject: project}: StepProps) {
const api = useApi();
const organization = useOrganization();
const products = useMemo(
() => (location.query.product ?? []) as ProductSolution[],
[location.query.product]
);
// SDK instrumentation
const [hasError, setHasError] = useState(false);
const [platformDocs, setPlatformDocs] = useState(null);
const [loadedPlatform, setLoadedPlatform] = useState(null);
const currentPlatformKey = loadedPlatform ?? project?.platform ?? 'other';
const [showLoaderOnboarding, setShowLoaderOnboarding] = useState(
currentPlatformKey === 'javascript'
);
useEffect(() => {
setShowLoaderOnboarding(currentPlatformKey === 'javascript');
}, [currentPlatformKey]);
const integrationSlug = project?.platform && platformToIntegrationMap[project.platform];
const [integrationUseManualSetup, setIntegrationUseManualSetup] = useState(false);
const showIntegrationOnboarding = integrationSlug && !integrationUseManualSetup;
const showDocsWithProductSelection =
currentPlatformKey.match('^javascript-([A-Za-z]+)$') ??
(showLoaderOnboarding === false && currentPlatformKey === 'javascript');
const hideLoaderOnboarding = useCallback(() => {
setShowLoaderOnboarding(false);
if (!project?.id) {
return;
}
trackAnalytics('onboarding.js_loader_npm_docs_shown', {
organization,
platform: currentPlatformKey,
project_id: project?.id,
});
}, [organization, currentPlatformKey, project?.id]);
const fetchData = useCallback(async () => {
// TODO: add better error handling logic
if (!project?.platform) {
return;
}
// this will be fetched in the DocWithProductSelection component
if (showDocsWithProductSelection) {
return;
}
// Show loader setup for base javascript platform
if (showLoaderOnboarding) {
return;
}
if (showIntegrationOnboarding) {
setLoadedPlatform(project.platform);
setPlatformDocs(null);
setHasError(false);
return;
}
// There are no docs for the other platform
if (project.platform === 'other') {
return;
}
try {
const loadedDocs = await loadDocs({
api,
orgSlug: organization.slug,
projectSlug: project.slug,
platform: project.platform as PlatformKey,
});
setPlatformDocs(loadedDocs);
setLoadedPlatform(project.platform);
setHasError(false);
} catch (error) {
setHasError(error);
throw error;
}
}, [
project?.slug,
project?.platform,
api,
organization.slug,
showDocsWithProductSelection,
showIntegrationOnboarding,
showLoaderOnboarding,
]);
useEffect(() => {
fetchData();
}, [fetchData, location.query.product, project?.platform]);
if (!project) {
return null;
}
const currentPlatform = platforms.find(p => p.id === currentPlatformKey);
const platformName = currentPlatform?.name ?? '';
const loadLocalSdkDocumentation =
currentPlatform && migratedDocs.includes(currentPlatformKey);
return (
{showIntegrationOnboarding ? (
{
setIntegrationUseManualSetup(true);
}}
/>
) : showLoaderOnboarding ? (
p.id === currentPlatformKey)?.name ?? ''
)}
platform={currentPlatformKey}
/>
) : loadLocalSdkDocumentation ? (
) : (
)}
{
const orgIssuesURL = `/organizations/${organization.slug}/issues/?project=${project.id}&referrer=onboarding-setup-docs`;
trackAnalytics('growth.onboarding_clicked_setup_platform_later', {
organization,
platform: currentPlatformKey,
project_id: project.id,
});
browserHistory.push(orgIssuesURL);
}}
/>
);
}
export default SetupDocs;
const AnimatedContentWrapper = styled(motion.div)`
overflow: hidden;
`;
AnimatedContentWrapper.defaultProps = {
initial: {
height: 0,
},
animate: {
height: 'auto',
},
exit: {
height: 0,
},
};
const DocsWrapper = styled(motion.div)``;
DocsWrapper.defaultProps = {
initial: {opacity: 0, y: 40},
animate: {opacity: 1, y: 0},
exit: {opacity: 0},
};
const Wrapper = styled('div')`
display: flex;
flex-direction: row;
margin: ${space(2)};
justify-content: center;
`;
const MainContent = styled('div')`
max-width: 850px;
min-width: 0;
flex-grow: 1;
`;