remove unused CTAs (#63512)

These CTAs are all inaccessible on dotcom anyway and would never show
up.


## Test plan

Visit pages where CTAs were deleted and ensure they work.
This commit is contained in:
Quinn Slack 2024-06-27 01:43:47 -07:00 committed by GitHub
parent 7e7de5ffb1
commit 4767166e1e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 30 additions and 899 deletions

View File

@ -304,7 +304,6 @@ ts_project(
"src/components/AwayPrompt.tsx",
"src/components/Breadcrumbs.tsx",
"src/components/Byline/CreatedByAndUpdatedByInfoByline.tsx",
"src/components/CallToActionBanner.tsx",
"src/components/CircleDashedIcon.tsx",
"src/components/Collapsible.tsx",
"src/components/ComponentsComposer.tsx",
@ -747,7 +746,6 @@ ts_project(
"src/enterprise/executors/secrets/backend.ts",
"src/enterprise/insights/CodeInsightsAppRouter.tsx",
"src/enterprise/insights/CodeInsightsBackendStoryMock.tsx",
"src/enterprise/insights/CodeInsightsRouter.tsx",
"src/enterprise/insights/admin-ui/CodeInsightsJobs.tsx",
"src/enterprise/insights/admin-ui/components/job-actions/CodeInsightsJobsActions.tsx",
"src/enterprise/insights/admin-ui/components/job-actions/index.ts",
@ -889,7 +887,6 @@ ts_project(
"src/enterprise/insights/hooks/use-query-parameters.ts",
"src/enterprise/insights/hooks/use-remove-insight.ts",
"src/enterprise/insights/hooks/use-ui-features.ts",
"src/enterprise/insights/index.ts",
"src/enterprise/insights/modals/GaConfirmationModal.tsx",
"src/enterprise/insights/modals/components/MediaCharts.tsx",
"src/enterprise/insights/pages/CodeInsightsRootPage.tsx",
@ -974,10 +971,6 @@ ts_project(
"src/enterprise/insights/pages/insights/insight/components/standalone-backend-insight/StandaloneBackendInsight.tsx",
"src/enterprise/insights/pages/insights/insight/components/standalone-lang-stats-insight/StandaloneLangStatsInsight.tsx",
"src/enterprise/insights/pages/landing/CodeInsightsLandingPageContext.tsx",
"src/enterprise/insights/pages/landing/dot-com-get-started/CodeInsightsDotComGetStarted.tsx",
"src/enterprise/insights/pages/landing/dot-com-get-started/components/code-insights-examples-picker/CodeInsightsExamplesPicker.tsx",
"src/enterprise/insights/pages/landing/dot-com-get-started/components/code-insights-examples-picker/code-insights-examples-slider/CodeInsightsExamplesSlider.tsx",
"src/enterprise/insights/pages/landing/dot-com-get-started/components/code-insights-examples-picker/examples.ts",
"src/enterprise/insights/pages/landing/getting-started/CodeInsightsGettingStartedPage.tsx",
"src/enterprise/insights/pages/landing/getting-started/components/code-insights-description/CodeInsightsDescription.tsx",
"src/enterprise/insights/pages/landing/getting-started/components/code-insights-examples/CodeInsightsExamples.tsx",
@ -2355,8 +2348,6 @@ ts_project(
"src/enterprise/insights/pages/insights/creation/lang-stats/LangStatsInsightCreationPage.story.tsx",
"src/enterprise/insights/pages/insights/creation/search-insight/SearchInsightCreationPage.story.tsx",
"src/enterprise/insights/pages/insights/insight/components/standalone-404-insight/Standalone404Insight.story.tsx",
"src/enterprise/insights/pages/landing/dot-com-get-started/CodeInsightsDotComGetStarted.story.tsx",
"src/enterprise/insights/pages/landing/dot-com-get-started/components/code-insights-examples-picker/code-insights-examples-slider/CodeInsightsExamplesSlider.story.tsx",
"src/enterprise/insights/pages/landing/getting-started/CodeInsightsGettingStartedPage.story.tsx",
"src/enterprise/insights/pages/landing/getting-started/components/code-insights-examples/CodeInsightsExamples.story.tsx",
"src/enterprise/own/RepositoryOwnEditPage.story.tsx",

View File

@ -1,20 +0,0 @@
.filled {
background-color: var(--primary-4);
border-radius: var(--border-radius);
margin: 1rem 0;
padding: 0.313rem 1.125rem;
}
.outlined {
background-color: var(--color-bg-1);
border: 1px solid var(--border-color);
border-radius: var(--border-radius);
margin-bottom: 0.5rem;
padding: 0.25rem 0.5rem;
}
.underlined {
background: linear-gradient(to left, var(--blue) 0%, var(--purple) 100%) left bottom no-repeat;
background-size: 100% 1px;
padding: 0.375rem 0.5rem;
}

View File

@ -1,31 +0,0 @@
import type { FunctionComponent, ReactNode } from 'react'
import { mdiArrowRight } from '@mdi/js'
import classNames from 'classnames'
import { Icon, Text } from '@sourcegraph/wildcard'
import styles from './CallToActionBanner.module.scss'
export interface CloudCtaBanner {
variant?: 'filled' | 'outlined' | 'underlined' | string | undefined
small?: boolean
className?: string
children: ReactNode
}
export const CallToActionBanner: FunctionComponent<CloudCtaBanner> = ({ variant, small, className, children }) => (
<section
className={classNames(className, 'd-flex justify-content-center', {
[styles.filled]: variant === 'filled',
[styles.outlined]: variant === 'outlined',
[styles.underlined]: variant === 'underlined',
})}
>
<Icon className="mr-2 text-merged" size={small ? 'sm' : 'md'} aria-hidden={true} svgPath={mdiArrowRight} />
<Text size={small ? 'small' : 'base'} className="my-auto">
{children}
</Text>
</section>
)

View File

@ -3,11 +3,9 @@ import React from 'react'
import { mdiOpenInNew } from '@mdi/js'
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
import { Alert, Container, H2, H3, Link, Text, Icon, useReducedMotion } from '@sourcegraph/wildcard'
import { Alert, Container, H2, H3, Icon, Link, Text, useReducedMotion } from '@sourcegraph/wildcard'
import { BatchChangesIcon } from '../../../batches/icons'
import { CallToActionBanner } from '../../../components/CallToActionBanner'
import { CtaBanner } from '../../../components/CtaBanner'
export interface GettingStartedProps extends TelemetryV2Props {
@ -93,33 +91,15 @@ export const GettingStarted: React.FunctionComponent<React.PropsWithChildren<Get
</div>
</div>
</Container>
{isSourcegraphDotCom ? (
<CallToActionBanner variant="filled">
To automate changes across your team's private repositories,{' '}
<Link
to="https://sourcegraph.com"
onClick={() => {
EVENT_LOGGER.log('ClickedOnEnterpriseCTA', { location: 'BatchChangesGettingStarted' })
telemetryRecorder.recordEvent('batchChanges.enterpriseCTA', 'click', {
metadata: { location: 1 },
})
}}
>
get Sourcegraph Enterprise
</Link>
.
</CallToActionBanner>
) : (
<div className="d-flex justify-content-start">
<CtaBanner
bodyText="Try it yourself in less than 10 minutes (without actually pushing changes)."
title={<H3>Start using Batch Changes</H3>}
linkText="Read quickstart docs"
href="/help/batch_changes/quickstart"
icon={<BatchChangesIcon />}
/>
</div>
)}
<div className="d-flex justify-content-start">
<CtaBanner
bodyText="Try it yourself in less than 10 minutes (without actually pushing changes)."
title={<H3>Start using Batch Changes</H3>}
linkText="Read quickstart docs"
href="/help/batch_changes/quickstart"
icon={<BatchChangesIcon />}
/>
</div>
</div>
)
}

View File

@ -4,11 +4,9 @@ import { useLocation } from 'react-router-dom'
import { of } from 'rxjs'
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
import { Container, Link, H2, H3 } from '@sourcegraph/wildcard'
import { Container, H2, H3 } from '@sourcegraph/wildcard'
import type { AuthenticatedUser } from '../../auth'
import { CallToActionBanner } from '../../components/CallToActionBanner'
import { FilteredConnection } from '../../components/FilteredConnection'
import type {
CodeMonitorFields,
@ -40,10 +38,8 @@ export const CodeMonitorList: React.FunctionComponent<React.PropsWithChildren<Co
fetchUserCodeMonitors,
fetchCodeMonitors,
toggleCodeMonitorEnabled,
telemetryRecorder,
}) => {
const location = useLocation()
const isSourcegraphDotCom: boolean = window.context?.sourcegraphDotComMode || false
const queryConnection = useCallback(
(args: Partial<ListUserCodeMonitorsVariables>) => {
@ -79,23 +75,6 @@ export const CodeMonitorList: React.FunctionComponent<React.PropsWithChildren<Co
<div className="d-flex flex-column w-100 col">
<div className="d-flex align-items-center justify-content-between">
<H3 className="mb-2">Your code monitors</H3>
{isSourcegraphDotCom && (
<CallToActionBanner variant="outlined" small={true}>
To monitor changes across your private repositories,{' '}
<Link
to="https://sourcegraph.com"
onClick={() => {
EVENT_LOGGER.log('ClickedOnEnterpriseCTA', { location: 'Monitoring' })
telemetryRecorder.recordEvent('codeMonitor.enterpriseCTA', 'click', {
metadata: { location: 1 },
})
}}
>
get Sourcegraph Enterprise
</Link>
.
</CallToActionBanner>
)}
</div>
<Container className="py-3">
<FilteredConnection<

View File

@ -7,9 +7,7 @@ import type { AuthenticatedUser } from '@sourcegraph/shared/src/auth'
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
import { useIsLightTheme } from '@sourcegraph/shared/src/theme'
import { Link, Button, CardBody, Card, Icon, H2, H3, H4, Text } from '@sourcegraph/wildcard'
import { CallToActionBanner } from '../../components/CallToActionBanner'
import { Button, Card, CardBody, H2, H3, H4, Icon, Link, Text } from '@sourcegraph/wildcard'
import styles from './CodeMonitoringGettingStarted.module.scss'
@ -68,7 +66,6 @@ export const CodeMonitoringGettingStarted: React.FunctionComponent<
React.PropsWithChildren<CodeMonitoringGettingStartedProps>
> = ({ authenticatedUser, telemetryRecorder }) => {
const isLightTheme = useIsLightTheme()
const isSourcegraphDotCom: boolean = window.context?.sourcegraphDotComMode || false
const assetsRoot = window.context?.assetsRoot || ''
const logExampleMonitorClicked = useCallback(() => {
@ -76,8 +73,6 @@ export const CodeMonitoringGettingStarted: React.FunctionComponent<
telemetryRecorder.recordEvent('codeMonitor.example', 'click')
}, [telemetryRecorder])
const ctaBannerUrl = 'https://sourcegraph.com/get-started?t=enterprise'
return (
<div>
<Card className={classNames('mb-4 flex-column flex-lg-row', styles.hero)}>
@ -107,27 +102,8 @@ export const CodeMonitoringGettingStarted: React.FunctionComponent<
</div>
</Card>
{isSourcegraphDotCom && (
<CallToActionBanner variant="filled">
To monitor changes across your team's private repositories,{' '}
<Link
to={ctaBannerUrl}
onClick={() => {
EVENT_LOGGER.log('ClickedOnEnterpriseCTA', { location: 'MonitoringGettingStarted' })
telemetryRecorder.recordEvent('codeMonitor.enterpriseCTA', 'click', {
metadata: { location: 0 },
})
}}
>
get Sourcegraph Enterprise
</Link>
.
</CallToActionBanner>
)}
<div>
<H3 className="mb-3">Example code monitors</H3>
<div className={classNames('mb-3', styles.startingPointsContainer)}>
{exampleCodeMonitors.map(monitor => (
<div className={styles.startingPoint} key={monitor.title}>

View File

@ -1,41 +0,0 @@
import type { FC } from 'react'
import { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
import type { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService'
import { lazyComponent } from '@sourcegraph/shared/src/util/lazyComponent'
import type { AuthenticatedUser } from '../../auth'
const CodeInsightsAppLazyRouter = lazyComponent(() => import('./CodeInsightsAppRouter'), 'CodeInsightsAppRouter')
const CodeInsightsDotComGetStartedLazy = lazyComponent(
() => import('./pages/landing/dot-com-get-started/CodeInsightsDotComGetStarted'),
'CodeInsightsDotComGetStarted'
)
export interface CodeInsightsRouterProps extends TelemetryProps, TelemetryV2Props {
authenticatedUser: AuthenticatedUser | null
isSourcegraphDotCom: boolean
}
export const CodeInsightsRouter: FC<CodeInsightsRouterProps> = props => {
const { authenticatedUser, telemetryService, telemetryRecorder } = props
if (!window.context?.codeInsightsEnabled) {
return (
<CodeInsightsDotComGetStartedLazy
telemetryService={telemetryService}
authenticatedUser={authenticatedUser}
telemetryRecorder={telemetryRecorder}
/>
)
}
return (
<CodeInsightsAppLazyRouter
authenticatedUser={authenticatedUser}
telemetryService={telemetryService}
telemetryRecorder={telemetryRecorder}
/>
)
}

View File

@ -1,2 +0,0 @@
// Public Insights components
export { CodeInsightsRouter } from './CodeInsightsRouter'

View File

@ -1,19 +0,0 @@
.hero-section {
display: flex;
flex-wrap: wrap;
// Override card default styles with flex-direction: column;
flex-direction: row;
padding: 1.5rem;
gap: 1.5rem;
margin-bottom: 1rem;
}
.hero-video-block {
flex-grow: 10;
flex-basis: 30rem;
}
.hero-description-block {
flex-grow: 1;
flex-basis: 25rem;
}

View File

@ -1,23 +0,0 @@
import type { Meta } from '@storybook/react'
import { noOpTelemetryRecorder } from '@sourcegraph/shared/src/telemetry'
import { NOOP_TELEMETRY_SERVICE } from '@sourcegraph/shared/src/telemetry/telemetryService'
import { WebStory } from '../../../../../components/WebStory'
import { CodeInsightsDotComGetStarted } from './CodeInsightsDotComGetStarted'
const meta: Meta = {
title: 'web/insights/dot-com-landing/CodeInsightsDotComGetStarted',
decorators: [story => <WebStory>{() => story()}</WebStory>],
}
export default meta
export const CodeInsightsDotComGetStartedStory = () => (
<CodeInsightsDotComGetStarted
telemetryService={NOOP_TELEMETRY_SERVICE}
authenticatedUser={null}
telemetryRecorder={noOpTelemetryRecorder}
/>
)

View File

@ -1,115 +0,0 @@
import React, { useEffect } from 'react'
import classNames from 'classnames'
import type { AuthenticatedUser } from '@sourcegraph/shared/src/auth'
import { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
import type { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService'
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
import { Button, Card, CardBody, Link, PageHeader } from '@sourcegraph/wildcard'
import { CallToActionBanner } from '../../../../../components/CallToActionBanner'
import { Page } from '../../../../../components/Page'
import { PageTitle } from '../../../../../components/PageTitle'
import { CodeInsightsIcon } from '../../../../../insights/Icons'
import { CodeInsightsLandingPageContext, CodeInsightsLandingPageType } from '../CodeInsightsLandingPageContext'
import { CodeInsightsDescription } from '../getting-started/components/code-insights-description/CodeInsightsDescription'
import { CodeInsightsExamplesPicker } from './components/code-insights-examples-picker/CodeInsightsExamplesPicker'
import styles from './CodeInsightsDotComGetStarted.module.scss'
const DOT_COM_CONTEXT = { mode: CodeInsightsLandingPageType.Cloud }
export interface CodeInsightsDotComGetStartedProps extends TelemetryProps, TelemetryV2Props {
authenticatedUser: AuthenticatedUser | null
}
export const CodeInsightsDotComGetStarted: React.FunctionComponent<
React.PropsWithChildren<CodeInsightsDotComGetStartedProps>
> = props => {
const { telemetryService, telemetryRecorder } = props
const isSourcegraphDotCom = window.context.sourcegraphDotComMode
useEffect(() => {
telemetryService.logViewEvent('CloudInsightsGetStartedPage')
telemetryRecorder.recordEvent('cloudInsights.getStarted', 'view')
}, [telemetryService, telemetryRecorder])
return (
<CodeInsightsLandingPageContext.Provider value={DOT_COM_CONTEXT}>
<Page>
<PageTitle title="Code Insights" />
<PageHeader
path={[{ icon: CodeInsightsIcon, text: 'Insights' }]}
actions={
isSourcegraphDotCom ? (
<Button
as={Link}
to="https://sourcegraph.com"
variant="primary"
onClick={() => {
EVENT_LOGGER.log('ClickedOnEnterpriseCTA', { location: 'TryInsights' })
telemetryRecorder.recordEvent('insights.enterpriseCTA', 'click', {
metadata: { location: 0 },
})
}}
>
Get Sourcegraph Enterprise
</Button>
) : null
}
className="mb-4"
/>
<main className="pb-5">
<Card as={CardBody} className={styles.heroSection}>
<aside className={styles.heroVideoBlock}>
<video
className={classNames('shadow percy-hide w-100 h-auto')}
width={1280}
height={720}
autoPlay={true}
muted={true}
loop={true}
playsInline={true}
controls={false}
>
<source
type="video/webm"
src="https://storage.googleapis.com/sourcegraph-assets/code_insights/code-insights-720.webm"
/>
<source
type="video/mp4"
src="https://storage.googleapis.com/sourcegraph-assets/code_insights/code-insights-720.mp4"
/>
</video>
</aside>
<CodeInsightsDescription className={styles.heroDescriptionBlock} />
</Card>
<CallToActionBanner variant="filled">
To track Insights across your team's private repositories,{' '}
<Link
to="https://sourcegraph.com"
onClick={() => {
EVENT_LOGGER.log('ClickedOnEnterpriseCTA', { location: 'Insights' })
telemetryRecorder.recordEvent('insights.enterpriseCTA', 'click', {
metadata: { location: 0 },
})
}}
>
get Sourcegraph Enterprise
</Link>
.
</CallToActionBanner>
<CodeInsightsExamplesPicker
telemetryService={telemetryService}
telemetryRecorder={telemetryRecorder}
/>
</main>
</Page>
</CodeInsightsLandingPageContext.Provider>
)
}

View File

@ -1,83 +0,0 @@
.root {
display: flex;
flex-wrap: wrap;
gap: 1.5rem;
flex-direction: row;
padding: 1.5rem;
&--mobile {
flex-direction: column;
}
}
.section {
flex: 1;
}
.list {
display: flex;
flex-direction: column;
gap: 0.5rem;
list-style: none;
margin: 2rem 0 0 0;
padding: 0;
}
.button {
text-align: left;
border: none;
padding: 0.5rem 0.75rem;
position: relative;
transition: none;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
outline: none;
--button-arrow-color: transparent;
&:hover,
&:focus {
background-color: var(--color-bg-2);
--button-arrow-color: var(--color-bg-2);
.button-svg {
display: block;
}
}
&--active {
--button-arrow-color: var(--secondary);
&:hover {
--button-arrow-color: var(--secondary-3);
}
&:focus {
--button-arrow-color: var(--secondary);
}
.button-svg {
display: block;
}
}
}
.button-svg {
display: none;
position: absolute;
height: 100%;
top: 0;
right: 0;
transform: translateX(calc(100% - 1px));
path {
fill: var(--button-arrow-color);
}
}
.chart {
height: 25rem;
width: 100%;
background-color: var(--color-bg-2);
}

View File

@ -1,92 +0,0 @@
import { type FunctionComponent, useLayoutEffect, useState } from 'react'
import classNames from 'classnames'
import { throttle } from 'lodash'
import { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
import type { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService'
import { Button, Card, CardBody, Link, H2 } from '@sourcegraph/wildcard'
import { CodeInsightExampleCard } from '../../../getting-started/components/code-insights-examples/code-insight-example-card/CodeInsightExampleCard'
import { CodeInsightsExamplesSlider } from './code-insights-examples-slider/CodeInsightsExamplesSlider'
import { EXAMPLES } from './examples'
import styles from './CodeInsightsExamplesPicker.module.scss'
interface CodeInsightsExamplesPickerProps extends TelemetryProps, TelemetryV2Props {}
export const CodeInsightsExamplesPicker: FunctionComponent<CodeInsightsExamplesPickerProps> = props => {
const { telemetryService, telemetryRecorder } = props
const [activeExampleIndex, setActiveExampleIndex] = useState(0)
const [windowSize, setWindowSize] = useState(0)
useLayoutEffect(() => {
setWindowSize(window.innerWidth)
const handleWindowResize = throttle(() => setWindowSize(window.innerWidth), 200)
window.addEventListener('resize', handleWindowResize)
return () => window.removeEventListener('resize', handleWindowResize)
}, [])
const handleUseCaseButtonClick = (useCaseIndex: number): void => {
setActiveExampleIndex(useCaseIndex)
telemetryService.log('CloudCodeInsightsGetStartedUseCase')
telemetryRecorder.recordEvent('codeInsights.getStarted.useCase', 'click')
}
const isMobileLayout = windowSize <= 900
return (
<Card as={CardBody} className={classNames(styles.root, { [styles.rootMobile]: isMobileLayout })}>
<div className={styles.section}>
<H2>Use Code Insights to...</H2>
<Link to="/help/code_insights/references/common_use_cases" target="_blank" rel="noopener">
See more use cases
</Link>
{!isMobileLayout && (
<ul className={styles.list}>
{EXAMPLES.map((example, index) => (
<li key={index}>
<Button
outline={index !== activeExampleIndex}
variant={index === activeExampleIndex ? 'secondary' : undefined}
className={classNames(styles.button, {
[styles.buttonActive]: index === activeExampleIndex,
})}
onClick={() => handleUseCaseButtonClick(index)}
>
{example.description}
<svg
className={styles.buttonSvg}
viewBox="0 0 16 36"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M0.443444 0H0V36H0.443444C2.04896 36 3.55682 35.229 4.49684 33.9275L15.1543 19.171C15.6591 18.472 15.6591 17.528 15.1543 16.829L4.49684 2.07255C3.55682 0.770985 2.04896 0 0.443444 0Z" />
</svg>
</Button>
</li>
))}
</ul>
)}
</div>
{!isMobileLayout && (
<CodeInsightExampleCard
{...EXAMPLES[activeExampleIndex]}
className={styles.section}
telemetryService={telemetryService}
telemetryRecorder={telemetryRecorder}
/>
)}
{isMobileLayout && (
<CodeInsightsExamplesSlider telemetryService={telemetryService} telemetryRecorder={telemetryRecorder} />
)}
</Card>
)
}

View File

@ -1,61 +0,0 @@
.slider-section {
display: flex;
flex-direction: column;
width: 100%;
max-width: 100%;
}
.header {
display: flex;
align-items: center;
margin-bottom: 1rem;
}
.header-control:disabled {
opacity: 0.2;
}
.header-title {
margin: 0 auto;
text-align: center;
padding: 0 0.5rem;
}
.slider-list {
display: flex;
width: 100%;
gap: 1rem;
overflow-x: scroll;
scroll-snap-type: x mandatory;
padding: 0;
margin: 0;
list-style: none;
}
.slider-item {
width: 100%;
flex-shrink: 0;
scroll-snap-align: start;
}
.slider-chart {
height: 100%;
}
.slider-dots {
margin: 1rem auto;
list-style: none;
display: flex;
gap: 1rem;
}
.slider-dot {
width: 0.3125rem;
height: 0.3125rem;
border-radius: 50%;
background-color: var(--icon-muted);
&--active {
background-color: var(--body-color);
}
}

View File

@ -1,24 +0,0 @@
import type { Meta } from '@storybook/react'
import { noOpTelemetryRecorder } from '@sourcegraph/shared/src/telemetry'
import { NOOP_TELEMETRY_SERVICE } from '@sourcegraph/shared/src/telemetry/telemetryService'
import { WebStory } from '../../../../../../../../components/WebStory'
import { CodeInsightsExamplesSlider } from './CodeInsightsExamplesSlider'
const meta: Meta = {
title: 'web/insights/dot-com-landing/CodeInsightsExampleSlider',
decorators: [story => <WebStory>{() => story()}</WebStory>],
}
export default meta
export const CodeInsightsExampleSliderExample = () => (
<div style={{ width: 500 }}>
<CodeInsightsExamplesSlider
telemetryService={NOOP_TELEMETRY_SERVICE}
telemetryRecorder={noOpTelemetryRecorder}
/>
</div>
)

View File

@ -1,181 +0,0 @@
import React, { forwardRef, useEffect, useRef, useState } from 'react'
import classNames from 'classnames'
import { useMergeRefs } from 'use-callback-ref'
import { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
import type { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService'
import { Button, type ForwardReferenceComponent, H3 } from '@sourcegraph/wildcard'
import { CodeInsightExampleCard } from '../../../../getting-started/components/code-insights-examples/code-insight-example-card/CodeInsightExampleCard'
import { EXAMPLES } from '../examples'
import styles from './CodeInsightsExamplesSlider.module.scss'
interface CodeInsightsExamplesSliderProps extends TelemetryProps, TelemetryV2Props {}
export const CodeInsightsExamplesSlider: React.FunctionComponent<
React.PropsWithChildren<CodeInsightsExamplesSliderProps>
> = props => {
const { telemetryService, telemetryRecorder } = props
const itemElementReferences = useRef<Map<number, HTMLElement | null>>(new Map())
const [activeExampleIndex, setActiveExampleIndex] = useState<number>(0)
const handleBackClick = (): void => {
const nextActiveExampleIndex = activeExampleIndex - 1
const nextElementReference = itemElementReferences.current.get(nextActiveExampleIndex)
if (nextElementReference) {
nextElementReference.scrollIntoView({ block: 'nearest', inline: 'start' })
telemetryService.log('CloudCodeInsightsGetStartedUseCase')
telemetryRecorder.recordEvent('cloudInsights.getStarted.useCase.back', 'click')
}
}
const handleForwardClick = (): void => {
const nextActiveExampleIndex = activeExampleIndex + 1
const nextElementReference = itemElementReferences.current.get(nextActiveExampleIndex)
if (nextElementReference) {
nextElementReference.scrollIntoView({ block: 'nearest', inline: 'start' })
telemetryService.log('CloudCodeInsightsGetStartedUseCase')
telemetryRecorder.recordEvent('cloudInsights.getStarted.useCase.forward', 'click')
}
}
const registerReferenceElement = (index: number, elementReference: HTMLElement | null): void => {
itemElementReferences.current.set(index, elementReference)
}
const activeExample = EXAMPLES[activeExampleIndex]
return (
<section className={styles.sliderSection}>
<header className={styles.header}>
<Button
variant="icon"
className={styles.headerControl}
onClick={handleBackClick}
disabled={activeExampleIndex === 0}
>
<ArrowIcon side="left" />
</Button>
<H3 className={styles.headerTitle}>{activeExample.content.title}</H3>
<Button
variant="icon"
className={styles.headerControl}
onClick={handleForwardClick}
disabled={activeExampleIndex === EXAMPLES.length - 1}
>
<ArrowIcon side="right" />
</Button>
</header>
<ul className={styles.sliderList}>
{EXAMPLES.map((example, index) => (
<CodeInsightsExamplesSliderItem
key={index}
as="li"
ref={element => registerReferenceElement(index, element)}
className={styles.sliderItem}
onFullIntersection={() => setActiveExampleIndex(index)}
>
<CodeInsightExampleCard
{...example}
className={styles.sliderChart}
telemetryService={telemetryService}
telemetryRecorder={telemetryRecorder}
/>
</CodeInsightsExamplesSliderItem>
))}
</ul>
<ul className={styles.sliderDots}>
{EXAMPLES.map((example, index) => (
<li
key={index}
className={classNames(styles.sliderDot, {
[styles.sliderDotActive]: index === activeExampleIndex,
})}
/>
))}
</ul>
</section>
)
}
interface CodeInsightsExamplesSliderItemProps {
onFullIntersection: () => void
}
export const CodeInsightsExamplesSliderItem = forwardRef((props, publicReference) => {
const { onFullIntersection, as: Comp = 'div', ...attributes } = props
const localReference = useRef<HTMLDivElement>(null)
const mergedReference = useMergeRefs([localReference, publicReference])
const onFullIntersectionReference = useRef(onFullIntersection)
onFullIntersectionReference.current = onFullIntersection
useEffect(() => {
const element = localReference.current
if (!element) {
return
}
const observer = new IntersectionObserver(
entries => {
for (const entry of entries) {
if (entry.isIntersecting) {
onFullIntersectionReference.current()
}
}
},
{ threshold: 0.5 }
)
observer.observe(element)
return () => observer.disconnect()
}, [])
return <Comp ref={mergedReference} {...attributes} />
}) as ForwardReferenceComponent<'div', CodeInsightsExamplesSliderItemProps>
CodeInsightsExamplesSliderItem.displayName = 'CodeInsightsExamplesSliderItem'
interface ArrowIconProps {
side: 'right' | 'left'
}
const ArrowIcon: React.FunctionComponent<React.PropsWithChildren<ArrowIconProps>> = props => {
const { side } = props
const rotate = `rotate(${side === 'left' ? 180 : 0}deg)`
return (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
/* eslint-disable-next-line react/forbid-dom-props */
style={{ transform: rotate }}
xmlns="http://www.w3.org/2000/svg"
className="inline-icon"
>
<path
fill="var(--body-color)"
fillRule="evenodd"
clipRule="evenodd"
d="M3.1875 12C3.1875 11.6893 3.43934 11.4375 3.75 11.4375L20.25 11.4375C20.5607 11.4375 20.8125 11.6893 20.8125 12C20.8125 12.3107 20.5607 12.5625 20.25 12.5625L3.75 12.5625C3.43934 12.5625 3.1875 12.3107 3.1875 12Z"
/>
<path
fill="var(--body-color)"
fillRule="evenodd"
clipRule="evenodd"
d="M13.1023 4.85225C13.3219 4.63258 13.6781 4.63258 13.8977 4.85225L20.6477 11.6023C20.8674 11.8219 20.8674 12.1781 20.6477 12.3977L13.8977 19.1477C13.6781 19.3674 13.3219 19.3674 13.1023 19.1477C12.8826 18.9281 12.8826 18.5719 13.1023 18.3523L19.4545 12L13.1023 5.64775C12.8826 5.42808 12.8826 5.07192 13.1023 4.85225Z"
/>
</svg>
)
}

View File

@ -1,66 +0,0 @@
import { InsightType } from '../../../../../core'
import {
ALPINE_VERSIONS_INSIGHT,
CSS_MODULES_VS_GLOBAL_STYLES_INSIGHT,
DEPRECATED_API_USAGE_BY_TEAM,
LINTER_OVERRIDES,
LOG_4_J_INCIDENT_INSIGHT,
OPENSSL_PYTHON,
REPOS_WITH_CI_SYSTEM,
} from '../../../getting-started/components/code-insights-examples/examples'
import type {
CaptureGroupExampleContent,
SearchInsightExampleContent,
} from '../../../getting-started/components/code-insights-examples/types'
interface SearchInsightExample {
type: InsightType.SearchBased
content: SearchInsightExampleContent<any>
}
interface CaptureGroupInsightExample {
type: InsightType.CaptureGroup
content: CaptureGroupExampleContent<any>
}
type Example = (SearchInsightExample | CaptureGroupInsightExample) & {
description: string
}
export const EXAMPLES: Example[] = [
{
type: InsightType.SearchBased,
content: CSS_MODULES_VS_GLOBAL_STYLES_INSIGHT,
description: 'Track migrations, adoption, and deprecations',
},
{
type: InsightType.CaptureGroup,
content: ALPINE_VERSIONS_INSIGHT,
description: 'Detect and track versions of languages or packages',
},
{
type: InsightType.SearchBased,
content: LOG_4_J_INCIDENT_INSIGHT,
description: 'Ensure removal of security vulnerabilities',
},
{
type: InsightType.SearchBased,
content: OPENSSL_PYTHON,
description: 'Find vulnerable OpenSSL versions in the Python Ecosystem',
},
{
type: InsightType.SearchBased,
content: DEPRECATED_API_USAGE_BY_TEAM,
description: 'Understand code by team',
},
{
type: InsightType.SearchBased,
content: LINTER_OVERRIDES,
description: 'Track code smells and health',
},
{
type: InsightType.SearchBased,
content: REPOS_WITH_CI_SYSTEM,
description: 'Visualize configurations and services',
},
]

View File

@ -4,11 +4,9 @@ import { mdiMagnify, mdiPlus } from '@mdi/js'
import type { PlatformContextProps } from '@sourcegraph/shared/src/platform/context'
import type { SearchContextProps } from '@sourcegraph/shared/src/search'
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
import { PageHeader, Link, Button, Icon, Alert } from '@sourcegraph/wildcard'
import { Alert, Button, Icon, Link, PageHeader } from '@sourcegraph/wildcard'
import type { AuthenticatedUser } from '../../auth'
import { CallToActionBanner } from '../../components/CallToActionBanner'
import { Page } from '../../components/Page'
import { SearchContextsList } from './SearchContextsList'
@ -48,36 +46,16 @@ export const SearchContextsListPage: React.FunctionComponent<SearchContextsListP
</div>
}
description={
<>
<span className="text-muted">
Search code you care about with search contexts.{' '}
<Link
to="/help/code_search/explanations/features#search-contexts"
target="_blank"
rel="noopener noreferrer"
>
Learn more
</Link>
</span>
{isSourcegraphDotCom && (
<CallToActionBanner variant="filled" className="mb-0">
To search across your team's private repositories,{' '}
<Link
to="https://sourcegraph.com"
onClick={() => {
EVENT_LOGGER.log('ClickedOnEnterpriseCTA', { location: 'ContextsSettings' })
platformContext.telemetryRecorder.recordEvent(
'searchContexts.enterpriseCTA',
'click'
)
}}
>
get Sourcegraph Enterprise
</Link>
.
</CallToActionBanner>
)}
</>
<span className="text-muted">
Search code you care about with search contexts.{' '}
<Link
to="/help/code-search/working/search_contexts"
target="_blank"
rel="noopener noreferrer"
>
Learn more
</Link>
</span>
}
className="mb-3"
>

View File

@ -6,11 +6,9 @@ import classNames from 'classnames'
import type { AuthenticatedUser } from '@sourcegraph/shared/src/auth'
import { useTemporarySetting } from '@sourcegraph/shared/src/settings/temporary/useTemporarySetting'
import type { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService'
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
import { useIsLightTheme } from '@sourcegraph/shared/src/theme'
import { Container, Icon, Link, H2, H3, Text, useReducedMotion } from '@sourcegraph/wildcard'
import { Container, H2, H3, Icon, Link, Text, useReducedMotion } from '@sourcegraph/wildcard'
import { CallToActionBanner } from '../../components/CallToActionBanner'
import { PageRoutes } from '../../routes.constants'
import styles from './NotebooksGettingStartedTab.module.scss'
@ -54,14 +52,13 @@ const functionalityPanels = [
export const NotebooksGettingStartedTab: React.FunctionComponent<
React.PropsWithChildren<NotebooksGettingStartedTabProps>
> = ({ telemetryService, authenticatedUser }) => {
> = ({ telemetryService }) => {
useEffect(() => {
// No V2 telemetry required, as this is duplicative with the view event logged in NotebooksListPage.tsx.
telemetryService.log('NotebooksGettingStartedTabViewed')
}, [telemetryService])
const [, setHasSeenGettingStartedTab] = useTemporarySetting('search.notebooks.gettingStartedTabSeen', false)
const isSourcegraphDotCom: boolean = window.context?.sourcegraphDotComMode || false
useEffect(() => {
setHasSeenGettingStartedTab(true)
@ -125,21 +122,6 @@ export const NotebooksGettingStartedTab: React.FunctionComponent<
</div>
</Container>
{isSourcegraphDotCom && (
<CallToActionBanner variant="filled">
To create Notebooks across your team's private repositories,{' '}
<Link
to="https://sourcegraph.com"
onClick={() =>
EVENT_LOGGER.log('ClickedOnEnterpriseCTA', { location: 'NotebooksGettingStarted' })
}
>
get Sourcegraph Enterprise
</Link>
.
</CallToActionBanner>
)}
<H3>Example notebooks</H3>
<div className={classNames(styles.row, 'row', 'mb-4')}>
<div className="col-12 col-md-6">

View File

@ -42,7 +42,10 @@ const GlobalCodeMonitoringArea = lazyComponent(
() => import('./enterprise/code-monitoring/global/GlobalCodeMonitoringArea'),
'GlobalCodeMonitoringArea'
)
const CodeInsightsRouter = lazyComponent(() => import('./enterprise/insights/CodeInsightsRouter'), 'CodeInsightsRouter')
const CodeInsightsAppRouter = lazyComponent(
() => import('./enterprise/insights/CodeInsightsAppRouter'),
'CodeInsightsAppRouter'
)
const SearchContextsListPage = lazyComponent(
() => import('./enterprise/searchContexts/SearchContextsListPage'),
'SearchContextsListPage'
@ -158,7 +161,7 @@ export const routes: RouteObject[] = [
element: (
<LegacyRoute
render={props => (
<CodeInsightsRouter {...props} telemetryRecorder={props.platformContext.telemetryRecorder} />
<CodeInsightsAppRouter {...props} telemetryRecorder={props.platformContext.telemetryRecorder} />
)}
condition={({ codeInsightsEnabled }) => !!codeInsightsEnabled}
/>