mirror of
https://github.com/sourcegraph/sourcegraph.git
synced 2026-02-06 19:51:50 +00:00
Svelte: Add basic telemetry to svelte implementation (#62190)
* Move telemetry service to the shared package * Migrate web to the shared based telemetry * Add svelte telemetry events * Run svelte format * Format:changed * Format:changed and fix custom log view event handler * Rebased onto main
This commit is contained in:
parent
645358f125
commit
c2afde8b43
@ -297,8 +297,16 @@ ts_project(
|
||||
"src/symbols/SymbolKind.tsx",
|
||||
"src/symbols/SymbolTag.tsx",
|
||||
"src/symbols/symbolIcons.ts",
|
||||
"src/telemetry/event-names.ts",
|
||||
"src/telemetry/index.ts",
|
||||
"src/telemetry/telemetryService.ts",
|
||||
"src/telemetry/web/backend.ts",
|
||||
"src/telemetry/web/cookies.ts",
|
||||
"src/telemetry/web/dom.ts",
|
||||
"src/telemetry/web/eventLogger.ts",
|
||||
"src/telemetry/web/sessionTracker.ts",
|
||||
"src/telemetry/web/userTracker.ts",
|
||||
"src/telemetry/web/util.ts",
|
||||
"src/theme.ts",
|
||||
"src/theme-types.ts",
|
||||
"src/tracking/event-log-creators.ts",
|
||||
@ -332,18 +340,22 @@ ts_project(
|
||||
"//:node_modules/@sourcegraph/extension-api-classes",
|
||||
"//:node_modules/@types/classnames",
|
||||
"//:node_modules/@types/history",
|
||||
"//:node_modules/@types/js-cookie",
|
||||
"//:node_modules/@types/lodash",
|
||||
"//:node_modules/@types/lru-cache",
|
||||
"//:node_modules/@types/minimatch",
|
||||
"//:node_modules/@types/node",
|
||||
"//:node_modules/@types/react",
|
||||
"//:node_modules/@types/uuid",
|
||||
"//:node_modules/@types/whatwg-url",
|
||||
"//:node_modules/classnames",
|
||||
"//:node_modules/comlink",
|
||||
"//:node_modules/core-js",
|
||||
"//:node_modules/date-fns",
|
||||
"//:node_modules/fast-json-stable-stringify",
|
||||
"//:node_modules/history",
|
||||
"//:node_modules/js-base64",
|
||||
"//:node_modules/js-cookie",
|
||||
"//:node_modules/lodash",
|
||||
"//:node_modules/lru-cache",
|
||||
"//:node_modules/mdi-react",
|
||||
@ -357,6 +369,7 @@ ts_project(
|
||||
"//:node_modules/use-deep-compare-effect",
|
||||
"//:node_modules/util",
|
||||
"//:node_modules/utility-types",
|
||||
"//:node_modules/uuid",
|
||||
"//:node_modules/whatwg-url",
|
||||
"//:node_modules/zustand",
|
||||
"//schema:settings", #keep
|
||||
@ -438,6 +451,8 @@ ts_project(
|
||||
"src/search/query/validate.test.ts",
|
||||
"src/settings/settings.test.ts",
|
||||
"src/settings/temporary/useTemporarySetting.test.tsx",
|
||||
"src/telemetry/web/userTracker.test.ts",
|
||||
"src/telemetry/web/util.test.ts",
|
||||
"src/testSetup.test.ts",
|
||||
"src/tracking/utm.test.ts",
|
||||
"src/util/dom.test.ts",
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
"lint:js": "eslint --cache '**/*.[jt]s?(x)'",
|
||||
"lint:css": "stylelint 'src/**/*.scss' --quiet",
|
||||
"test": "vitest",
|
||||
"build-ts": "tsc --build tsconfig.json --emitDeclarationOnly",
|
||||
"generate": "concurrently -r npm:generate:*",
|
||||
"generate:graphql-operations": "ts-node -T dev/generateGraphQlOperations.ts",
|
||||
"generate:schema": "ts-node -T dev/generateSchema.ts json-schema-draft-07 settings site batch_spec opencodegraph",
|
||||
@ -29,4 +30,4 @@
|
||||
"@sourcegraph/wildcard": "workspace:*"
|
||||
},
|
||||
"sideEffects": true
|
||||
}
|
||||
}
|
||||
|
||||
58
client/shared/src/telemetry/event-names.ts
Normal file
58
client/shared/src/telemetry/event-names.ts
Normal file
@ -0,0 +1,58 @@
|
||||
// NOTE(naman): Remember to add events to allow list: https://sourcegraph.com/docs/dev/background-information/data-usage-pipeline#allow-list
|
||||
export const enum EventName {
|
||||
CODY_CHAT_PAGE_VIEWED = 'web:codyChat:pageViewed',
|
||||
CODY_CHAT_SUBMIT = 'web:codyChat:submit',
|
||||
CODY_CHAT_EDIT = 'web:codyChat:edit',
|
||||
CODY_CHAT_INITIALIZED = 'web:codyChat:initialized',
|
||||
CODY_CHAT_EDITOR_WIDGET_VIEWED = 'web:codyChat:editorWidgetViewed',
|
||||
CODY_CHAT_HISTORY_CLEARED = 'web:codyChat:historyCleared',
|
||||
CODY_CHAT_HISTORY_ITEM_DELETED = 'web:codyChat:historyItemDeleted',
|
||||
|
||||
CODY_CHAT_SCOPE_REPO_ADDED = 'web:codyChat:scopeRepoAdded',
|
||||
CODY_CHAT_SCOPE_REPO_REMOVED = 'web:codyChat:scopeRepoRemoved',
|
||||
CODY_CHAT_SCOPE_RESET = 'web:codyChat:scopeReset',
|
||||
CODY_CHAT_SCOPE_INFERRED_REPO_ENABLED = 'web:codyChat:inferredRepoEnabled',
|
||||
CODY_CHAT_SCOPE_INFERRED_REPO_DISABLED = 'web:codyChat:inferredRepoDisabled',
|
||||
CODY_CHAT_SCOPE_INFERRED_FILE_ENABLED = 'web:codyChat:inferredFileEnabled',
|
||||
CODY_CHAT_SCOPE_INFERRED_FILE_DISABLED = 'web:codyChat:inferredFileDisabled',
|
||||
VIEW_GET_CODY = 'GetCody',
|
||||
|
||||
CODY_EDITOR_WIDGET_VIEWED = 'web:codyEditorWidget:viewed',
|
||||
CODY_SIDEBAR_CHAT_OPENED = 'web:codySidebar:chatOpened',
|
||||
CODY_SIGNUP_CTA_CLICK = 'CodySignUpCTAClick',
|
||||
CODY_CHAT_DOWNLOAD_VSCODE = 'web:codyChat:downloadVSCodeCTA',
|
||||
CODY_CHAT_GET_EDITOR_EXTENSION = 'web:codyChat:getEditorExtensionCTA',
|
||||
CODY_CHAT_TRY_ON_PUBLIC_CODE = 'web:codyChat:tryOnPublicCodeCTA',
|
||||
CODY_CTA = 'ClickedOnCodyCTA',
|
||||
VIEW_EDITOR_EXTENSIONS = 'CodyClickViewEditorExtensions',
|
||||
TRY_CODY_VSCODE = 'VSCodeInstall',
|
||||
TRY_CODY_MARKETPLACE = 'VSCodeMarketplace',
|
||||
TRY_CODY_WEB = 'TryCodyWeb',
|
||||
TRY_CODY_WEB_ONBOARDING_DISPLAYED = 'TryCodyWebOnboardingDisplayed',
|
||||
TRY_CODY_SIGNUP_INITIATED = 'CodySignUpInitiated',
|
||||
SPEAK_TO_AN_ENGINEER_CTA = 'SpeakToACodyEngineerCTA',
|
||||
AUTH_INITIATED = 'AuthInitiated',
|
||||
SIGNUP_COMPLETED = 'web:auth:signUpCompleted',
|
||||
SINGIN_COMPLETED = 'web:auth:signInCompleted',
|
||||
|
||||
JOIN_IDE_WAITLIST = 'JoinIDEWaitlist',
|
||||
DOWNLOAD_IDE = 'DownloadIDE',
|
||||
DOWNLOAD_APP = 'DownloadApp',
|
||||
|
||||
CODY_EDITOR_SETUP_VIEWED = 'CodyEditorSetUpViewed',
|
||||
CODY_EDITOR_SETUP_OPEN_MARKETPLACE = 'CodyEditorSetUpOpenMarketplace',
|
||||
CODY_EDITOR_FEATURES_VIEWED = 'CodyEditorFeaturesViewed',
|
||||
CODY_MANAGEMENT_PAGE_VIEWED = 'CodyManageViewed',
|
||||
CODY_SUBSCRIPTION_PAGE_VIEWED = 'CodyPlanSelectionViewed',
|
||||
CODY_SUBSCRIPTION_PLAN_CLICKED = 'CodyPlanSelectionClicked',
|
||||
CODY_SUBSCRIPTION_PLAN_CONFIRMED = 'CodyPlanSelectionConfirmed',
|
||||
CODY_SUBSCRIPTION_ADD_CREDIT_CARD_CLICKED = 'CodyAddCreditCard',
|
||||
CODY_MANAGE_SUBSCRIPTION_CLICKED = 'CodyManageSubscriptionClicked',
|
||||
CODY_ONBOARDING_WELCOME_VIEWED = 'CodyWelcomeViewed',
|
||||
CODY_ONBOARDING_PURPOSE_VIEWED = 'CodyUseCaseViewed',
|
||||
CODY_ONBOARDING_PURPOSE_SELECTED = 'CodyUseCaseSelected',
|
||||
CODY_ONBOARDING_CHOOSE_EDITOR_VIEWED = 'CodyEditorViewed',
|
||||
CODY_ONBOARDING_CHOOSE_EDITOR_SKIPPED = 'CodyEditorSkipped',
|
||||
CODY_ONBOARDING_CHOOSE_EDITOR_SELECTED = 'CodyEditorSelected',
|
||||
CODY_HANDRAISER_TEST_ENROLLMENT = 'HubspotFormFromWorkPersonalToHandRaiserTestEnrollment',
|
||||
}
|
||||
85
client/shared/src/telemetry/web/backend.ts
Normal file
85
client/shared/src/telemetry/web/backend.ts
Normal file
@ -0,0 +1,85 @@
|
||||
import { EMPTY, type Observable, Subject, lastValueFrom } from 'rxjs'
|
||||
import { bufferTime, catchError, concatMap } from 'rxjs/operators'
|
||||
|
||||
import { gql, dataOrThrowErrors, requestGraphQLCommon, type GraphQLResult } from '@sourcegraph/http-client'
|
||||
|
||||
import type { LogEventsResult, LogEventsVariables, Event } from '../../graphql-operations'
|
||||
|
||||
const getHeaders = (): { [header: string]: string } => {
|
||||
const headers: { [header: string]: string } = {
|
||||
...window.context?.xhrHeaders,
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
const parameters = new URLSearchParams(location.search)
|
||||
const trace = parameters.get('trace')
|
||||
if (trace) {
|
||||
headers['X-Sourcegraph-Should-Trace'] = trace
|
||||
}
|
||||
|
||||
// Get values from URL and local overrides
|
||||
const feat = parameters.getAll('feat')
|
||||
if (feat.length) {
|
||||
headers['X-Sourcegraph-Override-Feature'] = feat.join(',')
|
||||
}
|
||||
return headers
|
||||
}
|
||||
|
||||
const requestGraphQL = <TResult, TVariables = object>(
|
||||
request: string,
|
||||
variables?: TVariables
|
||||
): Observable<GraphQLResult<TResult>> =>
|
||||
requestGraphQLCommon({
|
||||
request,
|
||||
variables,
|
||||
headers: getHeaders(),
|
||||
})
|
||||
|
||||
// Log events in batches.
|
||||
const BATCHED_EVENTS = new Subject<Event>()
|
||||
|
||||
export const logEventsMutation = gql`
|
||||
mutation LogEvents($events: [Event!]) {
|
||||
logEvents(events: $events) {
|
||||
alwaysNil
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
function sendEvents(events: Event[]): Promise<void> {
|
||||
return lastValueFrom(
|
||||
requestGraphQL<LogEventsResult, LogEventsVariables>(logEventsMutation, {
|
||||
events,
|
||||
})
|
||||
)
|
||||
.then(dataOrThrowErrors)
|
||||
.then(() => {})
|
||||
}
|
||||
|
||||
BATCHED_EVENTS.pipe(
|
||||
bufferTime(1000),
|
||||
concatMap(events => {
|
||||
if (events.length > 0) {
|
||||
return sendEvents(events)
|
||||
}
|
||||
return EMPTY
|
||||
}),
|
||||
// TODO: log errors to Sentry
|
||||
catchError(() => [])
|
||||
)
|
||||
// eslint-disable-next-line rxjs/no-ignored-subscription
|
||||
.subscribe()
|
||||
|
||||
/**
|
||||
* Log a raw user action (used to allow site admins on a Sourcegraph instance
|
||||
* to see a count of unique users on a daily, weekly, and monthly basis).
|
||||
*
|
||||
* When invoked on a non-Sourcegraph.com instance, this data is stored in the
|
||||
* instance's database, and not sent to Sourcegraph.com.
|
||||
*
|
||||
* @deprecated Use a TelemetryRecorder or TelemetryRecorderProvider from
|
||||
* src/telemetry instead.
|
||||
*/
|
||||
export function logEvent(event: Event): void {
|
||||
BATCHED_EVENTS.next(event)
|
||||
}
|
||||
@ -32,6 +32,8 @@ export const userCookieSettings: CookieAttributes = {
|
||||
sameSite: 'Lax',
|
||||
// Specify the Domain attribute to ensure subdomains (sourcegraph.com) can receive this cookie.
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#define_where_cookies_are_sent
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
domain: location.hostname,
|
||||
}
|
||||
|
||||
@ -46,5 +48,7 @@ export const deviceSessionCookieSettings: CookieAttributes = {
|
||||
sameSite: 'Lax',
|
||||
// Specify the Domain attribute to ensure subdomains (sourcegraph.com) can receive this cookie.
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#define_where_cookies_are_sent
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
domain: location.hostname,
|
||||
}
|
||||
51
client/shared/src/telemetry/web/dom.ts
Normal file
51
client/shared/src/telemetry/web/dom.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import { Observable } from 'rxjs'
|
||||
|
||||
export interface ObserveQuerySelectorInit {
|
||||
/**
|
||||
* Any valid HTML/CSS selector
|
||||
*/
|
||||
selector: string
|
||||
/**
|
||||
* Timeout in milliseconds
|
||||
*/
|
||||
timeout: number
|
||||
/**
|
||||
* Target element to observe for changes.
|
||||
* Default is document
|
||||
*/
|
||||
target?: HTMLElement
|
||||
}
|
||||
|
||||
class ElementNotFoundError extends Error {
|
||||
public readonly name = 'ElementNotFoundError'
|
||||
constructor({ selector, timeout: timeoutMs }: ObserveQuerySelectorInit) {
|
||||
super(`Could not find element with selector ${selector} within ${timeoutMs}ms.`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an observable that emits when an element that matches `selector` is found.
|
||||
* Errors out if the selector doesn't yield an element by `timeoutMs`
|
||||
*/
|
||||
export const observeQuerySelector = ({ selector, timeout, target }: ObserveQuerySelectorInit): Observable<Element> =>
|
||||
new Observable(function subscribe(observer) {
|
||||
const targetElement = target ?? document
|
||||
const intervalId = setInterval(() => {
|
||||
const element = targetElement.querySelector(selector)
|
||||
if (element) {
|
||||
observer.next(element)
|
||||
observer.complete()
|
||||
}
|
||||
}, Math.min(100, timeout))
|
||||
|
||||
const timeoutId = setTimeout(() => {
|
||||
clearInterval(intervalId)
|
||||
// If the element still hasn't appeared, call error handler.
|
||||
observer.error(ElementNotFoundError)
|
||||
}, timeout)
|
||||
|
||||
return function unsubscribe() {
|
||||
clearTimeout(timeoutId)
|
||||
clearInterval(intervalId)
|
||||
}
|
||||
})
|
||||
@ -3,15 +3,15 @@ import { catchError, map, share, take } from 'rxjs/operators'
|
||||
import * as uuid from 'uuid'
|
||||
|
||||
import { isErrorLike, isFirefox, logger } from '@sourcegraph/common'
|
||||
import type { SharedEventLogger } from '@sourcegraph/shared/src/api/sharedEventLogger'
|
||||
import { EventClient } from '@sourcegraph/shared/src/graphql-operations'
|
||||
import type { TelemetryService } from '@sourcegraph/shared/src/telemetry/telemetryService'
|
||||
import type { UTMMarker } from '@sourcegraph/shared/src/tracking/utm'
|
||||
|
||||
import { EventName } from '../util/constants'
|
||||
import { observeQuerySelector } from '../util/dom'
|
||||
import type { SharedEventLogger } from '../../api/sharedEventLogger'
|
||||
import { type Event, EventClient, EventSource } from '../../graphql-operations'
|
||||
import type { UTMMarker } from '../../tracking/utm'
|
||||
import { EventName } from '../event-names'
|
||||
import type { TelemetryService } from '../telemetryService'
|
||||
|
||||
import { serverAdmin } from './services/serverAdminWrapper'
|
||||
import { logEvent } from './backend'
|
||||
import { observeQuerySelector } from './dom'
|
||||
import { sessionTracker } from './sessionTracker'
|
||||
import { userTracker } from './userTracker'
|
||||
import { stripURLParameters } from './util'
|
||||
@ -100,13 +100,13 @@ export class EventLogger implements TelemetryService, SharedEventLogger {
|
||||
}
|
||||
|
||||
private logViewEventInternal(eventName: string, eventProperties?: any, logAsActiveUser = true): void {
|
||||
const props = pageViewQueryParameters(window.location.href)
|
||||
serverAdmin.trackPageView(eventName, logAsActiveUser, eventProperties)
|
||||
const props = pageViewQueryParameters(location.href)
|
||||
logEvent(this.createEvent(eventName, logAsActiveUser, eventProperties))
|
||||
this.logToConsole(eventName, props)
|
||||
|
||||
// Use flag to ensure URL query params are only stripped once
|
||||
if (!this.hasStrippedQueryParameters) {
|
||||
handleQueryEvents(window.location.href)
|
||||
handleQueryEvents(location.href)
|
||||
this.hasStrippedQueryParameters = true
|
||||
}
|
||||
}
|
||||
@ -175,13 +175,13 @@ export class EventLogger implements TelemetryService, SharedEventLogger {
|
||||
|
||||
// Use flag to ensure URL query params are only stripped once
|
||||
if (!this.hasStrippedQueryParameters) {
|
||||
handleQueryEvents(window.location.href)
|
||||
handleQueryEvents(location.href)
|
||||
this.hasStrippedQueryParameters = true
|
||||
}
|
||||
}
|
||||
|
||||
public logInternal(eventLabel: string, eventProperties?: any, publicArgument?: any): void {
|
||||
serverAdmin.trackAction(eventLabel, eventProperties, publicArgument)
|
||||
logEvent(this.createEvent(eventLabel, eventProperties, publicArgument))
|
||||
this.logToConsole(eventLabel, eventProperties, publicArgument)
|
||||
}
|
||||
|
||||
@ -227,13 +227,38 @@ export class EventLogger implements TelemetryService, SharedEventLogger {
|
||||
this.listeners.add(callback)
|
||||
return () => this.listeners.delete(callback)
|
||||
}
|
||||
|
||||
private createEvent(event: string, eventProperties?: unknown, publicArgument?: unknown): Event {
|
||||
return {
|
||||
event,
|
||||
userCookieID: EVENT_LOGGER.user.anonymousUserID,
|
||||
cohortID: EVENT_LOGGER.user.cohortID || null,
|
||||
firstSourceURL: EVENT_LOGGER.session.getFirstSourceURL(),
|
||||
lastSourceURL: EVENT_LOGGER.session.getLastSourceURL(),
|
||||
referrer: EVENT_LOGGER.session.getReferrer(),
|
||||
originalReferrer: EVENT_LOGGER.session.getOriginalReferrer(),
|
||||
sessionReferrer: EVENT_LOGGER.session.getSessionReferrer(),
|
||||
sessionFirstURL: EVENT_LOGGER.session.getSessionFirstURL(),
|
||||
deviceSessionID: EVENT_LOGGER.user.deviceSessionID,
|
||||
url: location.href,
|
||||
source: EventSource.WEB,
|
||||
argument: eventProperties ? JSON.stringify(eventProperties) : null,
|
||||
publicArgument: publicArgument ? JSON.stringify(publicArgument) : null,
|
||||
deviceID: EVENT_LOGGER.user.deviceID,
|
||||
eventID: EVENT_LOGGER.getEventID(),
|
||||
insertID: EVENT_LOGGER.getInsertID(),
|
||||
client: EVENT_LOGGER.getClient(),
|
||||
connectedSiteID: window.context?.siteID,
|
||||
hashedLicenseKey: window.context?.hashedLicenseKey,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use a TelemetryRecorder or TelemetryRecorderProvider from
|
||||
* src/telemetry instead.
|
||||
*/
|
||||
export const eventLogger = new EventLogger()
|
||||
export const EVENT_LOGGER = new EventLogger()
|
||||
|
||||
export function debugEventLoggingEnabled(): boolean {
|
||||
return !!localStorage && localStorage.getItem('eventLogDebug') === 'true'
|
||||
@ -254,12 +279,12 @@ function handleQueryEvents(url: string): void {
|
||||
const parsedUrl = new URL(url)
|
||||
if (parsedUrl.searchParams.has('signup')) {
|
||||
const args = { serviceType: parsedUrl.searchParams.get('signup') || '' }
|
||||
eventLogger.logInternal(EventName.SIGNUP_COMPLETED, args, args)
|
||||
EVENT_LOGGER.logInternal(EventName.SIGNUP_COMPLETED, args, args)
|
||||
}
|
||||
|
||||
if (parsedUrl.searchParams.has('signin')) {
|
||||
const args = { serviceType: parsedUrl.searchParams.get('signin') || '' }
|
||||
eventLogger.logInternal(EventName.SINGIN_COMPLETED, args, args)
|
||||
EVENT_LOGGER.logInternal(EventName.SINGIN_COMPLETED, args, args)
|
||||
}
|
||||
|
||||
stripURLParameters(url, ['utm_campaign', 'utm_source', 'utm_medium', 'signup', 'signin'])
|
||||
@ -284,13 +309,13 @@ function pageViewQueryParameters(url: string): UTMMarker {
|
||||
}
|
||||
|
||||
if (utmSource === 'saved-search-email') {
|
||||
eventLogger.log('SavedSearchEmailClicked')
|
||||
EVENT_LOGGER.log('SavedSearchEmailClicked')
|
||||
} else if (utmSource === 'saved-search-slack') {
|
||||
eventLogger.log('SavedSearchSlackClicked')
|
||||
EVENT_LOGGER.log('SavedSearchSlackClicked')
|
||||
} else if (utmSource === 'code-monitoring-email') {
|
||||
eventLogger.log('CodeMonitorEmailLinkClicked')
|
||||
EVENT_LOGGER.log('CodeMonitorEmailLinkClicked')
|
||||
} else if (utmSource === 'hubspot' && utmCampaign?.match(/^cloud-onboarding-email(.*)$/)) {
|
||||
eventLogger.log('UTMCampaignLinkClicked', utmProps, utmProps)
|
||||
EVENT_LOGGER.log('UTMCampaignLinkClicked', utmProps, utmProps)
|
||||
} else if (
|
||||
[
|
||||
'safari-extension',
|
||||
@ -301,9 +326,9 @@ function pageViewQueryParameters(url: string): UTMMarker {
|
||||
'gitlab-integration',
|
||||
].includes(utmSource ?? '')
|
||||
) {
|
||||
eventLogger.log('UTMCodeHostIntegration', utmProps, utmProps)
|
||||
EVENT_LOGGER.log('UTMCodeHostIntegration', utmProps, utmProps)
|
||||
} else if (utmMedium === 'VSCODE' && utmCampaign === 'vsce-sign-up') {
|
||||
eventLogger.log('VSCODESignUpLinkClicked', utmProps, utmProps)
|
||||
EVENT_LOGGER.log('VSCODESignUpLinkClicked', utmProps, utmProps)
|
||||
}
|
||||
|
||||
return utmProps
|
||||
@ -14,7 +14,7 @@ export class SessionTracker {
|
||||
* Session tracking is only done in Sourcegraph.com, where cookie values are set in Google Tag Manager
|
||||
* to ensure consistency across all public Sourcegraph-managed properties (e.g. marketing sites, blog, etc.)
|
||||
*/
|
||||
private isSourcegraphDotComMode = window.context?.sourcegraphDotComMode || false
|
||||
private isSourcegraphDotComMode = window.context?.sourcegraphDotComMode
|
||||
|
||||
private originalReferrer: string
|
||||
private sessionReferrer: string
|
||||
29
client/shared/src/telemetry/web/util.test.ts
Normal file
29
client/shared/src/telemetry/web/util.test.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { getPreviousMonday } from './util'
|
||||
|
||||
describe(`${getPreviousMonday.name}()`, () => {
|
||||
it('gets the current day if it is a Monday', () => {
|
||||
const date = new Date(2021, 5, 14) // June 14, 2021 is a Monday
|
||||
const monday = getPreviousMonday(date)
|
||||
expect(monday).toBe('2021-06-14')
|
||||
})
|
||||
|
||||
it('gets the previous Monday if it is not a Monday', () => {
|
||||
const date = new Date(2021, 5, 13) // June 13, 2021 is a Sunday
|
||||
const monday = getPreviousMonday(date)
|
||||
expect(monday).toBe('2021-06-07')
|
||||
})
|
||||
|
||||
it('gets the previous Monday if it is in a different month', () => {
|
||||
const date = new Date(2021, 5, 3) // June 3, 2021 is a Thursday
|
||||
const monday = getPreviousMonday(date)
|
||||
expect(monday).toBe('2021-05-31')
|
||||
})
|
||||
|
||||
it('gets the previous Monday if it is in a different year', () => {
|
||||
const date = new Date(2021, 0, 2) // Jan 2, 2021 is a Saturday
|
||||
const monday = getPreviousMonday(date)
|
||||
expect(monday).toBe('2020-12-28')
|
||||
})
|
||||
})
|
||||
29
client/shared/src/telemetry/web/util.ts
Normal file
29
client/shared/src/telemetry/web/util.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { formatISO, startOfWeek } from 'date-fns'
|
||||
|
||||
export const DOTCOM_URL = new URL('https://sourcegraph.com')
|
||||
|
||||
/**
|
||||
* Strip provided URL parameters and update window history
|
||||
*/
|
||||
export function stripURLParameters(url: string, parametersToRemove: string[] = []): void {
|
||||
const parsedUrl = new URL(url)
|
||||
const existingParameters = parametersToRemove.filter(key => parsedUrl.searchParams.has(key))
|
||||
|
||||
// Update history state only if we have parameters to remove in the url.
|
||||
if (existingParameters.length !== 0) {
|
||||
for (const key of existingParameters) {
|
||||
parsedUrl.searchParams.delete(key)
|
||||
}
|
||||
|
||||
window.history.replaceState(window.history.state, window.document.title, parsedUrl.href)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Monday at or before the supplied date, in YYYY-MM-DD format.
|
||||
* This is used to generate cohort IDs for users who
|
||||
* started using the site on the same week.
|
||||
*/
|
||||
export function getPreviousMonday(date: Date): string {
|
||||
return formatISO(startOfWeek(date, { weekStartsOn: 1 }), { representation: 'date' })
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
<script lang="ts" context="module">
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { faker } from '@faker-js/faker'
|
||||
import { Story } from '@storybook/addon-svelte-csf'
|
||||
|
||||
import CodeExcerpt from './CodeExcerpt.svelte'
|
||||
@ -19,7 +19,12 @@ const obj = {
|
||||
<script lang="ts">
|
||||
faker.seed(16)
|
||||
const plaintextLines = code.trim().split('\n')
|
||||
const highlightedHTMLRows = plaintextLines.map((line, index) => `<tr><td class="line" data-line="${index + 1}" /><td class="code"><span style="color: ${faker.color.rgb()}">${line}</span></td></tr>`)
|
||||
const highlightedHTMLRows = plaintextLines.map(
|
||||
(line, index) =>
|
||||
`<tr><td class="line" data-line="${
|
||||
index + 1
|
||||
}" /><td class="code"><span style="color: ${faker.color.rgb()}">${line}</span></td></tr>`
|
||||
)
|
||||
</script>
|
||||
|
||||
<Story name="Default">
|
||||
@ -35,17 +40,17 @@ const obj = {
|
||||
|
||||
<h3>Hidden line numbers</h3>
|
||||
<div class="wrapper">
|
||||
<CodeExcerpt startLine={1} {plaintextLines} hideLineNumbers/>
|
||||
<CodeExcerpt startLine={1} {plaintextLines} hideLineNumbers />
|
||||
</div>
|
||||
|
||||
<h3>Collapsed whitespace</h3>
|
||||
<div class="wrapper">
|
||||
<CodeExcerpt startLine={1} {plaintextLines} collapseWhitespace/>
|
||||
<CodeExcerpt startLine={1} {plaintextLines} collapseWhitespace />
|
||||
</div>
|
||||
|
||||
<h3>With highlighted code</h3>
|
||||
<div class="wrapper">
|
||||
<CodeExcerpt startLine={1} {plaintextLines} {highlightedHTMLRows}/>
|
||||
<CodeExcerpt startLine={1} {plaintextLines} {highlightedHTMLRows} />
|
||||
</div>
|
||||
</Story>
|
||||
|
||||
|
||||
@ -153,6 +153,7 @@
|
||||
export let selectedLines: LineOrPositionOrRange | null = null
|
||||
export let codeIntelAPI: CodeIntelAPI | null
|
||||
export let staticHighlightRanges: Range[] = []
|
||||
export let onCopy: () => void = () => {}
|
||||
/**
|
||||
* The initial scroll position when the editor is first mounted.
|
||||
* Changing the value afterwards has no effect.
|
||||
@ -326,7 +327,7 @@
|
||||
</script>
|
||||
|
||||
{#if browser}
|
||||
<div bind:this={container} class="root test-editor" data-editor="codemirror6" />
|
||||
<div bind:this={container} class="root test-editor" data-editor="codemirror6" on:copy={onCopy} />
|
||||
{:else}
|
||||
<div class="root">
|
||||
<pre>{blobInfo.content}</pre>
|
||||
|
||||
@ -1,22 +1,18 @@
|
||||
// We want to limit the number of imported modules as much as possible
|
||||
/* eslint-disable no-restricted-imports */
|
||||
|
||||
import { onMount } from 'svelte'
|
||||
|
||||
// Dev build breaks if this import is moved to `$lib/web` ¯\_(ツ)_/¯
|
||||
import type { EventLogger } from '@sourcegraph/web/src/tracking/eventLogger'
|
||||
|
||||
import { PUBLIC_ENABLE_EVENT_LOGGER } from '$env/static/public'
|
||||
|
||||
/**
|
||||
* Can only be called during component initialization. It logs a view event when
|
||||
* the component is mounted (and event logging is enabled).
|
||||
*/
|
||||
export function logViewEvent(...args: Parameters<EventLogger['logViewEvent']>): void {
|
||||
export function logViewEvent(eventName: string, eventProperties?: any, publicArgument?: any): void {
|
||||
if (PUBLIC_ENABLE_EVENT_LOGGER) {
|
||||
onMount(() => {
|
||||
// TODO: Implement event logging
|
||||
console.log('logViewEvent', args)
|
||||
console.log('logViewEvent', eventName, eventProperties, publicArgument)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
export let title: string
|
||||
export let filterPlaceholder: string = ''
|
||||
export let showAll: boolean = false
|
||||
export let onFilterSelect: (kind: SectionItem['kind']) => void = () => {}
|
||||
|
||||
let filterText = ''
|
||||
$: processedFilterText = filterText.trim().toLowerCase()
|
||||
@ -37,6 +38,7 @@
|
||||
<a
|
||||
href={updateFilterInURL($page.url, item, item.selected).toString()}
|
||||
class:selected={item.selected}
|
||||
on:click={() => onFilterSelect(item.kind)}
|
||||
>
|
||||
<span class="label">
|
||||
<slot name="label" label={item.label} value={item.value}>
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
import LanguageIcon from '$lib/LanguageIcon.svelte'
|
||||
import CodeHostIcon from '$lib/search/CodeHostIcon.svelte'
|
||||
import SymbolKind from '$lib/search/SymbolKind.svelte'
|
||||
import { SVELTE_LOGGER, SVELTE_TELEMETRY_EVENTS } from '$lib/telemetry'
|
||||
import { displayRepoName, scanSearchQuery, type Filter } from '$lib/shared'
|
||||
import Tooltip from '$lib/Tooltip.svelte'
|
||||
import Button from '$lib/wildcard/Button.svelte'
|
||||
@ -75,11 +76,17 @@
|
||||
$: resetModifier = inferOperatingSystem(navigator.userAgent) === 'MacOS' ? '⌥' : 'Alt'
|
||||
$: resetURL = resetFilters($page.url).toString()
|
||||
$: enableReset = selectedFilters.length > 0
|
||||
|
||||
function handleResetKeydown(event: KeyboardEvent) {
|
||||
if (enableReset && event.altKey && event.key === 'Backspace') {
|
||||
goto(resetURL)
|
||||
}
|
||||
}
|
||||
|
||||
function handleFilterSelect(kind: SectionItem['kind']): void {
|
||||
SVELTE_LOGGER.log(SVELTE_TELEMETRY_EVENTS.SelectSearchFilter, { kind }, { kind })
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
window.addEventListener('keydown', handleResetKeydown)
|
||||
return () => window.removeEventListener('keydown', handleResetKeydown)
|
||||
@ -98,7 +105,7 @@
|
||||
</div>
|
||||
|
||||
{#if !queryHasTypeFilter(searchQuery)}
|
||||
<Section items={typeFilters} title="By type" showAll>
|
||||
<Section items={typeFilters} title="By type" showAll onFilterSelect={handleFilterSelect}>
|
||||
<svelte:fragment slot="label" let:label>
|
||||
<Icon svgPath={typeFilterIcons[label]} inline aria-hidden="true" />
|
||||
{label}
|
||||
@ -106,7 +113,12 @@
|
||||
</Section>
|
||||
{/if}
|
||||
|
||||
<Section items={groupedFilters.repo} title="By repository" filterPlaceholder="Filter repositories">
|
||||
<Section
|
||||
items={groupedFilters.repo}
|
||||
title="By repository"
|
||||
filterPlaceholder="Filter repositories"
|
||||
onFilterSelect={handleFilterSelect}
|
||||
>
|
||||
<svelte:fragment slot="label" let:label>
|
||||
<Tooltip tooltip={label} placement="right">
|
||||
<span>
|
||||
@ -116,27 +128,42 @@
|
||||
</Tooltip>
|
||||
</svelte:fragment>
|
||||
</Section>
|
||||
<Section items={groupedFilters.lang} title="By language" filterPlaceholder="Filter languages">
|
||||
<Section
|
||||
items={groupedFilters.lang}
|
||||
title="By language"
|
||||
filterPlaceholder="Filter languages"
|
||||
onFilterSelect={handleFilterSelect}
|
||||
>
|
||||
<svelte:fragment slot="label" let:label>
|
||||
<LanguageIcon class="icon" language={label} inline />
|
||||
{label}
|
||||
</svelte:fragment>
|
||||
</Section>
|
||||
<Section items={groupedFilters['symbol type']} title="By symbol type" filterPlaceholder="Filter symbol types">
|
||||
<Section
|
||||
items={groupedFilters['symbol type']}
|
||||
title="By symbol type"
|
||||
filterPlaceholder="Filter symbol types"
|
||||
onFilterSelect={handleFilterSelect}
|
||||
>
|
||||
<svelte:fragment slot="label" let:label>
|
||||
<SymbolKind symbolKind={label.toUpperCase()} />
|
||||
{label}
|
||||
</svelte:fragment>
|
||||
</Section>
|
||||
<Section items={groupedFilters.author} title="By author" filterPlaceholder="Filter authors" />
|
||||
<Section items={groupedFilters['commit date']} title="By commit date">
|
||||
<Section
|
||||
items={groupedFilters.author}
|
||||
title="By author"
|
||||
filterPlaceholder="Filter authors"
|
||||
onFilterSelect={handleFilterSelect}
|
||||
/>
|
||||
<Section items={groupedFilters['commit date']} title="By commit date" onFilterSelect={handleFilterSelect}>
|
||||
<span class="commit-date-label" slot="label" let:label let:value>
|
||||
{label}
|
||||
<small><pre>{value}</pre></small>
|
||||
</span>
|
||||
</Section>
|
||||
<Section items={groupedFilters.file} title="By file" showAll />
|
||||
<Section items={groupedFilters.utility} title="Utility" showAll />
|
||||
<Section items={groupedFilters.file} title="By file" showAll onFilterSelect={handleFilterSelect} />
|
||||
<Section items={groupedFilters.utility} title="Utility" showAll onFilterSelect={handleFilterSelect} />
|
||||
|
||||
{#if state === 'loading'}
|
||||
<LoadingSkeleton />
|
||||
|
||||
@ -117,6 +117,7 @@
|
||||
export let autoFocus = false
|
||||
export let size: 'normal' | 'compat' = 'normal'
|
||||
export let queryState: QueryStateStore
|
||||
export let onSubmit: (state: QueryState) => void = () => {}
|
||||
|
||||
export function focus() {
|
||||
input?.focus()
|
||||
@ -191,6 +192,7 @@
|
||||
event.preventDefault()
|
||||
if (!mode) {
|
||||
// Only submit query if you are not in history mode
|
||||
onSubmit($queryState)
|
||||
void submitQuery($queryState)
|
||||
}
|
||||
}
|
||||
|
||||
43
client/web-sveltekit/src/lib/telemetry.ts
Normal file
43
client/web-sveltekit/src/lib/telemetry.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import { EventLogger } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
|
||||
class SvelteTelemetry extends EventLogger {
|
||||
public override logViewEvent(event: string): void {
|
||||
super.logViewEvent(event, { isSveltePrototype: true })
|
||||
}
|
||||
|
||||
public override log(eventName: string, eventProperties?: any, publicArgument?: any): void {
|
||||
super.log(
|
||||
eventName,
|
||||
{ ...eventProperties, isSveltePrototype: true },
|
||||
{ ...publicArgument, isSveltePrototype: true }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export const SVELTE_LOGGER = new SvelteTelemetry()
|
||||
|
||||
// These events are minimal set of telemetry events that we
|
||||
// use in react version, note that names should be identical
|
||||
// with event names that we use in react
|
||||
export enum SVELTE_TELEMETRY_EVENTS {
|
||||
// Note that prefix 'View' will be added by EventLogger
|
||||
ViewHomePage = 'Home',
|
||||
ViewSearchResultsPage = 'SearchResults',
|
||||
ViewRepositoryPage = 'Repository',
|
||||
ViewBlobPage = 'Blob',
|
||||
|
||||
SearchSubmit = 'SearchSubmitted',
|
||||
SearchResultClick = 'SearchResultClicked',
|
||||
ShowHistoryPanel = 'ShowHistoryPanel',
|
||||
HideHistoryPanel = 'HideHistoryPanel',
|
||||
CodeCopied = 'CodeCopied',
|
||||
GoToCodeHost = 'GoToCodeHostClicked',
|
||||
GitBlameEnabled = 'GitBlameEnabled',
|
||||
SelectSearchFilter = 'SearchFiltersSelectFilter',
|
||||
}
|
||||
|
||||
export const codeCopiedEvent = (page: string): [string, { page: string }, { page: string }] => [
|
||||
SVELTE_TELEMETRY_EVENTS.CodeCopied,
|
||||
{ page },
|
||||
{ page },
|
||||
]
|
||||
@ -1,3 +1,21 @@
|
||||
<script context="module" lang="ts">
|
||||
import { SVELTE_LOGGER, SVELTE_TELEMETRY_EVENTS } from '$lib/telemetry'
|
||||
|
||||
// Not ideal solution, [TODO] Improve Tabs component API in order
|
||||
// to expose more info about nature of switch tab / close tab actions
|
||||
function trackHistoryPanelTabAction(selectedTab: number | null, nextSelectedTab: number | null) {
|
||||
if (nextSelectedTab === 0) {
|
||||
SVELTE_LOGGER.log(SVELTE_TELEMETRY_EVENTS.ShowHistoryPanel)
|
||||
return
|
||||
}
|
||||
|
||||
if (nextSelectedTab === null && selectedTab == 0) {
|
||||
SVELTE_LOGGER.log(SVELTE_TELEMETRY_EVENTS.HideHistoryPanel)
|
||||
return
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { tick } from 'svelte'
|
||||
|
||||
@ -51,6 +69,8 @@
|
||||
}
|
||||
|
||||
async function selectTab(event: { detail: number | null }) {
|
||||
trackHistoryPanelTabAction(selectedTab, event.detail)
|
||||
|
||||
if (event.detail === null) {
|
||||
const url = new URL($page.url)
|
||||
url.searchParams.delete('rev')
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
<script lang="ts">
|
||||
// @sg RepoRoot
|
||||
import Readme from '$lib/repo/Readme.svelte'
|
||||
import SidebarToggleButton from '$lib/repo/SidebarToggleButton.svelte'
|
||||
import { onMount } from 'svelte'
|
||||
|
||||
import { sidebarOpen } from '$lib/repo/stores'
|
||||
import { createPromiseStore } from '$lib/utils'
|
||||
import { SVELTE_LOGGER, SVELTE_TELEMETRY_EVENTS } from '$lib/telemetry'
|
||||
import Readme from '$lib/repo/Readme.svelte'
|
||||
import SidebarToggleButton from '$lib/repo/SidebarToggleButton.svelte'
|
||||
|
||||
import type { PageData } from './$types'
|
||||
import type { RepoPage_Readme } from './page.gql'
|
||||
@ -12,6 +15,10 @@
|
||||
|
||||
const readme = createPromiseStore<RepoPage_Readme | null>()
|
||||
$: readme.set(data.readme)
|
||||
|
||||
onMount(() => {
|
||||
SVELTE_LOGGER.logViewEvent(SVELTE_TELEMETRY_EVENTS.ViewRepositoryPage)
|
||||
})
|
||||
</script>
|
||||
|
||||
<h3 class="header">
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
<svelte:options immutable />
|
||||
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte'
|
||||
import { mdiFileEyeOutline, mdiMapSearch, mdiWrap, mdiWrapDisabled } from '@mdi/js'
|
||||
import { capitalize } from 'lodash'
|
||||
import { from } from 'rxjs'
|
||||
@ -8,6 +9,7 @@
|
||||
|
||||
import { afterNavigate, goto, preloadData } from '$app/navigation'
|
||||
import { page } from '$app/stores'
|
||||
import { SVELTE_LOGGER, SVELTE_TELEMETRY_EVENTS, codeCopiedEvent } from '$lib/telemetry'
|
||||
import type { ScrollSnapshot } from '$lib/codemirror/utils'
|
||||
import CodeMirrorBlob from '$lib/CodeMirrorBlob.svelte'
|
||||
import { isErrorLike, SourcegraphURL, type LineOrPositionOrRange, pluralize } from '$lib/common'
|
||||
@ -88,6 +90,10 @@
|
||||
},
|
||||
})
|
||||
|
||||
onMount(() => {
|
||||
SVELTE_LOGGER.logViewEvent(SVELTE_TELEMETRY_EVENTS.ViewBlobPage)
|
||||
})
|
||||
|
||||
afterNavigate(event => {
|
||||
// Only restore scroll position when the user used the browser history to navigate back
|
||||
// and forth. When the user reloads the page, in which case SvelteKit will also call
|
||||
@ -98,6 +104,19 @@
|
||||
}
|
||||
})
|
||||
|
||||
function handleCopy(): void {
|
||||
SVELTE_LOGGER.log(...codeCopiedEvent('blob-view'))
|
||||
}
|
||||
|
||||
function onViewModeChange(event: CustomEvent<ViewMode>): void {
|
||||
// TODO: track other blob mode
|
||||
if (event.detail === ViewMode.Blame) {
|
||||
SVELTE_LOGGER.log(SVELTE_TELEMETRY_EVENTS.GitBlameEnabled)
|
||||
}
|
||||
|
||||
goto(viewModeURL(event.detail), { replaceState: true, keepFocus: true })
|
||||
}
|
||||
|
||||
function viewModeURL(viewMode: ViewMode) {
|
||||
switch (viewMode) {
|
||||
case ViewMode.Code: {
|
||||
@ -176,7 +195,7 @@
|
||||
? [ViewMode.Default, ViewMode.Code, ViewMode.Blame]
|
||||
: [ViewMode.Default, ViewMode.Blame]}
|
||||
on:preload={event => preloadData(viewModeURL(event.detail))}
|
||||
on:change={event => goto(viewModeURL(event.detail), { replaceState: true, keepFocus: true })}
|
||||
on:change={onViewModeChange}
|
||||
>
|
||||
<svelte:fragment slot="label" let:value>
|
||||
{value === ViewMode.Default ? (isFormatted ? 'Formatted' : 'Code') : capitalize(value)}
|
||||
@ -241,6 +260,7 @@
|
||||
)
|
||||
}}
|
||||
{codeIntelAPI}
|
||||
onCopy={handleCopy}
|
||||
/>
|
||||
{/key}
|
||||
{:else if fileLoadingError}
|
||||
|
||||
@ -1,15 +1,20 @@
|
||||
<script lang="ts">
|
||||
import { SVELTE_LOGGER, SVELTE_TELEMETRY_EVENTS } from '$lib/telemetry'
|
||||
import Tooltip from '$lib/Tooltip.svelte'
|
||||
import { getHumanNameForCodeHost } from '$lib/repo/shared/codehost'
|
||||
import CodeHostIcon from '$lib/search/CodeHostIcon.svelte'
|
||||
import type { OpenInCodeHostAction } from './OpenInCodeHostAction.gql'
|
||||
|
||||
export let data: OpenInCodeHostAction
|
||||
|
||||
function handleOpenCodeHostClick(): void {
|
||||
SVELTE_LOGGER.log(SVELTE_TELEMETRY_EVENTS.GoToCodeHost)
|
||||
}
|
||||
</script>
|
||||
|
||||
{#each data.externalURLs as { url, serviceKind } (url)}
|
||||
<Tooltip tooltip="Open in code host">
|
||||
<a href={url} target="_blank" rel="noopener noreferrer">
|
||||
<a href={url} target="_blank" rel="noopener noreferrer" on:click={handleOpenCodeHostClick}>
|
||||
{#if serviceKind}
|
||||
<CodeHostIcon repository={serviceKind} disableTooltip />
|
||||
<span data-action-label>
|
||||
|
||||
@ -63,7 +63,7 @@
|
||||
<li
|
||||
class="location"
|
||||
class:selected
|
||||
on:click={() => selectedLocation = selected ? null : location}
|
||||
on:click={() => (selectedLocation = selected ? null : location)}
|
||||
>
|
||||
<span class="code-file">
|
||||
<span class="code">
|
||||
|
||||
@ -25,25 +25,39 @@
|
||||
|
||||
export let location: ReferencePanelCodeExcerpt_Location
|
||||
|
||||
$: plaintextLines = location.range ? getLines(location.resource).slice(location.range.start.line, location.range.end.line + 1) : []
|
||||
$: matches = location.range ? [{
|
||||
startLine: location.range.start.line,
|
||||
endLine: location.range.end.line,
|
||||
startCharacter: location.range.start.character,
|
||||
endCharacter: location.range.end.character,
|
||||
}] : []
|
||||
$: plaintextLines = location.range
|
||||
? getLines(location.resource).slice(location.range.start.line, location.range.end.line + 1)
|
||||
: []
|
||||
$: matches = location.range
|
||||
? [
|
||||
{
|
||||
startLine: location.range.start.line,
|
||||
endLine: location.range.end.line,
|
||||
startCharacter: location.range.start.character,
|
||||
endCharacter: location.range.end.character,
|
||||
},
|
||||
]
|
||||
: []
|
||||
|
||||
let visible = false
|
||||
// We rely on fetchFileRangeMatches to cache the result for us so that repeated
|
||||
// calls will not result in repeated network requests.
|
||||
$: highlightedHTMLRows = visible && location.range ? derived(toReadable(fetchFileRangeMatches({
|
||||
result: {
|
||||
repository: location.resource.repository.name,
|
||||
commit: location.resource.commit.oid,
|
||||
path: location.resource.path,
|
||||
},
|
||||
ranges: [{ startLine: location.range.start.line, endLine: location.range.end.line +1 }],
|
||||
})), result => result.value?.[0] || []) : readable([])
|
||||
$: highlightedHTMLRows =
|
||||
visible && location.range
|
||||
? derived(
|
||||
toReadable(
|
||||
fetchFileRangeMatches({
|
||||
result: {
|
||||
repository: location.resource.repository.name,
|
||||
commit: location.resource.commit.oid,
|
||||
path: location.resource.path,
|
||||
},
|
||||
ranges: [{ startLine: location.range.start.line, endLine: location.range.end.line + 1 }],
|
||||
})
|
||||
),
|
||||
result => result.value?.[0] || []
|
||||
)
|
||||
: readable([])
|
||||
</script>
|
||||
|
||||
{#if location.range && plaintextLines.length > 0}
|
||||
|
||||
@ -1,12 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { tick } from 'svelte'
|
||||
import { mdiMagnify } from '@mdi/js'
|
||||
import { createDialog } from '@melt-ui/svelte'
|
||||
|
||||
import Icon from '$lib/Icon.svelte'
|
||||
import SearchInput from '$lib/search/input/SearchInput.svelte'
|
||||
import { queryStateStore } from '$lib/search/state'
|
||||
import { QueryState, queryStateStore } from '$lib/search/state'
|
||||
import { settings } from '$lib/stores'
|
||||
import { mdiMagnify } from '@mdi/js'
|
||||
import { tick } from 'svelte'
|
||||
import { repositoryInsertText } from '$lib/shared'
|
||||
import { SVELTE_LOGGER, SVELTE_TELEMETRY_EVENTS } from '$lib/telemetry'
|
||||
|
||||
export let repoName: string
|
||||
|
||||
@ -18,6 +20,14 @@
|
||||
let searchInput: SearchInput | undefined
|
||||
let queryState = queryStateStore({ query: `repo:${repositoryInsertText({ repository: repoName })} ` }, $settings)
|
||||
|
||||
function handleSearchSubmit(state: QueryState): void {
|
||||
SVELTE_LOGGER.log(
|
||||
SVELTE_TELEMETRY_EVENTS.SearchSubmit,
|
||||
{ source: 'repo', query: state.query },
|
||||
{ source: 'repo', patternType: state.patternType }
|
||||
)
|
||||
}
|
||||
|
||||
$: if ($open) {
|
||||
// @melt-ui automatically focuses the search input but that positions the cursor at the
|
||||
// start of the input. We can move the cursor to the end by calling focus(), but we need
|
||||
@ -30,7 +40,7 @@
|
||||
<div class="wrapper">
|
||||
<div {...$overlay} use:overlay class="overlay" />
|
||||
<div {...$content} use:content>
|
||||
<SearchInput bind:this={searchInput} {queryState} />
|
||||
<SearchInput bind:this={searchInput} {queryState} onSubmit={handleSearchSubmit} />
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
<script lang="ts">
|
||||
import { setContext } from 'svelte'
|
||||
import { setContext, onMount } from 'svelte'
|
||||
|
||||
import { SVELTE_LOGGER, SVELTE_TELEMETRY_EVENTS } from '$lib/telemetry'
|
||||
import { logoLight, logoDark } from '$lib/images'
|
||||
import SearchInput from '$lib/search/input/SearchInput.svelte'
|
||||
import type { QueryStateStore } from '$lib/search/state'
|
||||
import type { QueryStateStore, QueryState } from '$lib/search/state'
|
||||
import type { SearchPageContext } from '$lib/search/utils'
|
||||
import { isLightTheme } from '$lib/stores'
|
||||
|
||||
@ -16,13 +17,25 @@
|
||||
queryState.setQuery(newQuery)
|
||||
},
|
||||
})
|
||||
|
||||
onMount(() => {
|
||||
SVELTE_LOGGER.logViewEvent(SVELTE_TELEMETRY_EVENTS.ViewHomePage)
|
||||
})
|
||||
|
||||
function handleSubmit(state: QueryState) {
|
||||
SVELTE_LOGGER.log(
|
||||
SVELTE_TELEMETRY_EVENTS.SearchSubmit,
|
||||
{ source: 'home', query: state.query },
|
||||
{ source: 'home', patternType: state.patternType }
|
||||
)
|
||||
}
|
||||
</script>
|
||||
|
||||
<section>
|
||||
<div class="content">
|
||||
<img class="logo" src={$isLightTheme ? logoLight : logoDark} alt="Sourcegraph Logo" />
|
||||
<div class="search">
|
||||
<SearchInput {queryState} autoFocus />
|
||||
<SearchInput {queryState} autoFocus onSubmit={handleSubmit} />
|
||||
<SearchHomeNotifications />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -16,19 +16,16 @@
|
||||
<script lang="ts">
|
||||
import { mdiCloseOctagonOutline } from '@mdi/js'
|
||||
import type { Observable } from 'rxjs'
|
||||
import { tick } from 'svelte'
|
||||
import { onMount, tick } from 'svelte'
|
||||
import { writable } from 'svelte/store'
|
||||
|
||||
import { beforeNavigate, goto } from '$app/navigation'
|
||||
import { limitHit } from '$lib/branded'
|
||||
import Icon from '$lib/Icon.svelte'
|
||||
import { observeIntersection } from '$lib/intersection-observer'
|
||||
import GlobalHeaderPortal from '$lib/navigation/GlobalHeaderPortal.svelte'
|
||||
import type { URLQueryFilter } from '$lib/search/dynamicFilters'
|
||||
import DynamicFiltersSidebar from '$lib/search/dynamicFilters/Sidebar.svelte'
|
||||
import { createRecentSearchesStore } from '$lib/search/input/recentSearches'
|
||||
import SearchInput from '$lib/search/input/SearchInput.svelte'
|
||||
import { getQueryURL, type QueryStateStore } from '$lib/search/state'
|
||||
import { SVELTE_LOGGER, SVELTE_TELEMETRY_EVENTS, codeCopiedEvent } from '$lib/telemetry'
|
||||
import {
|
||||
type AggregateStreamingSearchResults,
|
||||
type PathMatch,
|
||||
@ -36,9 +33,14 @@
|
||||
type SymbolMatch,
|
||||
type ContentMatch,
|
||||
} from '$lib/shared'
|
||||
import type { QueryState } from '$lib/search/state'
|
||||
import Icon from '$lib/Icon.svelte'
|
||||
import Panel from '$lib/wildcard/resizable-panel/Panel.svelte'
|
||||
import PanelGroup from '$lib/wildcard/resizable-panel/PanelGroup.svelte'
|
||||
import PanelResizeHandle from '$lib/wildcard/resizable-panel/PanelResizeHandle.svelte'
|
||||
import SearchInput from '$lib/search/input/SearchInput.svelte'
|
||||
import DynamicFiltersSidebar from '$lib/search/dynamicFilters/Sidebar.svelte'
|
||||
import GlobalHeaderPortal from '$lib/navigation/GlobalHeaderPortal.svelte'
|
||||
|
||||
import PreviewPanel from './PreviewPanel.svelte'
|
||||
import SearchAlert from './SearchAlert.svelte'
|
||||
@ -99,10 +101,15 @@
|
||||
},
|
||||
queryState,
|
||||
})
|
||||
|
||||
beforeNavigate(() => {
|
||||
cache.set(queryFromURL, { count, expanded: expandedSet, preview: $previewResult })
|
||||
})
|
||||
|
||||
onMount(() => {
|
||||
SVELTE_LOGGER.logViewEvent(SVELTE_TELEMETRY_EVENTS.ViewSearchResultsPage)
|
||||
})
|
||||
|
||||
function loadMore(event: { detail: boolean }) {
|
||||
if (event.detail) {
|
||||
count += INCREMENTAL_ITEMS_TO_SHOW
|
||||
@ -121,6 +128,22 @@
|
||||
await tick()
|
||||
void goto(getQueryURL($queryState))
|
||||
}
|
||||
|
||||
function handleResultCopy(): void {
|
||||
SVELTE_LOGGER.log(...codeCopiedEvent('search-result'))
|
||||
}
|
||||
|
||||
function handleSearchResultClick(): void {
|
||||
SVELTE_LOGGER.log(SVELTE_TELEMETRY_EVENTS.SearchResultClick)
|
||||
}
|
||||
|
||||
function handleSubmit(state: QueryState) {
|
||||
SVELTE_LOGGER.log(
|
||||
SVELTE_TELEMETRY_EVENTS.SearchSubmit,
|
||||
{ source: 'nav', query: state.query },
|
||||
{ source: 'nav', patternType: state.patternType }
|
||||
)
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
@ -129,7 +152,7 @@
|
||||
|
||||
<GlobalHeaderPortal>
|
||||
<div class="search-header">
|
||||
<SearchInput {queryState} size="compat" />
|
||||
<SearchInput {queryState} size="compat" onSubmit={handleSubmit} />
|
||||
</div>
|
||||
</GlobalHeaderPortal>
|
||||
|
||||
@ -155,7 +178,7 @@
|
||||
<SearchAlert alert={$stream.alert} />
|
||||
</div>
|
||||
{/if}
|
||||
<ol>
|
||||
<ol on:click={handleSearchResultClick} on:copy={handleResultCopy}>
|
||||
{#each resultsToShow as result, i}
|
||||
{@const component = getSearchResultComponent(result)}
|
||||
{#if i === resultsToShow.length - 1}
|
||||
|
||||
@ -1674,12 +1674,6 @@ ts_project(
|
||||
"src/tour/components/withErrorBoundary.tsx",
|
||||
"src/tour/data/index.tsx",
|
||||
"src/tour/hooks.ts",
|
||||
"src/tracking/TelemetricLink.tsx",
|
||||
"src/tracking/cookies.ts",
|
||||
"src/tracking/eventLogger.ts",
|
||||
"src/tracking/services/serverAdminWrapper.tsx",
|
||||
"src/tracking/sessionTracker.ts",
|
||||
"src/tracking/userTracker.ts",
|
||||
"src/tracking/util.ts",
|
||||
"src/types/fzy.js/index.d.ts",
|
||||
"src/user/area/UserArea.tsx",
|
||||
@ -1790,7 +1784,6 @@ ts_project(
|
||||
"//:node_modules/@types/d3-scale-chromatic",
|
||||
"//:node_modules/@types/d3-time-format",
|
||||
"//:node_modules/@types/history",
|
||||
"//:node_modules/@types/js-cookie",
|
||||
"//:node_modules/@types/js-yaml",
|
||||
"//:node_modules/@types/lodash",
|
||||
"//:node_modules/@types/lru-cache",
|
||||
@ -1825,7 +1818,6 @@ ts_project(
|
||||
"//:node_modules/http-status-codes",
|
||||
"//:node_modules/ignore",
|
||||
"//:node_modules/is-absolute-url",
|
||||
"//:node_modules/js-cookie",
|
||||
"//:node_modules/js-yaml",
|
||||
"//:node_modules/jsonc-parser",
|
||||
"//:node_modules/linguist-languages",
|
||||
@ -1997,7 +1989,6 @@ ts_project(
|
||||
"src/testSetup.test.ts",
|
||||
"src/tour/components/Tour/Tour.test.tsx",
|
||||
"src/tour/components/Tour/useTour.test.tsx",
|
||||
"src/tracking/userTracker.test.ts",
|
||||
"src/tracking/util.test.ts",
|
||||
"src/user/index.test.ts",
|
||||
"src/user/settings/auth/ExternalAccount.test.tsx",
|
||||
|
||||
@ -19,6 +19,7 @@ import {
|
||||
import { aggregateStreamingSearch } from '@sourcegraph/shared/src/search/stream'
|
||||
import type { 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 { isBatchChangesExecutionEnabled } from './batches'
|
||||
import { useBreadcrumbs, type BreadcrumbSetters, type BreadcrumbsProps } from './components/Breadcrumbs'
|
||||
@ -26,7 +27,6 @@ import { NotFoundPage } from './components/HeroPage'
|
||||
import type { SearchStreamingProps } from './search'
|
||||
import type { StaticSourcegraphWebAppContext, DynamicSourcegraphWebAppContext } from './SourcegraphWebApp'
|
||||
import type { StaticAppConfig } from './staticAppConfig'
|
||||
import { eventLogger } from './tracking/eventLogger'
|
||||
import { getLicenseFeatures } from './util/license'
|
||||
|
||||
export interface StaticLegacyRouteContext extends LegacyRouteComputedContext, LegacyRouteStaticInjections {}
|
||||
@ -151,7 +151,7 @@ export const LegacyRouteContextProvider: FC<PropsWithChildren<LegacyRouteContext
|
||||
*/
|
||||
streamSearch: aggregateStreamingSearch,
|
||||
fetchHighlightedFileLineRanges: _fetchHighlightedFileLineRanges,
|
||||
telemetryService: eventLogger,
|
||||
telemetryService: EVENT_LOGGER,
|
||||
telemetryRecorder: platformContext.telemetryRecorder,
|
||||
/**
|
||||
* Breadcrumb props
|
||||
|
||||
@ -35,6 +35,7 @@ import {
|
||||
import { TemporarySettingsProvider } from '@sourcegraph/shared/src/settings/temporary/TemporarySettingsProvider'
|
||||
import { TemporarySettingsStorage } from '@sourcegraph/shared/src/settings/temporary/TemporarySettingsStorage'
|
||||
import { NoOpTelemetryRecorderProvider } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { WildcardThemeContext, type WildcardTheme } from '@sourcegraph/wildcard'
|
||||
|
||||
import { authenticatedUser as authenticatedUserSubject, type AuthenticatedUser, authenticatedUserValue } from './auth'
|
||||
@ -53,7 +54,6 @@ import { GLOBAL_SEARCH_CONTEXT_SPEC } from './SearchQueryStateObserver'
|
||||
import type { StaticAppConfig } from './staticAppConfig'
|
||||
import { setQueryStateFromSettings, useDeveloperSettings, useNavbarQueryState } from './stores'
|
||||
import { TelemetryRecorderProvider } from './telemetry'
|
||||
import { eventLogger } from './tracking/eventLogger'
|
||||
import { UserSessionStores } from './UserSessionStores'
|
||||
import { getLicenseFeatures } from './util/license'
|
||||
import { siteSubjectNoAdmin, viewerSubjectFromSettings } from './util/settings'
|
||||
@ -224,7 +224,7 @@ export class LegacySourcegraphWebApp extends React.Component<StaticAppConfig, Le
|
||||
batchChangesExecutionEnabled={isBatchChangesExecutionEnabled(this.state.settingsCascade)}
|
||||
batchChangesWebhookLogsEnabled={window.context.batchChangesWebhookLogsEnabled}
|
||||
fetchHighlightedFileLineRanges={this.fetchHighlightedFileLineRanges}
|
||||
telemetryService={eventLogger}
|
||||
telemetryService={EVENT_LOGGER}
|
||||
telemetryRecorder={window.context.telemetryRecorder}
|
||||
isSourcegraphDotCom={window.context.sourcegraphDotComMode}
|
||||
isSearchContextSpecAvailable={isSearchContextSpecAvailable}
|
||||
|
||||
@ -9,10 +9,10 @@ import { catchError, debounceTime } from 'rxjs/operators'
|
||||
|
||||
import { asError, type ErrorLike, isErrorLike, logger } from '@sourcegraph/common'
|
||||
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { LoadingSpinner, ErrorAlert } from '@sourcegraph/wildcard'
|
||||
|
||||
import { PageTitle } from '../components/PageTitle'
|
||||
import { eventLogger } from '../tracking/eventLogger'
|
||||
|
||||
import { ApiConsoleToolbar } from './ApiConsoleToolbar'
|
||||
|
||||
@ -104,7 +104,7 @@ class ApiConsoleInner extends React.PureComponent<InnerProps, State> {
|
||||
}
|
||||
|
||||
public componentDidMount(): void {
|
||||
eventLogger.logViewEvent('ApiConsole')
|
||||
EVENT_LOGGER.logViewEvent('ApiConsole')
|
||||
this.props.telemetryRecorder.recordEvent('api-console', 'view')
|
||||
|
||||
// Update the browser URL bar when query/variables/operation name are
|
||||
|
||||
@ -3,13 +3,13 @@ import React, { useEffect, useState } from 'react'
|
||||
import { Navigate, Route, Routes, useLocation, useNavigate } from 'react-router-dom'
|
||||
|
||||
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Text, Link, ErrorAlert, Form, Input, TextArea, Container, Alert } from '@sourcegraph/wildcard'
|
||||
|
||||
import { LoaderButton } from '../components/LoaderButton'
|
||||
import { PageTitle } from '../components/PageTitle'
|
||||
import type { SourcegraphContext } from '../jscontext'
|
||||
import { PageRoutes } from '../routes.constants'
|
||||
import { eventLogger } from '../tracking/eventLogger'
|
||||
import { checkRequestAccessAllowed } from '../util/checkRequestAccessAllowed'
|
||||
|
||||
import { AuthPageWrapper } from './AuthPageWrapper'
|
||||
@ -124,7 +124,7 @@ export interface RequestAccessPageProps extends TelemetryV2Props {}
|
||||
*/
|
||||
export const RequestAccessPage: React.FunctionComponent<RequestAccessPageProps> = ({ telemetryRecorder }) => {
|
||||
useEffect(() => {
|
||||
eventLogger.logPageView('RequestAccessPage')
|
||||
EVENT_LOGGER.logPageView('RequestAccessPage')
|
||||
telemetryRecorder.recordEvent('auth.requestAccess', 'view')
|
||||
}, [telemetryRecorder])
|
||||
const location = useLocation()
|
||||
|
||||
@ -4,13 +4,13 @@ import { useLocation } from 'react-router-dom'
|
||||
|
||||
import { asError, type ErrorLike, isErrorLike, logger } from '@sourcegraph/common'
|
||||
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Button, Link, LoadingSpinner, Alert, Text, Input, ErrorAlert, Form, Container } from '@sourcegraph/wildcard'
|
||||
|
||||
import type { AuthenticatedUser } from '../auth'
|
||||
import { LoaderButton } from '../components/LoaderButton'
|
||||
import { PageTitle } from '../components/PageTitle'
|
||||
import type { SourcegraphContext } from '../jscontext'
|
||||
import { eventLogger } from '../tracking/eventLogger'
|
||||
|
||||
import { AuthPageWrapper } from './AuthPageWrapper'
|
||||
import { PasswordInput } from './SignInSignUpCommon'
|
||||
@ -239,7 +239,7 @@ export const ResetPasswordPage: React.FunctionComponent<ResetPasswordPageProps>
|
||||
const location = useLocation()
|
||||
|
||||
React.useEffect(() => {
|
||||
eventLogger.logViewEvent('ResetPassword', false)
|
||||
EVENT_LOGGER.logViewEvent('ResetPassword', false)
|
||||
props.telemetryRecorder.recordEvent('auth.resetPassword', 'view')
|
||||
}, [props.telemetryRecorder])
|
||||
|
||||
|
||||
@ -6,12 +6,12 @@ import { partition } from 'lodash'
|
||||
import { Navigate, useLocation, useSearchParams } from 'react-router-dom'
|
||||
|
||||
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Alert, Icon, Text, Link, Button, ErrorAlert, AnchorLink, Container } from '@sourcegraph/wildcard'
|
||||
|
||||
import type { AuthenticatedUser } from '../auth'
|
||||
import { PageTitle } from '../components/PageTitle'
|
||||
import type { AuthProvider, SourcegraphContext } from '../jscontext'
|
||||
import { eventLogger } from '../tracking/eventLogger'
|
||||
import { checkRequestAccessAllowed } from '../util/checkRequestAccessAllowed'
|
||||
|
||||
import { AuthPageWrapper } from './AuthPageWrapper'
|
||||
@ -40,7 +40,7 @@ export interface SignInPageProps extends TelemetryV2Props {
|
||||
export const SignInPage: React.FunctionComponent<React.PropsWithChildren<SignInPageProps>> = props => {
|
||||
const { context, authenticatedUser } = props
|
||||
useEffect(() => {
|
||||
eventLogger.logViewEvent('SignIn', null, false)
|
||||
EVENT_LOGGER.logViewEvent('SignIn', null, false)
|
||||
props.telemetryRecorder.recordEvent('auth.signIn', 'view')
|
||||
}, [props.telemetryRecorder])
|
||||
|
||||
@ -246,7 +246,7 @@ const SignUpNotice: React.FunctionComponent<SignUpNoticeProps> = ({
|
||||
<Link
|
||||
to="https://sourcegraph.com/get-started?t=enterprise"
|
||||
onClick={() => {
|
||||
eventLogger.log('ClickedOnEnterpriseCTA', { location: 'SignInPage' })
|
||||
EVENT_LOGGER.log('ClickedOnEnterpriseCTA', { location: 'SignInPage' })
|
||||
telemetryRecorder.recordEvent('auth.enterpriseCTA', 'click')
|
||||
}}
|
||||
>
|
||||
|
||||
@ -8,6 +8,7 @@ import { catchError, switchMap } from 'rxjs/operators'
|
||||
|
||||
import { asError } from '@sourcegraph/common'
|
||||
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import {
|
||||
useInputValidation,
|
||||
type ValidationOptions,
|
||||
@ -17,7 +18,6 @@ import { Link, Icon, Label, Text, Button, AnchorLink, LoaderInput, ErrorAlert }
|
||||
|
||||
import { LoaderButton } from '../components/LoaderButton'
|
||||
import type { AuthProvider, SourcegraphContext } from '../jscontext'
|
||||
import { eventLogger } from '../tracking/eventLogger'
|
||||
import { EventName, V2AuthProviderTypes } from '../util/constants'
|
||||
import { validatePassword, getPasswordRequirements } from '../util/security'
|
||||
|
||||
@ -110,14 +110,14 @@ export const SignUpForm: React.FunctionComponent<React.PropsWithChildren<SignUpF
|
||||
email: emailState.value,
|
||||
username: usernameState.value,
|
||||
password: passwordState.value,
|
||||
anonymousUserId: eventLogger.user.anonymousUserID,
|
||||
firstSourceUrl: eventLogger.session.getFirstSourceURL(),
|
||||
lastSourceUrl: eventLogger.session.getLastSourceURL(),
|
||||
anonymousUserId: EVENT_LOGGER.user.anonymousUserID,
|
||||
firstSourceUrl: EVENT_LOGGER.session.getFirstSourceURL(),
|
||||
lastSourceUrl: EVENT_LOGGER.session.getLastSourceURL(),
|
||||
}).catch(error => {
|
||||
setError(asError(error))
|
||||
setLoading(false)
|
||||
})
|
||||
eventLogger.log('InitiateSignUp')
|
||||
EVENT_LOGGER.log('InitiateSignUp')
|
||||
telemetryRecorder.recordEvent('auth', 'initiate', { metadata: { type: V2AuthProviderTypes.builtin } })
|
||||
},
|
||||
[onSignUp, disabled, emailState, usernameState, passwordState, telemetryRecorder]
|
||||
@ -129,7 +129,7 @@ export const SignUpForm: React.FunctionComponent<React.PropsWithChildren<SignUpF
|
||||
(type: AuthProvider['serviceType']) => () => {
|
||||
// TODO: Log events with keepalive=true to ensure they always outlive the webpage
|
||||
// https://github.com/sourcegraph/sourcegraph/issues/19174
|
||||
eventLogger.log(EventName.AUTH_INITIATED, { type }, { type })
|
||||
EVENT_LOGGER.log(EventName.AUTH_INITIATED, { type }, { type })
|
||||
telemetryRecorder.recordEvent('auth', 'initiate', { metadata: { type: V2AuthProviderTypes[type] } })
|
||||
},
|
||||
[telemetryRecorder]
|
||||
|
||||
@ -4,6 +4,7 @@ import { Navigate, useLocation } from 'react-router-dom'
|
||||
|
||||
import type { 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 { useIsLightTheme } from '@sourcegraph/shared/src/theme'
|
||||
import { Container, Link, Text } from '@sourcegraph/wildcard'
|
||||
|
||||
@ -11,7 +12,6 @@ import type { AuthenticatedUser } from '../auth'
|
||||
import { PageTitle } from '../components/PageTitle'
|
||||
import type { SourcegraphContext } from '../jscontext'
|
||||
import { PageRoutes } from '../routes.constants'
|
||||
import { eventLogger } from '../tracking/eventLogger'
|
||||
import { EventName } from '../util/constants'
|
||||
|
||||
import { AuthPageWrapper } from './AuthPageWrapper'
|
||||
@ -50,7 +50,7 @@ export const SignUpPage: React.FunctionComponent<React.PropsWithChildren<SignUpP
|
||||
const isLightTheme = useIsLightTheme()
|
||||
|
||||
useEffect(() => {
|
||||
eventLogger.logViewEvent('SignUp', null, false)
|
||||
EVENT_LOGGER.logViewEvent('SignUp', null, false)
|
||||
telemetryRecorder.recordEvent('auth.signUp', 'view', {
|
||||
metadata: { 'invited-by-user': invitedBy !== null ? 1 : 0 },
|
||||
})
|
||||
@ -60,7 +60,7 @@ export const SignUpPage: React.FunctionComponent<React.PropsWithChildren<SignUpP
|
||||
isAuthenticated: !!authenticatedUser,
|
||||
allowSignup: context.allowSignup,
|
||||
}
|
||||
eventLogger.log('SignUpInvitedByUser', parameters, parameters)
|
||||
EVENT_LOGGER.log('SignUpInvitedByUser', parameters, parameters)
|
||||
}
|
||||
}, [invitedBy, authenticatedUser, context.allowSignup, telemetryRecorder])
|
||||
|
||||
|
||||
@ -3,12 +3,12 @@ import React, { useEffect, useState } from 'react'
|
||||
import { Navigate, useLocation, useParams } from 'react-router-dom'
|
||||
|
||||
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Alert, Link, LoadingSpinner, ErrorAlert, Container } from '@sourcegraph/wildcard'
|
||||
|
||||
import type { AuthenticatedUser } from '../auth'
|
||||
import { PageTitle } from '../components/PageTitle'
|
||||
import type { SourcegraphContext } from '../jscontext'
|
||||
import { eventLogger } from '../tracking/eventLogger'
|
||||
|
||||
import { AuthPageWrapper } from './AuthPageWrapper'
|
||||
import { getReturnTo } from './SignInSignUpCommon'
|
||||
@ -52,11 +52,11 @@ export const UnlockAccountPage: React.FunctionComponent<React.PropsWithChildren<
|
||||
throw new Error('The url you provided is either expired or invalid.')
|
||||
}
|
||||
|
||||
eventLogger.log('OkUnlockAccount')
|
||||
EVENT_LOGGER.log('OkUnlockAccount')
|
||||
props.telemetryRecorder.recordEvent('auth.unlockAccount', 'success')
|
||||
} catch (error) {
|
||||
setError(error)
|
||||
eventLogger.log('KoUnlockAccount')
|
||||
EVENT_LOGGER.log('KoUnlockAccount')
|
||||
props.telemetryRecorder.recordEvent('auth.unlockAccount', 'fail')
|
||||
} finally {
|
||||
setLoading(false)
|
||||
@ -67,7 +67,7 @@ export const UnlockAccountPage: React.FunctionComponent<React.PropsWithChildren<
|
||||
if (props.authenticatedUser) {
|
||||
return
|
||||
}
|
||||
eventLogger.logPageView('UnlockUserAccountRequest', null, false)
|
||||
EVENT_LOGGER.logPageView('UnlockUserAccountRequest', null, false)
|
||||
props.telemetryRecorder.recordEvent('auth.unlockAccount', 'view')
|
||||
|
||||
unlockAccount().catch(error => {
|
||||
|
||||
@ -5,10 +5,10 @@ import { useLocation } from 'react-router-dom'
|
||||
|
||||
import { asError, logger } from '@sourcegraph/common'
|
||||
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Label, Button, LoadingSpinner, Link, Text, Input, Form } from '@sourcegraph/wildcard'
|
||||
|
||||
import type { SourcegraphContext } from '../jscontext'
|
||||
import { eventLogger } from '../tracking/eventLogger'
|
||||
import { V2AuthProviderTypes } from '../util/constants'
|
||||
|
||||
import { getReturnTo, PasswordInput } from './SignInSignUpCommon'
|
||||
@ -52,7 +52,7 @@ export const UsernamePasswordSignInForm: React.FunctionComponent<React.PropsWith
|
||||
}
|
||||
|
||||
setLoading(true)
|
||||
eventLogger.log('InitiateSignIn')
|
||||
EVENT_LOGGER.log('InitiateSignIn')
|
||||
telemetryRecorder.recordEvent('auth', 'initiate', { metadata: { type: V2AuthProviderTypes.builtin } })
|
||||
try {
|
||||
const response = await fetch('/-/sign-in', {
|
||||
|
||||
@ -24,9 +24,9 @@ import {
|
||||
} from '@sourcegraph/cody-ui'
|
||||
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 { Button, Icon, TextArea, Link, Tooltip, Alert, Text, H2 } from '@sourcegraph/wildcard'
|
||||
|
||||
import { eventLogger } from '../../../tracking/eventLogger'
|
||||
import { CodyPageIcon } from '../../chat/CodyPageIcon'
|
||||
import { isCodyEnabled, isEmailVerificationNeededForCody, isSignInRequiredForCody } from '../../isCodyEnabled'
|
||||
import { useCodySidebar } from '../../sidebar/Provider'
|
||||
@ -54,7 +54,7 @@ export const ChatUI: React.FC<IChatUIProps> = ({
|
||||
telemetryRecorder,
|
||||
}): JSX.Element => {
|
||||
const onFeedbackSubmit = (feedback: string): void => {
|
||||
eventLogger.log(`web:cody:feedbackSubmit:${feedback}`)
|
||||
EVENT_LOGGER.log(`web:cody:feedbackSubmit:${feedback}`)
|
||||
// TODO (dadlerj): update @sourcegraph/cody-ui/dist/Chat package to enforce a limited set of feedback strings.
|
||||
// Until then, this is a hack to avoid arbitrary event features.
|
||||
if (feedback === 'positive' || feedback === 'negative') {
|
||||
|
||||
@ -4,6 +4,7 @@ import { mdiChevronRight, mdiCodeBracesBox, mdiGit } from '@mdi/js'
|
||||
import classNames from 'classnames'
|
||||
|
||||
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Theme, useTheme } from '@sourcegraph/shared/src/theme'
|
||||
import { Badge, H1, H2, H3, H4, Icon, Link, PageHeader, Text } from '@sourcegraph/wildcard'
|
||||
|
||||
@ -14,7 +15,6 @@ import { Page } from '../../../components/Page'
|
||||
import { PageTitle } from '../../../components/PageTitle'
|
||||
import type { SourcegraphContext } from '../../../jscontext'
|
||||
import { MeetCodySVG } from '../../../repo/components/TryCodyWidget/WidgetIcons'
|
||||
import { eventLogger } from '../../../tracking/eventLogger'
|
||||
import { EventName } from '../../../util/constants'
|
||||
import { CodyColorIcon, CodyHelpIcon, CodyWorkIcon } from '../../chat/CodyPageIcon'
|
||||
|
||||
@ -29,7 +29,7 @@ interface CodyPlatformCardProps {
|
||||
|
||||
/* eslint-disable @sourcegraph/sourcegraph/check-help-links */
|
||||
|
||||
const onSpeakToAnEngineer = (): void => eventLogger.log(EventName.SPEAK_TO_AN_ENGINEER_CTA)
|
||||
const onSpeakToAnEngineer = (): void => EVENT_LOGGER.log(EventName.SPEAK_TO_AN_ENGINEER_CTA)
|
||||
|
||||
const IDEIcon: React.FunctionComponent<{}> = () => (
|
||||
<svg viewBox="-4 -4 31 31" fill="none" xmlns="http://www.w3.org/2000/svg" className={styles.codyPlatformCardIcon}>
|
||||
@ -182,7 +182,7 @@ export const CodyMarketingPage: React.FunctionComponent<CodyMarketingPageProps>
|
||||
ctaClassName={styles.authButton}
|
||||
iconClassName={styles.buttonIcon}
|
||||
telemetryRecorder={telemetryRecorder}
|
||||
telemetryService={eventLogger}
|
||||
telemetryService={EVENT_LOGGER}
|
||||
/>
|
||||
</div>
|
||||
<Text className="mt-3 mb-0">
|
||||
|
||||
@ -3,10 +3,10 @@ import { useState, useEffect } from 'react'
|
||||
import classNames from 'classnames'
|
||||
|
||||
import type { TelemetryRecorder } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { useIsLightTheme } from '@sourcegraph/shared/src/theme'
|
||||
import { Text, Button } from '@sourcegraph/wildcard'
|
||||
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
import { EventName } from '../../util/constants'
|
||||
|
||||
import styles from './CodyOnboarding.module.scss'
|
||||
@ -23,7 +23,7 @@ export function WelcomeStep({
|
||||
const [show, setShow] = useState(false)
|
||||
const isLightTheme = useIsLightTheme()
|
||||
useEffect(() => {
|
||||
eventLogger.log(
|
||||
EVENT_LOGGER.log(
|
||||
EventName.CODY_ONBOARDING_WELCOME_VIEWED,
|
||||
{ tier: pro ? 'pro' : 'free' },
|
||||
{ tier: pro ? 'pro' : 'free' }
|
||||
|
||||
@ -3,9 +3,9 @@ import { useState, useEffect } from 'react'
|
||||
import classNames from 'classnames'
|
||||
|
||||
import type { TelemetryRecorder } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Button, H2, Link, Text } from '@sourcegraph/wildcard'
|
||||
|
||||
import { eventLogger } from '../../../tracking/eventLogger'
|
||||
import { EventName } from '../../../util/constants'
|
||||
import { EditorStep } from '../../management/CodyManagementPage'
|
||||
|
||||
@ -29,10 +29,10 @@ export function JetBrainsInstructions({
|
||||
|
||||
useEffect(() => {
|
||||
if (step === EditorStep.SetupInstructions) {
|
||||
eventLogger.log(EventName.CODY_EDITOR_SETUP_VIEWED, { editor: 'JetBrains' })
|
||||
EVENT_LOGGER.log(EventName.CODY_EDITOR_SETUP_VIEWED, { editor: 'JetBrains' })
|
||||
telemetryRecorder.recordEvent('cody.editorSetupPage', 'view', { metadata: { jetBrains: 1 } })
|
||||
} else if (step === EditorStep.CodyFeatures) {
|
||||
eventLogger.log(EventName.CODY_EDITOR_FEATURES_VIEWED, { editor: 'JetBrains' })
|
||||
EVENT_LOGGER.log(EventName.CODY_EDITOR_FEATURES_VIEWED, { editor: 'JetBrains' })
|
||||
telemetryRecorder.recordEvent('cody.editorFeaturesPage', 'view', { metadata: { jetBrains: 1 } })
|
||||
}
|
||||
}, [step, telemetryRecorder])
|
||||
@ -60,7 +60,7 @@ export function JetBrainsInstructions({
|
||||
rel="noopener"
|
||||
onClick={event => {
|
||||
event.preventDefault()
|
||||
eventLogger.log(EventName.CODY_EDITOR_SETUP_OPEN_MARKETPLACE, {
|
||||
EVENT_LOGGER.log(EventName.CODY_EDITOR_SETUP_OPEN_MARKETPLACE, {
|
||||
editor: 'JetBrains',
|
||||
})
|
||||
telemetryRecorder.recordEvent(
|
||||
|
||||
@ -3,9 +3,9 @@ import { useState, useEffect } from 'react'
|
||||
import classNames from 'classnames'
|
||||
|
||||
import type { TelemetryRecorder } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Button, ButtonLink, H2, Text } from '@sourcegraph/wildcard'
|
||||
|
||||
import { eventLogger } from '../../../tracking/eventLogger'
|
||||
import { EventName } from '../../../util/constants'
|
||||
import { EditorStep } from '../../management/CodyManagementPage'
|
||||
|
||||
@ -29,10 +29,10 @@ export function NeoVimInstructions({
|
||||
|
||||
useEffect(() => {
|
||||
if (step === EditorStep.SetupInstructions) {
|
||||
eventLogger.log(EventName.CODY_EDITOR_SETUP_VIEWED, { editor: 'NeoVim' })
|
||||
EVENT_LOGGER.log(EventName.CODY_EDITOR_SETUP_VIEWED, { editor: 'NeoVim' })
|
||||
telemetryRecorder.recordEvent('cody.editorSetupPage', 'view', { metadata: { neoVim: 1 } })
|
||||
} else if (step === EditorStep.CodyFeatures) {
|
||||
eventLogger.log(EventName.CODY_EDITOR_FEATURES_VIEWED, { editor: 'NeoVim' })
|
||||
EVENT_LOGGER.log(EventName.CODY_EDITOR_FEATURES_VIEWED, { editor: 'NeoVim' })
|
||||
telemetryRecorder.recordEvent('cody.editorFeaturesPage', 'view', { metadata: { neoVim: 1 } })
|
||||
}
|
||||
}, [step, telemetryRecorder])
|
||||
@ -68,7 +68,7 @@ export function NeoVimInstructions({
|
||||
target="_blank"
|
||||
onClick={event => {
|
||||
event.preventDefault()
|
||||
eventLogger.log(EventName.CODY_EDITOR_SETUP_OPEN_MARKETPLACE, {
|
||||
EVENT_LOGGER.log(EventName.CODY_EDITOR_SETUP_OPEN_MARKETPLACE, {
|
||||
editor: 'NeoVim',
|
||||
})
|
||||
telemetryRecorder.recordEvent('cody.onboarding.openMarketplace', 'click', {
|
||||
|
||||
@ -3,9 +3,9 @@ import { useState, useEffect } from 'react'
|
||||
import classNames from 'classnames'
|
||||
|
||||
import type { TelemetryRecorder } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Button, ButtonLink, H2, Text } from '@sourcegraph/wildcard'
|
||||
|
||||
import { eventLogger } from '../../../tracking/eventLogger'
|
||||
import { EventName } from '../../../util/constants'
|
||||
import { EditorStep } from '../../management/CodyManagementPage'
|
||||
|
||||
@ -29,10 +29,10 @@ export function VSCodeInstructions({
|
||||
|
||||
useEffect(() => {
|
||||
if (step === EditorStep.SetupInstructions) {
|
||||
eventLogger.log(EventName.CODY_EDITOR_SETUP_VIEWED, { editor: 'VS Code' })
|
||||
EVENT_LOGGER.log(EventName.CODY_EDITOR_SETUP_VIEWED, { editor: 'VS Code' })
|
||||
telemetryRecorder.recordEvent('cody.editorSetupPage', 'view', { metadata: { vsCode: 1 } })
|
||||
} else if (step === EditorStep.CodyFeatures) {
|
||||
eventLogger.log(EventName.CODY_EDITOR_FEATURES_VIEWED, { editor: 'VS Code' })
|
||||
EVENT_LOGGER.log(EventName.CODY_EDITOR_FEATURES_VIEWED, { editor: 'VS Code' })
|
||||
telemetryRecorder.recordEvent('cody.editorFeaturesPage', 'view', { metadata: { vsCode: 1 } })
|
||||
}
|
||||
}, [step, telemetryRecorder])
|
||||
@ -69,7 +69,7 @@ export function VSCodeInstructions({
|
||||
target="_blank"
|
||||
onClick={event => {
|
||||
event.preventDefault()
|
||||
eventLogger.log(EventName.CODY_EDITOR_SETUP_OPEN_MARKETPLACE, {
|
||||
EVENT_LOGGER.log(EventName.CODY_EDITOR_SETUP_OPEN_MARKETPLACE, {
|
||||
editor: 'VS Code',
|
||||
})
|
||||
telemetryRecorder.recordEvent('cody.onboarding.openMarketplace', 'click', {
|
||||
|
||||
@ -7,6 +7,7 @@ import type { AuthenticatedUser } from '@sourcegraph/shared/src/auth'
|
||||
import { SearchPatternType } from '@sourcegraph/shared/src/graphql-operations'
|
||||
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import type { TelemetryService } from '@sourcegraph/shared/src/telemetry/telemetryService'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { useIsLightTheme } from '@sourcegraph/shared/src/theme'
|
||||
import { buildSearchURLQuery } from '@sourcegraph/shared/src/util/url'
|
||||
import { Alert, Form, Input, LoadingSpinner, Text, Badge, Link, useSessionStorage } from '@sourcegraph/wildcard'
|
||||
@ -14,7 +15,6 @@ import { Alert, Form, Input, LoadingSpinner, Text, Badge, Link, useSessionStorag
|
||||
import { BrandLogo } from '../../components/branding/BrandLogo'
|
||||
import { useFeatureFlag } from '../../featureFlags/useFeatureFlag'
|
||||
import { useURLSyncedString } from '../../hooks/useUrlSyncedString'
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
import { DOTCOM_URL } from '../../tracking/util'
|
||||
import { CodyIcon } from '../components/CodyIcon'
|
||||
import { isEmailVerificationNeededForCody } from '../isCodyEnabled'
|
||||
@ -40,7 +40,7 @@ export const CodySearchPage: React.FunctionComponent<CodeSearchPageProps> = ({
|
||||
telemetryRecorder,
|
||||
}) => {
|
||||
useEffect(() => {
|
||||
eventLogger.logPageView('CodySearch')
|
||||
EVENT_LOGGER.logPageView('CodySearch')
|
||||
telemetryRecorder.recordEvent('cody.search', 'view')
|
||||
}, [telemetryRecorder])
|
||||
|
||||
@ -70,7 +70,7 @@ export const CodySearchPage: React.FunctionComponent<CodeSearchPageProps> = ({
|
||||
return
|
||||
}
|
||||
|
||||
eventLogger.log(
|
||||
EVENT_LOGGER.log(
|
||||
'web:codySearch:submit',
|
||||
!isPrivateInstance ? { input: sanitizedInput } : null,
|
||||
!isPrivateInstance ? { input: sanitizedInput } : null
|
||||
@ -82,7 +82,7 @@ export const CodySearchPage: React.FunctionComponent<CodeSearchPageProps> = ({
|
||||
setLoading(false)
|
||||
|
||||
if (query) {
|
||||
eventLogger.log(
|
||||
EVENT_LOGGER.log(
|
||||
'web:codySearch:submitSucceeded',
|
||||
!isPrivateInstance ? { input: sanitizedInput, translatedQuery: query } : null,
|
||||
!isPrivateInstance ? { input: sanitizedInput, translatedQuery: query } : null
|
||||
@ -94,7 +94,7 @@ export const CodySearchPage: React.FunctionComponent<CodeSearchPageProps> = ({
|
||||
search: buildSearchURLQuery(query, SearchPatternType.regexp, false) + '&ref=cody-search',
|
||||
})
|
||||
} else {
|
||||
eventLogger.log(
|
||||
EVENT_LOGGER.log(
|
||||
'web:codySearch:submitFailed',
|
||||
!isPrivateInstance ? { input: sanitizedInput, reason: 'untranslatable' } : null,
|
||||
!isPrivateInstance ? { input: sanitizedInput, reason: 'untranslatable' } : null
|
||||
@ -107,7 +107,7 @@ export const CodySearchPage: React.FunctionComponent<CodeSearchPageProps> = ({
|
||||
},
|
||||
error => {
|
||||
telemetryRecorder.recordEvent('cody.search', 'fail')
|
||||
eventLogger.log(
|
||||
EVENT_LOGGER.log(
|
||||
'web:codySearch:submitFailed',
|
||||
!isPrivateInstance
|
||||
? {
|
||||
|
||||
@ -6,6 +6,7 @@ import { useNavigate } from 'react-router-dom'
|
||||
|
||||
import { useQuery } from '@sourcegraph/http-client'
|
||||
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
@ -25,7 +26,6 @@ import { Page } from '../../components/Page'
|
||||
import { PageTitle } from '../../components/PageTitle'
|
||||
import { CodySubscriptionPlan } from '../../graphql-operations'
|
||||
import type { UserCodyPlanResult, UserCodyPlanVariables } from '../../graphql-operations'
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
import { EventName } from '../../util/constants'
|
||||
import { CodyColorIcon } from '../chat/CodyPageIcon'
|
||||
import { useIsCodyPaymentsTestingMode } from '../featureFlags'
|
||||
@ -63,7 +63,7 @@ export const CodySubscriptionPage: React.FunctionComponent<CodySubscriptionPageP
|
||||
const manageSubscriptionRedirectURL = `${codyPaymentsUrl}/cody/subscription`
|
||||
|
||||
useEffect(() => {
|
||||
eventLogger.log(EventName.CODY_SUBSCRIPTION_PAGE_VIEWED, { utm_source }, { utm_source })
|
||||
EVENT_LOGGER.log(EventName.CODY_SUBSCRIPTION_PAGE_VIEWED, { utm_source }, { utm_source })
|
||||
telemetryRecorder.recordEvent('cody.planSelection', 'view')
|
||||
}, [utm_source, telemetryRecorder])
|
||||
|
||||
@ -98,7 +98,7 @@ export const CodySubscriptionPage: React.FunctionComponent<CodySubscriptionPageP
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={() => {
|
||||
eventLogger.log(EventName.CODY_MANAGE_SUBSCRIPTION_CLICKED)
|
||||
EVENT_LOGGER.log(EventName.CODY_MANAGE_SUBSCRIPTION_CLICKED)
|
||||
window.location.href = manageSubscriptionRedirectURL
|
||||
}}
|
||||
>
|
||||
@ -222,7 +222,7 @@ export const CodySubscriptionPage: React.FunctionComponent<CodySubscriptionPageP
|
||||
className="mb-0 text-muted d-inline cursor-pointer"
|
||||
size="small"
|
||||
onClick={() => {
|
||||
eventLogger.log(EventName.CODY_MANAGE_SUBSCRIPTION_CLICKED)
|
||||
EVENT_LOGGER.log(EventName.CODY_MANAGE_SUBSCRIPTION_CLICKED)
|
||||
telemetryRecorder.recordEvent('cody.planSelection', 'click', {
|
||||
metadata: { tier: 0 },
|
||||
})
|
||||
@ -236,7 +236,7 @@ export const CodySubscriptionPage: React.FunctionComponent<CodySubscriptionPageP
|
||||
className="flex-1"
|
||||
variant="primary"
|
||||
onClick={() => {
|
||||
eventLogger.log(
|
||||
EVENT_LOGGER.log(
|
||||
EventName.CODY_SUBSCRIPTION_PLAN_CLICKED,
|
||||
{ tier: 'pro' },
|
||||
{ tier: 'pro' }
|
||||
@ -352,7 +352,7 @@ export const CodySubscriptionPage: React.FunctionComponent<CodySubscriptionPageP
|
||||
to="https://sourcegraph.com/contact/request-info?utm_source=cody_subscription_page"
|
||||
target="_blank"
|
||||
onClick={() => {
|
||||
eventLogger.log(
|
||||
EVENT_LOGGER.log(
|
||||
EventName.CODY_SUBSCRIPTION_PLAN_CLICKED,
|
||||
{ tier: 'enterprise' },
|
||||
{ tier: 'enterprise' }
|
||||
|
||||
@ -13,9 +13,9 @@ import type {
|
||||
import { Transcript, useClient, NoopEditor } from '@sourcegraph/cody-shared'
|
||||
import type { Scalars } from '@sourcegraph/shared/src/graphql-operations'
|
||||
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { useLocalStorage } from '@sourcegraph/wildcard'
|
||||
|
||||
import { eventLogger } from '../tracking/eventLogger'
|
||||
import { EventName } from '../util/constants'
|
||||
|
||||
import { isEmailVerificationNeededForCody } from './isCodyEnabled'
|
||||
@ -196,7 +196,7 @@ export const useCodyChat = ({
|
||||
if (!transcript) {
|
||||
return
|
||||
}
|
||||
eventLogger.log(v1EventLabel, { transcriptId: transcript.id, ...eventProperties })
|
||||
EVENT_LOGGER.log(v1EventLabel, { transcriptId: transcript.id, ...eventProperties })
|
||||
|
||||
let numericID = new Date(transcript.id).getTime()
|
||||
if (isNaN(numericID)) {
|
||||
@ -257,7 +257,7 @@ export const useCodyChat = ({
|
||||
return
|
||||
}
|
||||
|
||||
eventLogger.log(EventName.CODY_CHAT_HISTORY_CLEARED)
|
||||
EVENT_LOGGER.log(EventName.CODY_CHAT_HISTORY_CLEARED)
|
||||
|
||||
const newTranscript = initializeNewChatInternal()
|
||||
if (newTranscript) {
|
||||
@ -360,7 +360,7 @@ export const useCodyChat = ({
|
||||
|
||||
const executeRecipe = useCallback<typeof executeRecipeInternal>(
|
||||
async (recipeId, options): Promise<Transcript | null> => {
|
||||
eventLogger.log(`web:codyChat:recipe:${recipeId}:executed`, { recipeId })
|
||||
EVENT_LOGGER.log(`web:codyChat:recipe:${recipeId}:executed`, { recipeId })
|
||||
|
||||
const transcript = await executeRecipeInternal(recipeId, options)
|
||||
|
||||
|
||||
@ -4,8 +4,8 @@ import { mdiCardBulletedOutline, mdiDotsVertical, mdiProgressPencil, mdiShuffleV
|
||||
|
||||
import { TranslateToLanguage } from '@sourcegraph/cody-shared'
|
||||
import type { TelemetryRecorder } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
import { EventName } from '../../util/constants'
|
||||
import type { CodeMirrorEditor } from '../components/CodeMirrorEditor'
|
||||
import type { useCodySidebar } from '../sidebar/Provider'
|
||||
@ -19,7 +19,7 @@ export const CodyRecipesWidget: React.FC<{ editor?: CodeMirrorEditor; telemetryR
|
||||
telemetryRecorder,
|
||||
}) => {
|
||||
useEffect(() => {
|
||||
eventLogger.log(EventName.CODY_CHAT_EDITOR_WIDGET_VIEWED)
|
||||
EVENT_LOGGER.log(EventName.CODY_CHAT_EDITOR_WIDGET_VIEWED)
|
||||
telemetryRecorder.recordEvent('cody.chat.editor-widget', 'view')
|
||||
}, [telemetryRecorder])
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ import React, { type FC, useState, useCallback, useRef, useEffect } from 'react'
|
||||
import { noop } from 'lodash'
|
||||
|
||||
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import {
|
||||
Alert,
|
||||
Container,
|
||||
@ -17,7 +18,6 @@ import {
|
||||
} from '@sourcegraph/wildcard'
|
||||
|
||||
import { GitHubAppDomain } from '../../graphql-operations'
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
import { PageTitle } from '../PageTitle'
|
||||
|
||||
interface StateResponse {
|
||||
@ -91,7 +91,7 @@ export const CreateGitHubAppPage: FC<CreateGitHubAppPageProps> = ({
|
||||
const [error, setError] = useState<string>()
|
||||
|
||||
useEffect(() => {
|
||||
eventLogger.logPageView('SiteAdminCreateGiHubApp')
|
||||
EVENT_LOGGER.logPageView('SiteAdminCreateGiHubApp')
|
||||
telemetryRecorder.recordEvent('admin.GitHubApp.create', 'view')
|
||||
}, [telemetryRecorder])
|
||||
|
||||
|
||||
@ -6,10 +6,10 @@ import { useLocation } from 'react-router-dom'
|
||||
|
||||
import { useQuery } from '@sourcegraph/http-client'
|
||||
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { ButtonLink, Container, ErrorAlert, Icon, Link, LoadingSpinner, PageHeader } from '@sourcegraph/wildcard'
|
||||
|
||||
import { type GitHubAppsResult, type GitHubAppsVariables, GitHubAppDomain } from '../../graphql-operations'
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
import {
|
||||
ConnectionContainer,
|
||||
ConnectionLoading,
|
||||
@ -38,7 +38,7 @@ export const GitHubAppsPage: React.FC<Props> = ({ batchChangesEnabled, telemetry
|
||||
const gitHubApps = useMemo(() => data?.gitHubApps?.nodes ?? [], [data])
|
||||
|
||||
useEffect(() => {
|
||||
eventLogger.logPageView('SiteAdminGitHubApps')
|
||||
EVENT_LOGGER.logPageView('SiteAdminGitHubApps')
|
||||
telemetryRecorder.recordEvent('admin.GitHubApps', 'view')
|
||||
}, [telemetryRecorder])
|
||||
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
import { type FC, useState } from 'react'
|
||||
|
||||
import {
|
||||
debugEventLoggingEnabled,
|
||||
setDebugEventLoggingEnabled,
|
||||
} from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Checkbox } from '@sourcegraph/wildcard'
|
||||
|
||||
import { debugEventLoggingEnabled, setDebugEventLoggingEnabled } from '../../tracking/eventLogger'
|
||||
|
||||
export const EventLoggingDebugToggle: FC<{}> = () => {
|
||||
const [enabled, setEnabled] = useState(debugEventLoggingEnabled())
|
||||
return (
|
||||
|
||||
@ -5,11 +5,11 @@ import { kebabCase } from 'lodash'
|
||||
|
||||
import { Timestamp } from '@sourcegraph/branded/src/components/Timestamp'
|
||||
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, Icon, Text, Tooltip, Button, AnchorLink } from '@sourcegraph/wildcard'
|
||||
|
||||
import type { BatchChangeFields } from '../../graphql-operations'
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
|
||||
import { MonacoBatchSpecEditor } from './batch-spec/edit/editor/MonacoBatchSpecEditor'
|
||||
|
||||
@ -68,7 +68,7 @@ export const BatchSpecDownloadLink: React.FunctionComponent<React.PropsWithChild
|
||||
telemetryRecorder,
|
||||
}) {
|
||||
const onClick: () => void = () => {
|
||||
eventLogger.log('batch_change_editor:download_for_src_cli:clicked')
|
||||
EVENT_LOGGER.log('batch_change_editor:download_for_src_cli:clicked')
|
||||
telemetryRecorder.recordEvent('batchChange.editor.downloadForCLI', 'click')
|
||||
}
|
||||
const component = asButton ? (
|
||||
|
||||
@ -5,6 +5,7 @@ import { VisuallyHidden } from '@reach/visually-hidden'
|
||||
import { animated } from 'react-spring'
|
||||
|
||||
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
@ -20,7 +21,6 @@ import {
|
||||
Tooltip,
|
||||
} from '@sourcegraph/wildcard'
|
||||
|
||||
import { eventLogger } from '../../../../tracking/eventLogger'
|
||||
import type { ExecutionOptions } from '../BatchSpecContext'
|
||||
|
||||
import styles from './RunBatchSpecButton.module.scss'
|
||||
@ -56,7 +56,7 @@ export const RunBatchSpecButton: React.FunctionComponent<React.PropsWithChildren
|
||||
variant="primary"
|
||||
onClick={() => {
|
||||
execute()
|
||||
eventLogger.log('batch_change_editor:run_batch_spec:clicked')
|
||||
EVENT_LOGGER.log('batch_change_editor:run_batch_spec:clicked')
|
||||
telemetryRecorder.recordEvent('batchChange.editor.runSpec', 'click')
|
||||
}}
|
||||
aria-label={typeof isExecutionDisabled === 'string' ? isExecutionDisabled : undefined}
|
||||
|
||||
@ -5,10 +5,10 @@ import { useLocation } from 'react-router-dom'
|
||||
import { animated, useSpring } from 'react-spring'
|
||||
|
||||
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Button, useLocalStorage, H3, H4, Icon, Link, Text, VIEWPORT_XL } from '@sourcegraph/wildcard'
|
||||
|
||||
import type { Scalars } from '../../../../../graphql-operations'
|
||||
import { eventLogger } from '../../../../../tracking/eventLogger'
|
||||
import { createRenderTemplate } from '../../../create/useSearchTemplate'
|
||||
import { insertNameIntoLibraryItem } from '../../yaml-util'
|
||||
|
||||
@ -134,7 +134,7 @@ export const LibraryPane: React.FunctionComponent<React.PropsWithChildren<Librar
|
||||
if (selectedItem && !('isReadOnly' in props && props.isReadOnly)) {
|
||||
const codeWithName = updateTemplateWithQueryAndName(selectedItem.code)
|
||||
const templateName = selectedItem.name
|
||||
eventLogger.log('batch_change_editor:template:loaded', { template: templateName })
|
||||
EVENT_LOGGER.log('batch_change_editor:template:loaded', { template: templateName })
|
||||
props.telemetryRecorder.recordEvent('batchChange.editor.template', 'load')
|
||||
props.onReplaceItem(codeWithName)
|
||||
setSelectedItem(undefined)
|
||||
@ -191,7 +191,7 @@ export const LibraryPane: React.FunctionComponent<React.PropsWithChildren<Librar
|
||||
rel="noopener noreferrer"
|
||||
to="https://github.com/sourcegraph/batch-change-examples"
|
||||
onClick={() => {
|
||||
eventLogger.log('batch_change_editor:view_more_examples:clicked')
|
||||
EVENT_LOGGER.log('batch_change_editor:view_more_examples:clicked')
|
||||
props.telemetryRecorder.recordEvent('batchChange.editor.viewMoreExamples', 'click')
|
||||
}}
|
||||
>
|
||||
|
||||
@ -7,6 +7,7 @@ import { animated, useSpring } from 'react-spring'
|
||||
|
||||
import { CodeSnippet } from '@sourcegraph/branded/src/components/CodeSnippet'
|
||||
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Alert, Button, H4, Icon, Tooltip, useAccordion, useStopwatch, ErrorAlert } from '@sourcegraph/wildcard'
|
||||
|
||||
import type { Connection } from '../../../../../components/FilteredConnection'
|
||||
@ -15,7 +16,6 @@ import {
|
||||
type PreviewHiddenBatchSpecWorkspaceFields,
|
||||
type PreviewVisibleBatchSpecWorkspaceFields,
|
||||
} from '../../../../../graphql-operations'
|
||||
import { eventLogger } from '../../../../../tracking/eventLogger'
|
||||
import { useBatchChangesLicense } from '../../../useBatchChangesLicense'
|
||||
import { Header as WorkspacesListHeader } from '../../../workspaces-list'
|
||||
import { type BatchSpecContextState, useBatchSpecContext } from '../../BatchSpecContext'
|
||||
@ -166,7 +166,7 @@ const MemoizedWorkspacesPreview: React.FunctionComponent<React.PropsWithChildren
|
||||
isWorkspacesPreviewInProgress
|
||||
? cancel
|
||||
: () => {
|
||||
eventLogger.log('batch_change_editor:preview_workspaces:clicked')
|
||||
EVENT_LOGGER.log('batch_change_editor:preview_workspaces:clicked')
|
||||
telemetryRecorder.recordEvent('batchChange.editor.previewWorkspaces', 'click')
|
||||
return preview(debouncedCode)
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import { useNavigate, useLocation } from 'react-router-dom'
|
||||
|
||||
import { useMutation } from '@sourcegraph/http-client'
|
||||
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import {
|
||||
Button,
|
||||
Icon,
|
||||
@ -28,7 +29,6 @@ import {
|
||||
type RetryBatchSpecExecutionResult,
|
||||
type RetryBatchSpecExecutionVariables,
|
||||
} from '../../../../graphql-operations'
|
||||
import { eventLogger } from '../../../../tracking/eventLogger'
|
||||
import { type BatchSpecContextState, useBatchSpecContext } from '../BatchSpecContext'
|
||||
|
||||
import { CANCEL_BATCH_SPEC_EXECUTION, RETRY_BATCH_SPEC_EXECUTION } from './backend'
|
||||
@ -172,7 +172,7 @@ const MemoizedActionsMenu: React.FunctionComponent<
|
||||
className={styles.previewButton}
|
||||
style={{ width: menuWidth }}
|
||||
onClick={() => {
|
||||
eventLogger.log('batch_change_execution:preview:clicked')
|
||||
EVENT_LOGGER.log('batch_change_execution:preview:clicked')
|
||||
telemetryRecorder.recordEvent('batchChange.execution', 'preview')
|
||||
}}
|
||||
>
|
||||
@ -232,12 +232,12 @@ const MemoizedActionsMenu: React.FunctionComponent<
|
||||
onConfirm={
|
||||
cancelModalType === 'cancel'
|
||||
? () => {
|
||||
eventLogger.log('batch_change_execution:actions_execution_cancel:clicked')
|
||||
EVENT_LOGGER.log('batch_change_execution:actions_execution_cancel:clicked')
|
||||
telemetryRecorder.recordEvent('batchChange.execution', 'cancel')
|
||||
return cancelBatchSpecExecution()
|
||||
}
|
||||
: () => {
|
||||
eventLogger.log('batch_change_execution:actions_execution_cancel_and_edit:clicked')
|
||||
EVENT_LOGGER.log('batch_change_execution:actions_execution_cancel_and_edit:clicked')
|
||||
telemetryRecorder.recordEvent('batchChange.execution', 'edit')
|
||||
return cancelAndEdit()
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ import indicator from 'ordinal/indicator'
|
||||
import { dataOrThrowErrors } from '@sourcegraph/http-client'
|
||||
import type { Maybe } from '@sourcegraph/shared/src/graphql-operations'
|
||||
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import {
|
||||
Badge,
|
||||
LoadingSpinner,
|
||||
@ -64,7 +65,6 @@ import {
|
||||
type BatchSpecWorkspaceStepResult,
|
||||
type BatchSpecWorkspaceStepVariables,
|
||||
} from '../../../../../graphql-operations'
|
||||
import { eventLogger } from '../../../../../tracking/eventLogger'
|
||||
import { queryChangesetSpecFileDiffs as _queryChangesetSpecFileDiffs } from '../../../preview/list/backend'
|
||||
import { ChangesetSpecFileDiffConnection } from '../../../preview/list/ChangesetSpecFileDiffConnection'
|
||||
import {
|
||||
@ -197,7 +197,7 @@ const WorkspaceHeader: React.FunctionComponent<React.PropsWithChildren<Workspace
|
||||
className={styles.workspaceDetail}
|
||||
onClick={() => {
|
||||
toggleShowDiagnostics()
|
||||
eventLogger.log('batch_change_execution:workspace_timeline:clicked')
|
||||
EVENT_LOGGER.log('batch_change_execution:workspace_timeline:clicked')
|
||||
telemetryRecorder.recordEvent('batchChange.execution.workspaceTimeline', 'click')
|
||||
}}
|
||||
variant="link"
|
||||
@ -640,7 +640,7 @@ const WorkspaceStep: React.FunctionComponent<React.PropsWithChildren<WorkspaceSt
|
||||
size="medium"
|
||||
behavior="forceRender"
|
||||
onChange={index => {
|
||||
eventLogger.log(`batch_change_execution:workspace_tab_${tabsNames[index]}:clicked`)
|
||||
EVENT_LOGGER.log(`batch_change_execution:workspace_tab_${tabsNames[index]}:clicked`)
|
||||
telemetryRecorder.recordEvent('batchChange.execution.tab', 'click', {
|
||||
metadata: { tab: index },
|
||||
})
|
||||
|
||||
@ -7,11 +7,11 @@ import { isErrorLike, asError } from '@sourcegraph/common'
|
||||
import type { Settings } from '@sourcegraph/shared/src/schema/settings.schema'
|
||||
import type { SettingsCascadeProps } from '@sourcegraph/shared/src/settings/settings'
|
||||
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Button, Link, Icon, Tooltip } from '@sourcegraph/wildcard'
|
||||
|
||||
import { isBatchChangesExecutionEnabled } from '../../../batches'
|
||||
import type { Scalars } from '../../../graphql-operations'
|
||||
import { eventLogger } from '../../../tracking/eventLogger'
|
||||
|
||||
import { deleteBatchChange as _deleteBatchChange } from './backend'
|
||||
|
||||
@ -81,7 +81,7 @@ export const BatchChangeDetailsActionSection: React.FunctionComponent<
|
||||
variant="secondary"
|
||||
as={Link}
|
||||
onClick={() => {
|
||||
eventLogger.log('batch_change_details:edit:clicked')
|
||||
EVENT_LOGGER.log('batch_change_details:edit:clicked')
|
||||
telemetryRecorder.recordEvent('batchChange.details', 'edit')
|
||||
}}
|
||||
>
|
||||
@ -96,7 +96,7 @@ export const BatchChangeDetailsActionSection: React.FunctionComponent<
|
||||
outline={true}
|
||||
as={Link}
|
||||
onClick={() => {
|
||||
eventLogger.log('batch_change_details:close:clicked')
|
||||
EVENT_LOGGER.log('batch_change_details:close:clicked')
|
||||
telemetryRecorder.recordEvent('batchChange.details', 'close')
|
||||
}}
|
||||
>
|
||||
|
||||
@ -5,10 +5,10 @@ import { of } from 'rxjs'
|
||||
|
||||
import { pluralize } from '@sourcegraph/common'
|
||||
import type { TelemetryRecorder, TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Button, useObservable, Icon } from '@sourcegraph/wildcard'
|
||||
|
||||
import { type AllChangesetIDsVariables, type Scalars, BulkOperationType } from '../../../../graphql-operations'
|
||||
import { eventLogger } from '../../../../tracking/eventLogger'
|
||||
import { type Action, DropdownButton } from '../../DropdownButton'
|
||||
import { MultiSelectContext } from '../../MultiSelectContext'
|
||||
import {
|
||||
@ -53,7 +53,7 @@ const AVAILABLE_ACTIONS: Record<BulkOperationType, ChangesetListAction> = {
|
||||
dropdownDescription:
|
||||
'Attempt to close all selected changesets on the code hosts. The changesets will remain part of the batch change.',
|
||||
onTrigger: (batchChangeID, changesetIDs, onDone, onCancel, telemetryRecorder) => {
|
||||
eventLogger.log('batch_change_details:bulk_action_close:clicked')
|
||||
EVENT_LOGGER.log('batch_change_details:bulk_action_close:clicked')
|
||||
telemetryRecorder.recordEvent('batchChange.details.bulkAction', 'close')
|
||||
return (
|
||||
<CloseChangesetsModal
|
||||
@ -72,7 +72,7 @@ const AVAILABLE_ACTIONS: Record<BulkOperationType, ChangesetListAction> = {
|
||||
dropdownDescription:
|
||||
'Create a comment on all selected changesets. For example, you could ask people for reviews, give an update, or post a cat GIF.',
|
||||
onTrigger: (batchChangeID, changesetIDs, onDone, onCancel, telemetryRecorder) => {
|
||||
eventLogger.log('batch_change_details:bulk_action_comment:clicked')
|
||||
EVENT_LOGGER.log('batch_change_details:bulk_action_comment:clicked')
|
||||
telemetryRecorder.recordEvent('batchChange.details.bulkAction', 'comment')
|
||||
return (
|
||||
<CreateCommentModal
|
||||
@ -97,7 +97,7 @@ const AVAILABLE_ACTIONS: Record<BulkOperationType, ChangesetListAction> = {
|
||||
changesetIDs={changesetIDs}
|
||||
afterCreate={onDone}
|
||||
onCancel={onCancel}
|
||||
telemetryService={eventLogger}
|
||||
telemetryService={EVENT_LOGGER}
|
||||
telemetryRecorder={telemetryRecorder}
|
||||
/>
|
||||
),
|
||||
@ -108,7 +108,7 @@ const AVAILABLE_ACTIONS: Record<BulkOperationType, ChangesetListAction> = {
|
||||
dropdownTitle: 'Export Changeset(s)',
|
||||
dropdownDescription: 'Export selected changesets',
|
||||
onTrigger: (batchChangeID, changesetIDs, onDone, onCancel, telemetryRecorder) => {
|
||||
eventLogger.log('batch_change_details:bulk_action_export:clicked')
|
||||
EVENT_LOGGER.log('batch_change_details:bulk_action_export:clicked')
|
||||
telemetryRecorder.recordEvent('batchChange.details.bulkAction', 'export')
|
||||
return (
|
||||
<ExportChangesetsModal
|
||||
@ -128,7 +128,7 @@ const AVAILABLE_ACTIONS: Record<BulkOperationType, ChangesetListAction> = {
|
||||
dropdownDescription:
|
||||
'Attempt to merge all selected changesets. Some changesets may be unmergeable if there are rules preventing merge, such as CI requirements.',
|
||||
onTrigger: (batchChangeID, changesetIDs, onDone, onCancel, telemetryRecorder) => {
|
||||
eventLogger.log('batch_change_details:bulk_action_merge:clicked')
|
||||
EVENT_LOGGER.log('batch_change_details:bulk_action_merge:clicked')
|
||||
telemetryRecorder.recordEvent('batchChange.details.bulkAction', 'merge')
|
||||
return (
|
||||
<MergeChangesetsModal
|
||||
@ -146,7 +146,7 @@ const AVAILABLE_ACTIONS: Record<BulkOperationType, ChangesetListAction> = {
|
||||
dropdownTitle: 'Publish changesets',
|
||||
dropdownDescription: 'Attempt to publish all selected changesets to the code hosts.',
|
||||
onTrigger: (batchChangeID, changesetIDs, onDone, onCancel, telemetryRecorder) => {
|
||||
eventLogger.log('batch_change_details:bulk_action_published:clicked')
|
||||
EVENT_LOGGER.log('batch_change_details:bulk_action_published:clicked')
|
||||
telemetryRecorder.recordEvent('batchChange.details.bulkAction', 'publish')
|
||||
return (
|
||||
<PublishChangesetsModal
|
||||
@ -164,7 +164,7 @@ const AVAILABLE_ACTIONS: Record<BulkOperationType, ChangesetListAction> = {
|
||||
dropdownTitle: 'Retry changesets',
|
||||
dropdownDescription: 'Re-enqueues the selected changesets for processing, if they failed.',
|
||||
onTrigger: (batchChangeID, changesetIDs, onDone, onCancel, telemetryRecorder) => {
|
||||
eventLogger.log('batch_change_details:bulk_action_retry:clicked')
|
||||
EVENT_LOGGER.log('batch_change_details:bulk_action_retry:clicked')
|
||||
telemetryRecorder.recordEvent('batchChange.details.bulkAction', 'retry')
|
||||
return (
|
||||
<ReenqueueChangesetsModal
|
||||
|
||||
@ -9,6 +9,7 @@ import type { Settings } from '@sourcegraph/shared/src/schema/settings.schema'
|
||||
import type { SettingsCascadeProps } from '@sourcegraph/shared/src/settings/settings'
|
||||
import type { 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, PageHeader, Link, Container, H3, Text, screenReaderAnnounce } from '@sourcegraph/wildcard'
|
||||
|
||||
import type { AuthenticatedUser } from '../../../auth'
|
||||
@ -36,7 +37,6 @@ import type {
|
||||
GetLicenseAndUsageInfoResult,
|
||||
GetLicenseAndUsageInfoVariables,
|
||||
} from '../../../graphql-operations'
|
||||
import { eventLogger } from '../../../tracking/eventLogger'
|
||||
|
||||
import { BATCH_CHANGES, BATCH_CHANGES_BY_NAMESPACE, GET_LICENSE_AND_USAGE_INFO } from './backend'
|
||||
import { BatchChangeListFilters } from './BatchChangeListFilters'
|
||||
@ -168,7 +168,7 @@ export const BatchChangeListPage: React.FunctionComponent<React.PropsWithChildre
|
||||
to="https://sourcegraph.com"
|
||||
variant="primary"
|
||||
onClick={() => {
|
||||
eventLogger.log('ClickedOnEnterpriseCTA', { location: 'TryBatchChanges' })
|
||||
EVENT_LOGGER.log('ClickedOnEnterpriseCTA', { location: 'TryBatchChanges' })
|
||||
telemetryRecorder.recordEvent('batchChanges.enterpriseCTA', 'click', {
|
||||
metadata: { location: 0 },
|
||||
})
|
||||
@ -375,7 +375,7 @@ const BatchChangeListTabHeader: React.FunctionComponent<
|
||||
to=""
|
||||
onClick={event => {
|
||||
onSelectGettingStarted(event)
|
||||
eventLogger.log('batch_change_homepage:getting_started:clicked')
|
||||
EVENT_LOGGER.log('batch_change_homepage:getting_started:clicked')
|
||||
telemetryRecorder.recordEvent('batchChanges.gettingStarted', 'click')
|
||||
}}
|
||||
className={classNames('nav-link', selectedTab === 'gettingStarted' && 'active')}
|
||||
|
||||
@ -3,12 +3,12 @@ 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 { BatchChangesIcon } from '../../../batches/icons'
|
||||
import { CallToActionBanner } from '../../../components/CallToActionBanner'
|
||||
import { CtaBanner } from '../../../components/CtaBanner'
|
||||
import { eventLogger } from '../../../tracking/eventLogger'
|
||||
|
||||
export interface GettingStartedProps extends TelemetryV2Props {
|
||||
isSourcegraphDotCom: boolean
|
||||
@ -99,7 +99,7 @@ export const GettingStarted: React.FunctionComponent<React.PropsWithChildren<Get
|
||||
<Link
|
||||
to="https://sourcegraph.com"
|
||||
onClick={() => {
|
||||
eventLogger.log('ClickedOnEnterpriseCTA', { location: 'BatchChangesGettingStarted' })
|
||||
EVENT_LOGGER.log('ClickedOnEnterpriseCTA', { location: 'BatchChangesGettingStarted' })
|
||||
telemetryRecorder.recordEvent('batchChanges.enterpriseCTA', 'click', {
|
||||
metadata: { location: 1 },
|
||||
})
|
||||
|
||||
@ -3,10 +3,9 @@ import React from 'react'
|
||||
import { mdiPlus } from '@mdi/js'
|
||||
|
||||
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Link, type LinkProps, Button, Icon, Tooltip } from '@sourcegraph/wildcard'
|
||||
|
||||
import { eventLogger } from '../../../tracking/eventLogger'
|
||||
|
||||
interface NewBatchChangeButtonProps extends Pick<LinkProps, 'to'>, TelemetryV2Props {
|
||||
// canCreate indicates whether or not the currently-authenticated user has sufficient
|
||||
// permissions to create a batch change in whatever context this button is being
|
||||
@ -27,7 +26,7 @@ export const NewBatchChangeButton: React.FunctionComponent<React.PropsWithChildr
|
||||
variant="primary"
|
||||
as={Link}
|
||||
onClick={() => {
|
||||
eventLogger.log('batch_change_list_page:create_batch_change_details:clicked')
|
||||
EVENT_LOGGER.log('batch_change_list_page:create_batch_change_details:clicked')
|
||||
telemetryRecorder.recordEvent('batchChanges', 'create')
|
||||
}}
|
||||
>
|
||||
|
||||
@ -6,10 +6,10 @@ import { useNavigate } from 'react-router-dom'
|
||||
import { isErrorLike } from '@sourcegraph/common'
|
||||
import type { 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 { Alert, Button, Code, Link, Tooltip, ErrorAlert } from '@sourcegraph/wildcard'
|
||||
|
||||
import type { BatchSpecFields } from '../../../graphql-operations'
|
||||
import { eventLogger } from '../../../tracking/eventLogger'
|
||||
import { MultiSelectContext } from '../MultiSelectContext'
|
||||
|
||||
import { applyBatchChange, createBatchChange } from './backend'
|
||||
@ -121,10 +121,10 @@ export const CreateUpdateBatchChangeAlert: React.FunctionComponent<
|
||||
)}
|
||||
onClick={() => {
|
||||
if (batchChange) {
|
||||
eventLogger.log('batch_change_execution_preview:apply_update:clicked')
|
||||
EVENT_LOGGER.log('batch_change_execution_preview:apply_update:clicked')
|
||||
telemetryRecorder.recordEvent('batchChange.execution.updateAndApply', 'click')
|
||||
} else {
|
||||
eventLogger.log('batch_change_execution_preview:apply:clicked')
|
||||
EVENT_LOGGER.log('batch_change_execution_preview:apply:clicked')
|
||||
telemetryRecorder.recordEvent('batchChange.execution.createAndApply', 'click')
|
||||
}
|
||||
return onApply()
|
||||
|
||||
@ -4,6 +4,7 @@ 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 type { AuthenticatedUser } from '../../auth'
|
||||
@ -16,7 +17,6 @@ import type {
|
||||
ListUserCodeMonitorsResult,
|
||||
ListUserCodeMonitorsVariables,
|
||||
} from '../../graphql-operations'
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
|
||||
import { CodeMonitorNode, type CodeMonitorNodeProps } from './CodeMonitoringNode'
|
||||
import type { CodeMonitoringPageProps } from './CodeMonitoringPage'
|
||||
@ -85,7 +85,7 @@ export const CodeMonitorList: React.FunctionComponent<React.PropsWithChildren<Co
|
||||
<Link
|
||||
to="https://sourcegraph.com"
|
||||
onClick={() => {
|
||||
eventLogger.log('ClickedOnEnterpriseCTA', { location: 'Monitoring' })
|
||||
EVENT_LOGGER.log('ClickedOnEnterpriseCTA', { location: 'Monitoring' })
|
||||
telemetryRecorder.recordEvent('codeMonitor.enterpriseCTA', 'click', {
|
||||
metadata: { location: 1 },
|
||||
})
|
||||
|
||||
@ -5,11 +5,11 @@ import classNames from 'classnames'
|
||||
|
||||
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 { eventLogger } from '../../tracking/eventLogger'
|
||||
|
||||
import styles from './CodeMonitoringGettingStarted.module.scss'
|
||||
|
||||
@ -72,7 +72,7 @@ export const CodeMonitoringGettingStarted: React.FunctionComponent<
|
||||
const assetsRoot = window.context?.assetsRoot || ''
|
||||
|
||||
const logExampleMonitorClicked = useCallback(() => {
|
||||
eventLogger.log('CodeMonitoringExampleMonitorClicked')
|
||||
EVENT_LOGGER.log('CodeMonitoringExampleMonitorClicked')
|
||||
telemetryRecorder.recordEvent('codeMonitor.example', 'click')
|
||||
}, [telemetryRecorder])
|
||||
|
||||
@ -113,7 +113,7 @@ export const CodeMonitoringGettingStarted: React.FunctionComponent<
|
||||
<Link
|
||||
to={ctaBannerUrl}
|
||||
onClick={() => {
|
||||
eventLogger.log('ClickedOnEnterpriseCTA', { location: 'MonitoringGettingStarted' })
|
||||
EVENT_LOGGER.log('ClickedOnEnterpriseCTA', { location: 'MonitoringGettingStarted' })
|
||||
telemetryRecorder.recordEvent('codeMonitor.enterpriseCTA', 'click', {
|
||||
metadata: { location: 0 },
|
||||
})
|
||||
|
||||
@ -10,6 +10,7 @@ import { asError, isErrorLike } from '@sourcegraph/common'
|
||||
import type { Settings } from '@sourcegraph/shared/src/schema/settings.schema'
|
||||
import type { SettingsCascadeProps } from '@sourcegraph/shared/src/settings/settings'
|
||||
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import {
|
||||
PageHeader,
|
||||
LoadingSpinner,
|
||||
@ -24,7 +25,6 @@ import {
|
||||
import type { AuthenticatedUser } from '../../auth'
|
||||
import { CodeMonitoringLogo } from '../../code-monitoring/CodeMonitoringLogo'
|
||||
import { PageTitle } from '../../components/PageTitle'
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
|
||||
import {
|
||||
fetchUserCodeMonitors as _fetchUserCodeMonitors,
|
||||
@ -127,17 +127,17 @@ export const CodeMonitoringPage: React.FunctionComponent<React.PropsWithChildren
|
||||
if (userHasCodeMonitors !== undefined) {
|
||||
switch (currentTab) {
|
||||
case 'getting-started': {
|
||||
eventLogger.logPageView('CodeMonitoringGettingStartedPage')
|
||||
EVENT_LOGGER.logPageView('CodeMonitoringGettingStartedPage')
|
||||
telemetryRecorder.recordEvent('codeMonitor.gettingStarted', 'view')
|
||||
break
|
||||
}
|
||||
case 'logs': {
|
||||
eventLogger.logPageView('CodeMonitoringLogsPage')
|
||||
EVENT_LOGGER.logPageView('CodeMonitoringLogsPage')
|
||||
telemetryRecorder.recordEvent('codeMonitor.logs', 'view')
|
||||
break
|
||||
}
|
||||
case 'list': {
|
||||
eventLogger.logPageView('CodeMonitoringPage')
|
||||
EVENT_LOGGER.logPageView('CodeMonitoringPage')
|
||||
telemetryRecorder.recordEvent('codeMonitor.list', 'view')
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ import { useLocation } from 'react-router-dom'
|
||||
import type { Observable } from 'rxjs'
|
||||
|
||||
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { PageHeader, Link } from '@sourcegraph/wildcard'
|
||||
|
||||
import type { AuthenticatedUser } from '../../auth'
|
||||
@ -12,7 +13,6 @@ import { withAuthenticatedUser } from '../../auth/withAuthenticatedUser'
|
||||
import { CodeMonitoringLogo } from '../../code-monitoring/CodeMonitoringLogo'
|
||||
import { PageTitle } from '../../components/PageTitle'
|
||||
import type { CodeMonitorFields } from '../../graphql-operations'
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
|
||||
import { convertActionsForCreate } from './action-converters'
|
||||
import { createCodeMonitor as _createCodeMonitor } from './backend'
|
||||
@ -42,7 +42,7 @@ const AuthenticatedCreateCodeMonitorPage: React.FunctionComponent<
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
eventLogger.logPageView('CreateCodeMonitorPage', {
|
||||
EVENT_LOGGER.logPageView('CreateCodeMonitorPage', {
|
||||
hasTriggerQuery: !!triggerQuery,
|
||||
hasDescription: !!description,
|
||||
})
|
||||
@ -53,7 +53,7 @@ const AuthenticatedCreateCodeMonitorPage: React.FunctionComponent<
|
||||
|
||||
const createMonitorRequest = useCallback(
|
||||
(codeMonitor: CodeMonitorFields): Observable<Partial<CodeMonitorFields>> => {
|
||||
eventLogger.log('CreateCodeMonitorFormSubmitted')
|
||||
EVENT_LOGGER.log('CreateCodeMonitorFormSubmitted')
|
||||
telemetryRecorder.recordEvent('codeMonitor.create', 'submit')
|
||||
return createCodeMonitor({
|
||||
monitor: {
|
||||
|
||||
@ -7,6 +7,7 @@ import { startWith, catchError, tap } from 'rxjs/operators'
|
||||
|
||||
import { asError, isErrorLike } from '@sourcegraph/common'
|
||||
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { PageHeader, Link, LoadingSpinner, useObservable } from '@sourcegraph/wildcard'
|
||||
|
||||
import type { AuthenticatedUser } from '../../auth'
|
||||
@ -14,7 +15,6 @@ import { withAuthenticatedUser } from '../../auth/withAuthenticatedUser'
|
||||
import { CodeMonitoringLogo } from '../../code-monitoring/CodeMonitoringLogo'
|
||||
import { PageTitle } from '../../components/PageTitle'
|
||||
import type { CodeMonitorFields } from '../../graphql-operations'
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
|
||||
import { convertActionsForUpdate } from './action-converters'
|
||||
import {
|
||||
@ -47,7 +47,7 @@ const AuthenticatedManageCodeMonitorPage: React.FunctionComponent<
|
||||
const LOADING = 'loading' as const
|
||||
|
||||
useEffect(() => {
|
||||
eventLogger.logPageView('ManageCodeMonitorPage')
|
||||
EVENT_LOGGER.logPageView('ManageCodeMonitorPage')
|
||||
telemetryRecorder.recordEvent('codeMonitor.manage', 'view')
|
||||
}, [telemetryRecorder])
|
||||
|
||||
@ -84,7 +84,7 @@ const AuthenticatedManageCodeMonitorPage: React.FunctionComponent<
|
||||
|
||||
const updateMonitorRequest = React.useCallback(
|
||||
(codeMonitor: CodeMonitorFields): Observable<Partial<CodeMonitorFields>> => {
|
||||
eventLogger.log('ManageCodeMonitorFormSubmitted')
|
||||
EVENT_LOGGER.log('ManageCodeMonitorFormSubmitted')
|
||||
telemetryRecorder.recordEvent('codeMonitor.manage.update', 'submit')
|
||||
return updateCodeMonitor(
|
||||
{
|
||||
@ -104,7 +104,7 @@ const AuthenticatedManageCodeMonitorPage: React.FunctionComponent<
|
||||
|
||||
const deleteMonitorRequest = React.useCallback(
|
||||
(id: string): Observable<void> => {
|
||||
eventLogger.log('ManageCodeMonitorDeleteSubmitted')
|
||||
EVENT_LOGGER.log('ManageCodeMonitorDeleteSubmitted')
|
||||
telemetryRecorder.recordEvent('codeMonitor.manage.delete', 'submit')
|
||||
return deleteCodeMonitor(id)
|
||||
},
|
||||
|
||||
@ -4,6 +4,7 @@ import { useApolloClient } from '@apollo/client'
|
||||
import { mdiMapSearch } from '@mdi/js'
|
||||
|
||||
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Container, Link, PageHeader, Icon, H3, Text } from '@sourcegraph/wildcard'
|
||||
|
||||
import {
|
||||
@ -13,7 +14,6 @@ import {
|
||||
} from '../../../components/FilteredConnection'
|
||||
import { PageTitle } from '../../../components/PageTitle'
|
||||
import type { ExecutorFields } from '../../../graphql-operations'
|
||||
import { eventLogger } from '../../../tracking/eventLogger'
|
||||
|
||||
import { ExecutorNode } from './ExecutorNode'
|
||||
import { queryExecutors as defaultQueryExecutors } from './useExecutors'
|
||||
@ -49,7 +49,7 @@ export const ExecutorsListPage: React.FC<ExecutorsListPageProps> = ({
|
||||
telemetryRecorder,
|
||||
}) => {
|
||||
useEffect(() => {
|
||||
eventLogger.logViewEvent('ExecutorsList')
|
||||
EVENT_LOGGER.logViewEvent('ExecutorsList')
|
||||
telemetryRecorder.recordEvent('executors.list', 'view')
|
||||
}, [telemetryRecorder])
|
||||
|
||||
|
||||
@ -4,9 +4,9 @@ import { lastValueFrom } from 'rxjs'
|
||||
|
||||
import { type ErrorLike, logger } from '@sourcegraph/common'
|
||||
import { BillingCategory, BillingProduct } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { TelemetryRecorder } from '@sourcegraph/telemetry'
|
||||
|
||||
import { eventLogger } from '../../../tracking/eventLogger'
|
||||
import { CodeInsightsBackendContext, type Insight } from '../core'
|
||||
import { getTrackingTypeByInsightType } from '../pings'
|
||||
import { V2InsightType } from '../pings/types'
|
||||
@ -45,7 +45,7 @@ export function useDeleteInsight(
|
||||
await lastValueFrom(deleteInsight(insight.id), { defaultValue: undefined })
|
||||
const insightType = getTrackingTypeByInsightType(insight.type)
|
||||
|
||||
eventLogger.log('InsightRemoval', { insightType }, { insightType })
|
||||
EVENT_LOGGER.log('InsightRemoval', { insightType }, { insightType })
|
||||
telemetryRecorder.recordEvent('insight', 'delete', {
|
||||
metadata: { insightType: V2InsightType[insightType] },
|
||||
})
|
||||
|
||||
@ -4,9 +4,9 @@ import { lastValueFrom } from 'rxjs'
|
||||
|
||||
import { type ErrorLike, logger } from '@sourcegraph/common'
|
||||
import { BillingCategory, BillingProduct } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { TelemetryRecorder } from '@sourcegraph/telemetry'
|
||||
|
||||
import { eventLogger } from '../../../tracking/eventLogger'
|
||||
import { CodeInsightsBackendContext, type Insight, type InsightDashboard } from '../core'
|
||||
import { getTrackingTypeByInsightType } from '../pings'
|
||||
import { V2InsightType } from '../pings/types'
|
||||
@ -53,7 +53,7 @@ export function useRemoveInsightFromDashboard(
|
||||
|
||||
const insightType = getTrackingTypeByInsightType(insight.type)
|
||||
|
||||
eventLogger.log('InsightRemovalFromDashboard', { insightType }, { insightType })
|
||||
EVENT_LOGGER.log('InsightRemovalFromDashboard', { insightType }, { insightType })
|
||||
telemetryRecorder.recordEvent('insight', 'removeFromDashboard', {
|
||||
metadata: { insightType: V2InsightType[insightType] },
|
||||
})
|
||||
|
||||
@ -4,9 +4,9 @@ import { useNavigate } from 'react-router-dom'
|
||||
import { lastValueFrom } from 'rxjs'
|
||||
|
||||
import { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import type { SubmissionErrors } from '@sourcegraph/wildcard'
|
||||
|
||||
import { eventLogger } from '../../../../../../tracking/eventLogger'
|
||||
import { CodeInsightsBackendContext, type CreationInsightInput } from '../../../../core'
|
||||
import { useQueryParameters } from '../../../../hooks'
|
||||
import { getTrackingTypeByInsightType } from '../../../../pings'
|
||||
@ -46,7 +46,7 @@ export function useEditPageHandlers(props: Props): useHandleSubmitOutput {
|
||||
)
|
||||
|
||||
const insightType = getTrackingTypeByInsightType(newInsight.type)
|
||||
eventLogger.log('InsightEdit', { insightType }, { insightType })
|
||||
EVENT_LOGGER.log('InsightEdit', { insightType }, { insightType })
|
||||
telemetryRecorder.recordEvent('insight', 'edit', { metadata: { type: V2InsightType[insightType] } })
|
||||
navigate(redirectUrl)
|
||||
}
|
||||
|
||||
@ -5,13 +5,13 @@ 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 { eventLogger } from '../../../../../tracking/eventLogger'
|
||||
import { CodeInsightsLandingPageContext, CodeInsightsLandingPageType } from '../CodeInsightsLandingPageContext'
|
||||
import { CodeInsightsDescription } from '../getting-started/components/code-insights-description/CodeInsightsDescription'
|
||||
|
||||
@ -49,7 +49,7 @@ export const CodeInsightsDotComGetStarted: React.FunctionComponent<
|
||||
to="https://sourcegraph.com"
|
||||
variant="primary"
|
||||
onClick={() => {
|
||||
eventLogger.log('ClickedOnEnterpriseCTA', { location: 'TryInsights' })
|
||||
EVENT_LOGGER.log('ClickedOnEnterpriseCTA', { location: 'TryInsights' })
|
||||
telemetryRecorder.recordEvent('insights.enterpriseCTA', 'click', {
|
||||
metadata: { location: 0 },
|
||||
})
|
||||
@ -93,7 +93,7 @@ export const CodeInsightsDotComGetStarted: React.FunctionComponent<
|
||||
<Link
|
||||
to="https://sourcegraph.com"
|
||||
onClick={() => {
|
||||
eventLogger.log('ClickedOnEnterpriseCTA', { location: 'Insights' })
|
||||
EVENT_LOGGER.log('ClickedOnEnterpriseCTA', { location: 'Insights' })
|
||||
telemetryRecorder.recordEvent('insights.enterpriseCTA', 'click', {
|
||||
metadata: { location: 0 },
|
||||
})
|
||||
|
||||
@ -4,12 +4,12 @@ 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 type { AuthenticatedUser } from '../../auth'
|
||||
import { CallToActionBanner } from '../../components/CallToActionBanner'
|
||||
import { Page } from '../../components/Page'
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
|
||||
import { SearchContextsList } from './SearchContextsList'
|
||||
|
||||
@ -65,7 +65,7 @@ export const SearchContextsListPage: React.FunctionComponent<SearchContextsListP
|
||||
<Link
|
||||
to="https://sourcegraph.com"
|
||||
onClick={() => {
|
||||
eventLogger.log('ClickedOnEnterpriseCTA', { location: 'ContextsSettings' })
|
||||
EVENT_LOGGER.log('ClickedOnEnterpriseCTA', { location: 'ContextsSettings' })
|
||||
platformContext.telemetryRecorder.recordEvent(
|
||||
'searchContexts.enterpriseCTA',
|
||||
'click'
|
||||
|
||||
@ -5,13 +5,13 @@ import { map } from 'rxjs/operators'
|
||||
|
||||
import { createAggregateError } from '@sourcegraph/common'
|
||||
import { gql } from '@sourcegraph/http-client'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Badge, Link, H2, Text } from '@sourcegraph/wildcard'
|
||||
|
||||
import { queryGraphQL } from '../../backend/graphql'
|
||||
import { FilteredConnection } from '../../components/FilteredConnection'
|
||||
import { PageTitle } from '../../components/PageTitle'
|
||||
import type { AuthProviderFields, AuthProvidersResult } from '../../graphql-operations'
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
|
||||
interface AuthProviderNodeProps {
|
||||
/** The auth provider to display in this item. */
|
||||
@ -58,7 +58,7 @@ interface Props {}
|
||||
*/
|
||||
export class SiteAdminAuthenticationProvidersPage extends React.Component<Props> {
|
||||
public componentDidMount(): void {
|
||||
eventLogger.logViewEvent('SiteAdminAuthentication')
|
||||
EVENT_LOGGER.logViewEvent('SiteAdminAuthentication')
|
||||
}
|
||||
|
||||
public render(): JSX.Element | null {
|
||||
|
||||
@ -6,6 +6,7 @@ import { map } from 'rxjs/operators'
|
||||
import { createAggregateError } from '@sourcegraph/common'
|
||||
import { gql } from '@sourcegraph/http-client'
|
||||
import type { Scalars } from '@sourcegraph/shared/src/graphql-operations'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Button, Link, H2, Text } from '@sourcegraph/wildcard'
|
||||
|
||||
import { requestGraphQL } from '../../backend/graphql'
|
||||
@ -17,7 +18,6 @@ import type {
|
||||
ExternalAccountsResult,
|
||||
ExternalAccountsVariables,
|
||||
} from '../../graphql-operations'
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
import {
|
||||
ExternalAccountNode,
|
||||
type ExternalAccountNodeProps,
|
||||
@ -41,7 +41,7 @@ export class SiteAdminExternalAccountsPage extends React.Component<Props> {
|
||||
private externalAccountUpdates = new Subject<void>()
|
||||
|
||||
public componentDidMount(): void {
|
||||
eventLogger.logViewEvent('SiteAdminExternalAccounts')
|
||||
EVENT_LOGGER.logViewEvent('SiteAdminExternalAccounts')
|
||||
}
|
||||
|
||||
public componentWillUnmount(): void {
|
||||
|
||||
@ -4,10 +4,10 @@ import { Navigate, useParams } from 'react-router-dom'
|
||||
import { catchError } from 'rxjs/operators'
|
||||
|
||||
import { asError, type ErrorLike, isErrorLike } from '@sourcegraph/common'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { LoadingSpinner, useObservable, ErrorAlert } from '@sourcegraph/wildcard'
|
||||
|
||||
import { PageTitle } from '../../components/PageTitle'
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
|
||||
import { fetchPreciseIndex } from './backend'
|
||||
|
||||
@ -16,7 +16,7 @@ import { fetchPreciseIndex } from './backend'
|
||||
*/
|
||||
export const SiteAdminPreciseIndexPage: React.FC<{}> = () => {
|
||||
const { id = '' } = useParams<{ id: string }>()
|
||||
useEffect(() => eventLogger.logViewEvent('SiteAdminPreciseIndex'))
|
||||
useEffect(() => EVENT_LOGGER.logViewEvent('SiteAdminPreciseIndex'))
|
||||
|
||||
const indexOrError = useObservable(
|
||||
useMemo(() => fetchPreciseIndex({ id }).pipe(catchError((error): [ErrorLike] => [asError(error)])), [id])
|
||||
|
||||
@ -6,6 +6,7 @@ import { map } from 'rxjs/operators'
|
||||
import { createAggregateError } from '@sourcegraph/common'
|
||||
import { gql } from '@sourcegraph/http-client'
|
||||
import { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Container, Link, PageHeader, Text } from '@sourcegraph/wildcard'
|
||||
|
||||
import { queryGraphQL } from '../../../backend/graphql'
|
||||
@ -17,7 +18,6 @@ import type {
|
||||
ProductSubscriptionsVariables,
|
||||
UserAreaUserFields,
|
||||
} from '../../../graphql-operations'
|
||||
import { eventLogger } from '../../../tracking/eventLogger'
|
||||
import {
|
||||
ProductSubscriptionNode,
|
||||
ProductSubscriptionNodeHeader,
|
||||
@ -89,7 +89,7 @@ export const UserSubscriptionsProductSubscriptionsPage: React.FunctionComponent<
|
||||
<Link
|
||||
to="https://sourcegraph.com"
|
||||
onClick={() => {
|
||||
eventLogger.log('ClickedOnEnterpriseCTA', { location: 'Subscriptions' })
|
||||
EVENT_LOGGER.log('ClickedOnEnterpriseCTA', { location: 'Subscriptions' })
|
||||
props.telemetryRecorder.recordEvent('settings.userSubscriptions.enterpriseCTA', 'click')
|
||||
}}
|
||||
>
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
import classNames from 'classnames'
|
||||
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Badge, Icon, Link } from '@sourcegraph/wildcard'
|
||||
|
||||
import { eventLogger } from '../tracking/eventLogger'
|
||||
|
||||
import styles from './DownloadAppButton.module.scss'
|
||||
|
||||
interface DownloadAppButtonProps {
|
||||
@ -24,7 +23,7 @@ export const DownloadAppButton: React.FunctionComponent<DownloadAppButtonProps>
|
||||
eventType,
|
||||
}) => {
|
||||
const handleOnClick = (): void => {
|
||||
eventLogger.log(eventName, { type: eventType })
|
||||
EVENT_LOGGER.log(eventName, { type: eventType })
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@ -6,6 +6,7 @@ import { useNavigate, useLocation } from 'react-router-dom'
|
||||
|
||||
import type { AuthenticatedUser } from '@sourcegraph/shared/src/auth'
|
||||
import { noOpTelemetryRecorder } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Badge, H2, Icon, Link, PageHeader, Text } from '@sourcegraph/wildcard'
|
||||
|
||||
import { ExternalsAuth } from '../auth/components/ExternalsAuth'
|
||||
@ -13,7 +14,6 @@ import { CodyLetsWorkIcon } from '../cody/chat/CodyPageIcon'
|
||||
import { Page } from '../components/Page'
|
||||
import { PageTitle } from '../components/PageTitle'
|
||||
import type { SourcegraphContext } from '../jscontext'
|
||||
import { eventLogger } from '../tracking/eventLogger'
|
||||
import { EventName } from '../util/constants'
|
||||
|
||||
import { DownloadAppButton } from './DownloadAppButton'
|
||||
@ -39,9 +39,9 @@ const SOURCEGRAPH_MAC_INTEL = 'https://sourcegraph.com/.api/app/latest?arch=x86_
|
||||
const SOURCEGRAPH_LINUX = 'https://sourcegraph.com/.api/app/latest?arch=x86_64&target=linux'
|
||||
|
||||
const logEvent = (eventName: string, type?: string, source?: string): void =>
|
||||
eventLogger.log(eventName, { type, source })
|
||||
EVENT_LOGGER.log(eventName, { type, source })
|
||||
|
||||
const logPageView = (pageTitle: string): void => eventLogger.logPageView(pageTitle)
|
||||
const logPageView = (pageTitle: string): void => EVENT_LOGGER.logPageView(pageTitle)
|
||||
|
||||
/* eslint-disable @sourcegraph/sourcegraph/check-help-links */
|
||||
|
||||
@ -112,7 +112,7 @@ export const GetCodyPage: React.FunctionComponent<GetCodyPageProps> = ({ authent
|
||||
onClick={() => {}}
|
||||
ctaClassName={styles.authButton}
|
||||
telemetryRecorder={noOpTelemetryRecorder}
|
||||
telemetryService={eventLogger}
|
||||
telemetryService={EVENT_LOGGER}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -4,10 +4,9 @@ import classNames from 'classnames'
|
||||
import { range } from 'lodash'
|
||||
|
||||
import { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Button } from '@sourcegraph/wildcard'
|
||||
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
|
||||
import radioStyles from './SurveyRatingRadio.module.scss'
|
||||
|
||||
interface SurveyRatingRadio extends TelemetryV2Props {
|
||||
@ -29,7 +28,7 @@ export const SurveyRatingRadio: React.FunctionComponent<React.PropsWithChildren<
|
||||
}
|
||||
|
||||
const handleChange = (score: number): void => {
|
||||
eventLogger.log('SurveyButtonClicked', { score }, { score })
|
||||
EVENT_LOGGER.log('SurveyButtonClicked', { score }, { score })
|
||||
props.telemetryRecorder.recordEvent('surveyNPS.button', 'click', { metadata: { score } })
|
||||
|
||||
if (props.onChange) {
|
||||
|
||||
@ -4,11 +4,11 @@ import { useNavigate } from 'react-router-dom'
|
||||
|
||||
import { useMutation, gql } from '@sourcegraph/http-client'
|
||||
import { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Button, LoadingSpinner, Label, Text, Form } from '@sourcegraph/wildcard'
|
||||
|
||||
import type { AuthenticatedUser } from '../../auth'
|
||||
import type { SubmitSurveyResult, SubmitSurveyVariables } from '../../graphql-operations'
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
import { SurveyRatingRadio } from '../components/SurveyRatingRadio'
|
||||
import { SurveyUseCaseForm } from '../components/SurveyUseCaseForm'
|
||||
|
||||
@ -79,7 +79,7 @@ export const SurveyForm: React.FunctionComponent<React.PropsWithChildren<SurveyF
|
||||
return
|
||||
}
|
||||
|
||||
eventLogger.log('SurveySubmitted')
|
||||
EVENT_LOGGER.log('SurveySubmitted')
|
||||
telemetryRecorder.recordEvent('surveyNPS', 'submit')
|
||||
|
||||
await submitSurvey({
|
||||
|
||||
@ -3,12 +3,12 @@ import React, { useEffect } from 'react'
|
||||
import { useParams, useLocation } from 'react-router-dom'
|
||||
|
||||
import { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { FeedbackText } from '@sourcegraph/wildcard'
|
||||
|
||||
import type { AuthenticatedUser } from '../../auth'
|
||||
import { HeroPage } from '../../components/HeroPage'
|
||||
import { PageTitle } from '../../components/PageTitle'
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
import { TweetFeedback } from '../components/TweetFeedback'
|
||||
|
||||
import { SurveyForm } from './SurveyForm'
|
||||
@ -32,7 +32,7 @@ export const SurveyPage: React.FunctionComponent<React.PropsWithChildren<SurveyP
|
||||
const score = props.forceScore || matchParameters.score
|
||||
|
||||
useEffect(() => {
|
||||
eventLogger.logViewEvent('Survey')
|
||||
EVENT_LOGGER.logViewEvent('Survey')
|
||||
props.telemetryRecorder.recordEvent('surveyNPS.page', 'view')
|
||||
}, [props.telemetryRecorder])
|
||||
|
||||
|
||||
@ -3,10 +3,10 @@ import React, { useEffect, useState } from 'react'
|
||||
import { gql, useMutation } from '@apollo/client'
|
||||
|
||||
import { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
|
||||
import type { AuthenticatedUser } from '../../auth'
|
||||
import type { SubmitSurveyResult, SubmitSurveyVariables } from '../../graphql-operations'
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
|
||||
import { SurveySuccessToast } from './SurveySuccessToast'
|
||||
import { SurveyUseCaseToast } from './SurveyUseCaseToast'
|
||||
@ -58,7 +58,7 @@ export const SurveyToastContent: React.FunctionComponent<React.PropsWithChildren
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
eventLogger.log('SurveyReminderViewed')
|
||||
EVENT_LOGGER.log('SurveyReminderViewed')
|
||||
telemetryRecorder.recordEvent('surveyNPS.toast', 'view')
|
||||
}, [telemetryRecorder])
|
||||
|
||||
|
||||
@ -6,12 +6,12 @@ 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 { CallToActionBanner } from '../../components/CallToActionBanner'
|
||||
import { PageRoutes } from '../../routes.constants'
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
|
||||
import styles from './NotebooksGettingStartedTab.module.scss'
|
||||
|
||||
@ -131,7 +131,7 @@ export const NotebooksGettingStartedTab: React.FunctionComponent<
|
||||
<Link
|
||||
to="https://sourcegraph.com"
|
||||
onClick={() =>
|
||||
eventLogger.log('ClickedOnEnterpriseCTA', { location: 'NotebooksGettingStarted' })
|
||||
EVENT_LOGGER.log('ClickedOnEnterpriseCTA', { location: 'NotebooksGettingStarted' })
|
||||
}
|
||||
>
|
||||
get Sourcegraph Enterprise
|
||||
|
||||
@ -12,9 +12,9 @@ import {
|
||||
} from '@sourcegraph/shared/src/backend/file'
|
||||
import type { PlatformContextProps } from '@sourcegraph/shared/src/platform/context'
|
||||
import { aggregateStreamingSearch } from '@sourcegraph/shared/src/search/stream'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Alert, LoadingSpinner, useObservable } from '@sourcegraph/wildcard'
|
||||
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
import { fetchNotebook } from '../backend'
|
||||
import { convertNotebookTitleToFileName } from '../serialize'
|
||||
|
||||
@ -32,7 +32,7 @@ const LOADING = 'loading' as const
|
||||
export const EmbeddedNotebookPage: FC<EmbeddedNotebookPageProps> = ({ platformContext, ...props }) => {
|
||||
const { notebookId } = useParams()
|
||||
|
||||
useEffect(() => eventLogger.logPageView('EmbeddedNotebookPage'), [])
|
||||
useEffect(() => EVENT_LOGGER.logPageView('EmbeddedNotebookPage'), [])
|
||||
platformContext.telemetryRecorder.recordEvent('embeddedNotebook', 'view')
|
||||
|
||||
const notebookOrError = useObservable(
|
||||
@ -78,7 +78,7 @@ export const EmbeddedNotebookPage: FC<EmbeddedNotebookPageProps> = ({ platformCo
|
||||
viewerCanManage={false}
|
||||
fetchHighlightedFileLineRanges={fetchHighlightedFileLineRanges}
|
||||
streamSearch={aggregateStreamingSearch}
|
||||
telemetryService={eventLogger}
|
||||
telemetryService={EVENT_LOGGER}
|
||||
telemetryRecorder={platformContext.telemetryRecorder}
|
||||
platformContext={platformContext}
|
||||
exportedFileName={convertNotebookTitleToFileName(notebookOrError.title)}
|
||||
|
||||
@ -9,6 +9,7 @@ import { SimpleActionItem } from '@sourcegraph/shared/src/actions/SimpleActionIt
|
||||
import type { PlatformContext } from '@sourcegraph/shared/src/platform/context'
|
||||
import { isSettingsValid, type Settings } from '@sourcegraph/shared/src/settings/settings'
|
||||
import { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import {
|
||||
Button,
|
||||
Icon,
|
||||
@ -22,7 +23,6 @@ import {
|
||||
|
||||
import { RepoHeaderActionAnchor, RepoHeaderActionMenuLink } from '../repo/components/RepoHeaderActions'
|
||||
import { RepoActionInfo } from '../repo/RepoActionInfo'
|
||||
import { eventLogger } from '../tracking/eventLogger'
|
||||
|
||||
import { getEditorSettingsErrorMessage } from './build-url'
|
||||
import type { EditorSettings } from './editor-settings'
|
||||
@ -110,7 +110,7 @@ export const OpenInEditorActionItem: React.FunctionComponent<OpenInEditorActionI
|
||||
/>
|
||||
}
|
||||
onClick={() => {
|
||||
eventLogger.log('OpenInEditorClicked', { editor: editor.id }, { editor: editor.id })
|
||||
EVENT_LOGGER.log('OpenInEditorClicked', { editor: editor.id }, { editor: editor.id })
|
||||
props.telemetryRecorder.recordEvent('blob.openInEditor', 'click', {
|
||||
metadata: { editor: editor.telemetryID },
|
||||
})
|
||||
|
||||
@ -7,6 +7,7 @@ import { catchError, concatMap, distinctUntilKeyChanged, map, tap, withLatestFro
|
||||
import { asError, type ErrorLike, isErrorLike, logger } from '@sourcegraph/common'
|
||||
import { dataOrThrowErrors, gql } from '@sourcegraph/http-client'
|
||||
import { OrganizationInvitationResponseType } from '@sourcegraph/shared/src/graphql-operations'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { LoadingSpinner, Button, Link, Alert, H3, Text, ErrorAlert, Form } from '@sourcegraph/wildcard'
|
||||
|
||||
import { orgURL } from '..'
|
||||
@ -19,7 +20,6 @@ import type {
|
||||
RespondToOrganizationInvitationResult,
|
||||
RespondToOrganizationInvitationVariables,
|
||||
} from '../../graphql-operations'
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
import { userURL } from '../../user'
|
||||
import { OrgAvatar } from '../OrgAvatar'
|
||||
|
||||
@ -51,7 +51,7 @@ export const OrgInvitationPageLegacy = withAuthenticatedUser(
|
||||
private subscriptions = new Subscription()
|
||||
|
||||
public componentDidMount(): void {
|
||||
eventLogger.logViewEvent('OrgInvitation')
|
||||
EVENT_LOGGER.logViewEvent('OrgInvitation')
|
||||
|
||||
const orgChanges = this.componentUpdates.pipe(
|
||||
distinctUntilKeyChanged('org'),
|
||||
@ -74,7 +74,7 @@ export const OrgInvitationPageLegacy = withAuthenticatedUser(
|
||||
organizationInvitation: org.viewerPendingInvitation!.id,
|
||||
responseType,
|
||||
}).pipe(
|
||||
tap(() => eventLogger.log('OrgInvitationRespondedTo')),
|
||||
tap(() => EVENT_LOGGER.log('OrgInvitationRespondedTo')),
|
||||
tap(() =>
|
||||
this.props.onDidRespondToInvitation(
|
||||
responseType === OrganizationInvitationResponseType.ACCEPT
|
||||
|
||||
@ -3,6 +3,7 @@ import { map, mergeMap } from 'rxjs/operators'
|
||||
|
||||
import { createAggregateError } from '@sourcegraph/common'
|
||||
import { gql } from '@sourcegraph/http-client'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
|
||||
import { refreshAuthenticatedUser } from '../auth'
|
||||
import { requestGraphQL } from '../backend/graphql'
|
||||
@ -15,7 +16,6 @@ import type {
|
||||
UpdateOrganizationResult,
|
||||
UpdateOrganizationVariables,
|
||||
} from '../graphql-operations'
|
||||
import { eventLogger } from '../tracking/eventLogger'
|
||||
|
||||
export const ORGANIZATION_MEMBERS_QUERY = gql`
|
||||
query OrganizationSettingsMembers(
|
||||
@ -80,10 +80,10 @@ export function createOrganization(args: {
|
||||
).pipe(
|
||||
mergeMap(({ data, errors }) => {
|
||||
if (!data?.createOrganization) {
|
||||
eventLogger.log('NewOrgFailed')
|
||||
EVENT_LOGGER.log('NewOrgFailed')
|
||||
throw createAggregateError(errors)
|
||||
}
|
||||
eventLogger.log('NewOrgCreated')
|
||||
EVENT_LOGGER.log('NewOrgCreated')
|
||||
return concat(refreshAuthenticatedUser(), [data.createOrganization])
|
||||
})
|
||||
)
|
||||
@ -115,10 +115,10 @@ export function removeUserFromOrganization(args: {
|
||||
).pipe(
|
||||
mergeMap(({ errors }) => {
|
||||
if (errors && errors.length > 0) {
|
||||
eventLogger.log('RemoveOrgMemberFailed')
|
||||
EVENT_LOGGER.log('RemoveOrgMemberFailed')
|
||||
throw createAggregateError(errors)
|
||||
}
|
||||
eventLogger.log('OrgMemberRemoved')
|
||||
EVENT_LOGGER.log('OrgMemberRemoved')
|
||||
// Reload user data
|
||||
return concat(refreshAuthenticatedUser(), [undefined])
|
||||
})
|
||||
@ -149,10 +149,10 @@ export function updateOrganization(id: Scalars['ID'], displayName: string): Prom
|
||||
).pipe(
|
||||
map(({ data, errors }) => {
|
||||
if (!data || (errors && errors.length > 0)) {
|
||||
eventLogger.log('UpdateOrgSettingsFailed')
|
||||
EVENT_LOGGER.log('UpdateOrgSettingsFailed')
|
||||
throw createAggregateError(errors)
|
||||
}
|
||||
eventLogger.log('OrgSettingsUpdated')
|
||||
EVENT_LOGGER.log('OrgSettingsUpdated')
|
||||
return
|
||||
})
|
||||
)
|
||||
|
||||
@ -7,6 +7,7 @@ import { logger } from '@sourcegraph/common'
|
||||
import { gql, useMutation, useQuery } from '@sourcegraph/http-client'
|
||||
import { UserAvatar } from '@sourcegraph/shared/src/components/UserAvatar'
|
||||
import { OrganizationInvitationResponseType } from '@sourcegraph/shared/src/graphql-operations'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Alert, AnchorLink, Button, LoadingSpinner, Link, H2, H3, Form } from '@sourcegraph/wildcard'
|
||||
|
||||
import { orgURL } from '..'
|
||||
@ -19,7 +20,6 @@ import type {
|
||||
RespondToOrgInvitationResult,
|
||||
RespondToOrgInvitationVariables,
|
||||
} from '../../graphql-operations'
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
import { userURL } from '../../user'
|
||||
import { OrgAvatar } from '../OrgAvatar'
|
||||
|
||||
@ -92,7 +92,7 @@ export const OrgInvitationPage: React.FunctionComponent<React.PropsWithChildren<
|
||||
const willVerifyEmail = data?.recipientEmail && !data?.isVerifiedEmail
|
||||
|
||||
useEffect(() => {
|
||||
eventLogger.logPageView('OrganizationInvitation', { organizationId: orgId, invitationId: data?.id })
|
||||
EVENT_LOGGER.logPageView('OrganizationInvitation', { organizationId: orgId, invitationId: data?.id })
|
||||
}, [orgId, data?.id])
|
||||
|
||||
const [respondToInvitation, { loading: respondLoading, error: respondError }] = useMutation<
|
||||
@ -105,7 +105,7 @@ export const OrgInvitationPage: React.FunctionComponent<React.PropsWithChildren<
|
||||
})
|
||||
|
||||
const acceptInvitation = useCallback(async () => {
|
||||
eventLogger.log(
|
||||
EVENT_LOGGER.log(
|
||||
'OrganizationInvitationAcceptClicked',
|
||||
{
|
||||
organizationId: orgId,
|
||||
@ -125,13 +125,13 @@ export const OrgInvitationPage: React.FunctionComponent<React.PropsWithChildren<
|
||||
response: OrganizationInvitationResponseType.ACCEPT,
|
||||
},
|
||||
})
|
||||
eventLogger.log(
|
||||
EVENT_LOGGER.log(
|
||||
'OrganizationInvitationAcceptSucceeded',
|
||||
{ organizationId: orgId, invitationId: data?.id },
|
||||
{ organizationId: orgId, invitationId: data?.id }
|
||||
)
|
||||
} catch {
|
||||
eventLogger.log(
|
||||
EVENT_LOGGER.log(
|
||||
'OrganizationInvitationAcceptFailed',
|
||||
{ organizationId: orgId, invitationId: data?.id },
|
||||
{ organizationId: orgId, invitationId: data?.id }
|
||||
@ -145,7 +145,7 @@ export const OrgInvitationPage: React.FunctionComponent<React.PropsWithChildren<
|
||||
}, [data?.id, navigate, orgId, orgName, respondToInvitation, willVerifyEmail])
|
||||
|
||||
const declineInvitation = useCallback(async () => {
|
||||
eventLogger.log(
|
||||
EVENT_LOGGER.log(
|
||||
'OrganizationInvitationDeclineClicked',
|
||||
{
|
||||
organizationId: orgId,
|
||||
@ -165,13 +165,13 @@ export const OrgInvitationPage: React.FunctionComponent<React.PropsWithChildren<
|
||||
response: OrganizationInvitationResponseType.REJECT,
|
||||
},
|
||||
})
|
||||
eventLogger.log(
|
||||
EVENT_LOGGER.log(
|
||||
'OrganizationInvitationDeclineSucceeded',
|
||||
{ organizationId: orgId, invitationId: data?.id },
|
||||
{ organizationId: orgId, invitationId: data?.id }
|
||||
)
|
||||
} catch {
|
||||
eventLogger.log(
|
||||
EVENT_LOGGER.log(
|
||||
'OrganizationInvitationDeclineFailed',
|
||||
{ organizationId: orgId, invitationId: data?.id },
|
||||
{ organizationId: orgId, invitationId: data?.id }
|
||||
|
||||
@ -3,12 +3,12 @@ import React, { useCallback, useEffect, useState } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
|
||||
import { asError, isErrorLike } from '@sourcegraph/common'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Button, Container, PageHeader, LoadingSpinner, Link, Input, ErrorAlert, Form } from '@sourcegraph/wildcard'
|
||||
|
||||
import { ORG_NAME_MAX_LENGTH, VALID_ORG_NAME_REGEXP } from '..'
|
||||
import { Page } from '../../components/Page'
|
||||
import { PageTitle } from '../../components/PageTitle'
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
import { createOrganization } from '../backend'
|
||||
|
||||
import styles from './NewOrganizationPage.module.scss'
|
||||
@ -18,7 +18,7 @@ interface Props {}
|
||||
export const NewOrganizationPage: React.FunctionComponent<React.PropsWithChildren<Props>> = () => {
|
||||
const navigate = useNavigate()
|
||||
useEffect(() => {
|
||||
eventLogger.logViewEvent('NewOrg')
|
||||
EVENT_LOGGER.logViewEvent('NewOrg')
|
||||
}, [])
|
||||
const [loading, setLoading] = useState<boolean | Error>(false)
|
||||
const [name, setName] = useState<string>('')
|
||||
@ -36,7 +36,7 @@ export const NewOrganizationPage: React.FunctionComponent<React.PropsWithChildre
|
||||
const onSubmit = useCallback<React.FormEventHandler<HTMLFormElement>>(
|
||||
async event => {
|
||||
event.preventDefault()
|
||||
eventLogger.log('CreateNewOrgClicked')
|
||||
EVENT_LOGGER.log('CreateNewOrgClicked')
|
||||
if (!event.currentTarget.checkValidity()) {
|
||||
return
|
||||
}
|
||||
|
||||
@ -4,9 +4,9 @@ import { gql, useMutation } from '@apollo/client'
|
||||
import { mdiClose } from '@mdi/js'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Button, Input, LoadingSpinner, Modal, Icon, H3, Text } from '@sourcegraph/wildcard'
|
||||
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
import type { OrgAreaRouteContext } from '../area/OrgArea'
|
||||
|
||||
interface DeleteOrgModalProps extends OrgAreaRouteContext {
|
||||
@ -52,7 +52,7 @@ export const DeleteOrgModal: React.FunctionComponent<React.PropsWithChildren<Del
|
||||
pathname: '/settings',
|
||||
})
|
||||
} catch {
|
||||
eventLogger.log('OrgDeletionFailed')
|
||||
EVENT_LOGGER.log('OrgDeletionFailed')
|
||||
}
|
||||
}, [org, deleteOrganization, navigate])
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ import { map } from 'rxjs/operators'
|
||||
import { asError, createAggregateError, isErrorLike } from '@sourcegraph/common'
|
||||
import { gql } from '@sourcegraph/http-client'
|
||||
import type { Scalars } from '@sourcegraph/shared/src/graphql-operations'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import {
|
||||
LoadingSpinner,
|
||||
Button,
|
||||
@ -33,7 +34,6 @@ import type {
|
||||
AddUserToOrganizationVariables,
|
||||
InviteUserToOrganizationFields,
|
||||
} from '../../../graphql-operations'
|
||||
import { eventLogger } from '../../../tracking/eventLogger'
|
||||
|
||||
import styles from './InviteForm.module.scss'
|
||||
|
||||
@ -68,7 +68,7 @@ export const InviteForm: React.FunctionComponent<React.PropsWithChildren<Props>>
|
||||
const [isInviteShown, setShowInvitation] = useState<boolean>(false)
|
||||
|
||||
const inviteUser = useCallback(() => {
|
||||
eventLogger.log('InviteOrgMemberClicked')
|
||||
EVENT_LOGGER.log('InviteOrgMemberClicked')
|
||||
;(async () => {
|
||||
setLoading('inviteUserToOrganization')
|
||||
const { invitationURL, sentInvitationEmail } = await inviteUserToOrganization(username, orgID)
|
||||
@ -226,10 +226,10 @@ function inviteUserToOrganization(
|
||||
).pipe(
|
||||
map(({ data, errors }) => {
|
||||
if (!data?.inviteUserToOrganization || (errors && errors.length > 0)) {
|
||||
eventLogger.log('InviteOrgMemberFailed')
|
||||
EVENT_LOGGER.log('InviteOrgMemberFailed')
|
||||
throw createAggregateError(errors)
|
||||
}
|
||||
eventLogger.log('OrgMemberInvited')
|
||||
EVENT_LOGGER.log('OrgMemberInvited')
|
||||
return data.inviteUserToOrganization
|
||||
})
|
||||
)
|
||||
@ -253,10 +253,10 @@ function addUserToOrganization(username: string, organization: Scalars['ID']): P
|
||||
).pipe(
|
||||
map(({ data, errors }) => {
|
||||
if (!data?.addUserToOrganization || (errors && errors.length > 0)) {
|
||||
eventLogger.log('AddOrgMemberFailed')
|
||||
EVENT_LOGGER.log('AddOrgMemberFailed')
|
||||
throw createAggregateError(errors)
|
||||
}
|
||||
eventLogger.log('OrgMemberAdded')
|
||||
EVENT_LOGGER.log('OrgMemberAdded')
|
||||
})
|
||||
)
|
||||
)
|
||||
|
||||
@ -6,6 +6,7 @@ import { useNavigate } from 'react-router-dom'
|
||||
import { pluralize } from '@sourcegraph/common'
|
||||
import { useMutation } from '@sourcegraph/http-client'
|
||||
import { UserAvatar } from '@sourcegraph/shared/src/components/UserAvatar'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import {
|
||||
Container,
|
||||
PageHeader,
|
||||
@ -31,7 +32,6 @@ import type {
|
||||
RemoveUserFromOrganizationResult,
|
||||
RemoveUserFromOrganizationVariables,
|
||||
} from '../../../graphql-operations'
|
||||
import { eventLogger } from '../../../tracking/eventLogger'
|
||||
import { userURL } from '../../../user'
|
||||
import type { OrgAreaRouteContext } from '../../area/OrgArea'
|
||||
import { ORGANIZATION_MEMBERS_QUERY, REMOVE_USER_FROM_ORGANIZATION_QUERY } from '../../backend'
|
||||
@ -136,7 +136,7 @@ export const OrgSettingsMembersPage: React.FunctionComponent<Props> = ({
|
||||
onOrganizationUpdate,
|
||||
}) => {
|
||||
React.useEffect(() => {
|
||||
eventLogger.logViewEvent('OrgMembers')
|
||||
EVENT_LOGGER.logViewEvent('OrgMembers')
|
||||
}, [])
|
||||
|
||||
const navigate = useNavigate()
|
||||
|
||||
@ -2,11 +2,11 @@ import React, { useCallback, useEffect, useState } from 'react'
|
||||
|
||||
import { Timestamp } from '@sourcegraph/branded/src/components/Timestamp'
|
||||
import { asError, isErrorLike } from '@sourcegraph/common'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Container, PageHeader, Button, LoadingSpinner, Input, Text, ErrorAlert, Form } from '@sourcegraph/wildcard'
|
||||
|
||||
import { ORG_DISPLAY_NAME_MAX_LENGTH } from '../..'
|
||||
import { PageTitle } from '../../../components/PageTitle'
|
||||
import { eventLogger } from '../../../tracking/eventLogger'
|
||||
import type { OrgAreaRouteContext } from '../../area/OrgArea'
|
||||
import { updateOrganization } from '../../backend'
|
||||
|
||||
@ -20,7 +20,7 @@ export const OrgSettingsProfilePage: React.FunctionComponent<React.PropsWithChil
|
||||
onOrganizationUpdate,
|
||||
}) => {
|
||||
useEffect(() => {
|
||||
eventLogger.logViewEvent('OrgSettingsProfile')
|
||||
EVENT_LOGGER.logViewEvent('OrgSettingsProfile')
|
||||
}, [org.id])
|
||||
|
||||
const [displayName, setDisplayName] = useState<string>(org.displayName ?? '')
|
||||
|
||||
@ -9,6 +9,7 @@ import type { ViewerSettingsResult, ViewerSettingsVariables } from '@sourcegraph
|
||||
import type { PlatformContext } from '@sourcegraph/shared/src/platform/context'
|
||||
import { mutateSettings, updateSettings } from '@sourcegraph/shared/src/settings/edit'
|
||||
import { gqlToCascade, type SettingsSubject } from '@sourcegraph/shared/src/settings/settings'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import {
|
||||
toPrettyBlobURL,
|
||||
type RepoFile,
|
||||
@ -21,7 +22,6 @@ import { CallbackTelemetryProcessor } from '@sourcegraph/telemetry'
|
||||
|
||||
import { getWebGraphQLClient, requestGraphQL } from '../backend/graphql'
|
||||
import type { TelemetryRecorderProvider } from '../telemetry'
|
||||
import { eventLogger } from '../tracking/eventLogger'
|
||||
|
||||
/**
|
||||
* Creates the {@link PlatformContext} for the web app.
|
||||
@ -91,7 +91,7 @@ export function createPlatformContext(props: {
|
||||
urlToFile: toPrettyWebBlobURL,
|
||||
sourcegraphURL: window.context.externalURL,
|
||||
clientApplication: 'sourcegraph',
|
||||
telemetryService: eventLogger,
|
||||
telemetryService: EVENT_LOGGER,
|
||||
telemetryRecorder: props.telemetryRecorderProvider.getRecorder(
|
||||
window.context.debug
|
||||
? [
|
||||
|
||||
@ -20,6 +20,7 @@ import {
|
||||
import { viewerSettingsQuery } from '@sourcegraph/shared/src/backend/settings'
|
||||
import type { ViewerSettingsResult, ViewerSettingsVariables } from '@sourcegraph/shared/src/graphql-operations'
|
||||
import type { PlatformContext } from '@sourcegraph/shared/src/platform/context'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import type { Config } from '@sourcegraph/shared/src/testing/config'
|
||||
|
||||
import type {
|
||||
@ -594,10 +595,10 @@ export function createOrganization(
|
||||
}).pipe(
|
||||
mergeMap(({ data, errors }) => {
|
||||
if (!data?.createOrganization) {
|
||||
eventLogger.log('NewOrgFailed')
|
||||
EVENT_LOGGER.log('NewOrgFailed')
|
||||
throw createAggregateError(errors)
|
||||
}
|
||||
eventLogger.log('NewOrgCreated')
|
||||
EVENT_LOGGER.log('NewOrgCreated')
|
||||
return concat([data.createOrganization])
|
||||
})
|
||||
)
|
||||
@ -711,10 +712,10 @@ export function addExternalService(
|
||||
}).pipe(
|
||||
map(({ data, errors }) => {
|
||||
if (!data?.addExternalService || (errors && errors.length > 0)) {
|
||||
eventLogger.log('AddExternalServiceFailed')
|
||||
EVENT_LOGGER.log('AddExternalServiceFailed')
|
||||
throw createAggregateError(errors)
|
||||
}
|
||||
eventLogger.log('AddExternalServiceSucceeded')
|
||||
EVENT_LOGGER.log('AddExternalServiceSucceeded')
|
||||
return data.addExternalService
|
||||
})
|
||||
)
|
||||
|
||||
@ -4,6 +4,7 @@ import { createAggregateError } from '@sourcegraph/common'
|
||||
import { gql } from '@sourcegraph/http-client'
|
||||
import type { Scalars } from '@sourcegraph/shared/src/graphql-operations'
|
||||
import type { TelemetryProps } from '@sourcegraph/shared/src/telemetry/telemetryService'
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { useDebounce } from '@sourcegraph/wildcard'
|
||||
|
||||
import { useShowMorePagination } from '../../components/FilteredConnection/hooks/useShowMorePagination'
|
||||
@ -19,7 +20,6 @@ import type {
|
||||
RepositoriesForPopoverVariables,
|
||||
RepositoryPopoverFields,
|
||||
} from '../../graphql-operations'
|
||||
import { eventLogger } from '../../tracking/eventLogger'
|
||||
import {
|
||||
ConnectionPopover,
|
||||
ConnectionPopoverContainer,
|
||||
@ -69,7 +69,7 @@ export const RepositoriesPopover: React.FunctionComponent<React.PropsWithChildre
|
||||
const query = useDebounce(searchValue, 200)
|
||||
|
||||
useEffect(() => {
|
||||
eventLogger.logViewEvent('RepositoriesPopover')
|
||||
EVENT_LOGGER.logViewEvent('RepositoriesPopover')
|
||||
telemetryService.log('RepositoriesPopover')
|
||||
}, [telemetryService])
|
||||
|
||||
|
||||
@ -2,10 +2,10 @@ import * as React from 'react'
|
||||
|
||||
import MapSearchIcon from 'mdi-react/MapSearchIcon'
|
||||
|
||||
import { EVENT_LOGGER } from '@sourcegraph/shared/src/telemetry/web/eventLogger'
|
||||
import { Code, Link, Text } from '@sourcegraph/wildcard'
|
||||
|
||||
import { HeroPage } from '../components/HeroPage'
|
||||
import { eventLogger } from '../tracking/eventLogger'
|
||||
|
||||
import styles from './RepositoryNotFoundPage.module.scss'
|
||||
|
||||
@ -22,7 +22,7 @@ interface Props {
|
||||
* attempts to present the user with actions to solve the problem.
|
||||
*/
|
||||
export const RepositoryNotFoundPage: React.FunctionComponent<Props> = ({ repo, viewerCanAdminister }) => {
|
||||
React.useEffect(() => eventLogger.logViewEvent('RepositoryError'), [])
|
||||
React.useEffect(() => EVENT_LOGGER.logViewEvent('RepositoryError'), [])
|
||||
|
||||
return (
|
||||
<HeroPage
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user