Skip to content

Commit

Permalink
chore: use $exception_issue_id (#26488)
Browse files Browse the repository at this point in the history
  • Loading branch information
daibhin authored Nov 28, 2024
1 parent 2cfe91a commit 218bfdf
Show file tree
Hide file tree
Showing 26 changed files with 375 additions and 1,116 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 16 additions & 18 deletions frontend/src/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { ActivityLogItem } from 'lib/components/ActivityLog/humanizeActivity'
import { apiStatusLogic } from 'lib/logic/apiStatusLogic'
import { objectClean, toParams } from 'lib/utils'
import posthog from 'posthog-js'
import { stringifiedFingerprint } from 'scenes/error-tracking/utils'
import { RecordingComment } from 'scenes/session-recordings/player/inspector/playerInspectorLogic'
import { SavedSessionRecordingPlaylistsResult } from 'scenes/session-recordings/saved-playlists/savedSessionRecordingPlaylistsLogic'

Expand All @@ -14,7 +13,7 @@ import { Variable } from '~/queries/nodes/DataVisualization/types'
import {
DashboardFilter,
DatabaseSerializedFieldType,
ErrorTrackingGroup,
ErrorTrackingIssue,
HogCompileResponse,
HogQLVariable,
QuerySchema,
Expand Down Expand Up @@ -712,14 +711,12 @@ class ApiRequest {
return this.projectsDetail(teamId).addPathComponent('error_tracking')
}

public errorTrackingGroup(fingerprint: ErrorTrackingGroup['fingerprint'], teamId?: TeamType['id']): ApiRequest {
return this.errorTracking(teamId)
.addPathComponent('group')
.addPathComponent(stringifiedFingerprint(fingerprint))
public errorTrackingIssue(id: ErrorTrackingIssue['id'], teamId?: TeamType['id']): ApiRequest {
return this.errorTracking(teamId).addPathComponent('issue').addPathComponent(id)
}

public errorTrackingGroupMerge(fingerprint: ErrorTrackingGroup['fingerprint']): ApiRequest {
return this.errorTrackingGroup(fingerprint).addPathComponent('merge')
public errorTrackingIssueMerge(into: ErrorTrackingIssue['id']): ApiRequest {
return this.errorTrackingIssue(into).addPathComponent('merge')
}

public errorTrackingSymbolSets(teamId?: TeamType['id']): ApiRequest {
Expand Down Expand Up @@ -1862,21 +1859,22 @@ const api = {

errorTracking: {
async updateIssue(
fingerprint: ErrorTrackingGroup['fingerprint'],
data: Partial<Pick<ErrorTrackingGroup, 'assignee' | 'status'>>
): Promise<ErrorTrackingGroup> {
return await new ApiRequest().errorTrackingGroup(fingerprint).update({ data })
id: ErrorTrackingIssue['id'],
data: Partial<Pick<ErrorTrackingIssue, 'assignee' | 'status'>>
): Promise<ErrorTrackingIssue> {
return await new ApiRequest().errorTrackingIssue(id).update({ data })
},

async merge(
primaryFingerprint: ErrorTrackingGroup['fingerprint'],
mergingFingerprints: ErrorTrackingGroup['fingerprint'][]
async mergeInto(
primaryIssueId: ErrorTrackingIssue['id'],
mergingIssueIds: ErrorTrackingIssue['id'][]
): Promise<{ content: string }> {
return await new ApiRequest()
.errorTrackingGroup(primaryFingerprint)
.create({ data: { merging_fingerprints: mergingFingerprints } })
.errorTrackingIssueMerge(primaryIssueId)
.create({ data: { ids: mergingIssueIds } })
},
async updateSymbolSet(id: ErrorTrackingSymbolSet['id'], data: FormData): Promise<ErrorTrackingGroup> {

async updateSymbolSet(id: ErrorTrackingSymbolSet['id'], data: FormData): Promise<void> {
return await new ApiRequest().errorTrackingSymbolSet(id).update({ data })
},

Expand Down
48 changes: 16 additions & 32 deletions frontend/src/queries/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1893,7 +1893,7 @@
},
"results": {
"items": {
"$ref": "#/definitions/ErrorTrackingGroup"
"$ref": "#/definitions/ErrorTrackingIssue"
},
"type": "array"
},
Expand Down Expand Up @@ -4580,7 +4580,7 @@
},
"results": {
"items": {
"$ref": "#/definitions/ErrorTrackingGroup"
"$ref": "#/definitions/ErrorTrackingIssue"
},
"type": "array"
},
Expand Down Expand Up @@ -5498,7 +5498,7 @@
"enum": ["actions", "events", "data_warehouse", "new_entity"],
"type": "string"
},
"ErrorTrackingGroup": {
"ErrorTrackingIssue": {
"additionalProperties": false,
"properties": {
"assignee": {
Expand All @@ -5507,31 +5507,19 @@
"description": {
"type": ["string", "null"]
},
"exception_type": {
"type": ["string", "null"]
},
"fingerprint": {
"items": {
"type": "string"
},
"type": "array"
},
"first_seen": {
"format": "date-time",
"type": "string"
},
"id": {
"type": "string"
},
"last_seen": {
"format": "date-time",
"type": "string"
},
"merged_fingerprints": {
"items": {
"items": {
"type": "string"
},
"type": "array"
},
"type": "array"
"name": {
"type": ["string", "null"]
},
"occurrences": {
"type": "number"
Expand All @@ -5549,13 +5537,12 @@
"volume": {}
},
"required": [
"fingerprint",
"exception_type",
"merged_fingerprints",
"id",
"name",
"description",
"occurrences",
"sessions",
"users",
"description",
"first_seen",
"last_seen",
"assignee",
Expand Down Expand Up @@ -5585,11 +5572,8 @@
"filterTestAccounts": {
"type": "boolean"
},
"fingerprint": {
"items": {
"type": "string"
},
"type": "array"
"issueId": {
"type": "string"
},
"kind": {
"const": "ErrorTrackingQuery",
Expand Down Expand Up @@ -5658,7 +5642,7 @@
},
"results": {
"items": {
"$ref": "#/definitions/ErrorTrackingGroup"
"$ref": "#/definitions/ErrorTrackingIssue"
},
"type": "array"
},
Expand Down Expand Up @@ -9856,7 +9840,7 @@
},
"results": {
"items": {
"$ref": "#/definitions/ErrorTrackingGroup"
"$ref": "#/definitions/ErrorTrackingIssue"
},
"type": "array"
},
Expand Down Expand Up @@ -10529,7 +10513,7 @@
},
"results": {
"items": {
"$ref": "#/definitions/ErrorTrackingGroup"
"$ref": "#/definitions/ErrorTrackingIssue"
},
"type": "array"
},
Expand Down
13 changes: 6 additions & 7 deletions frontend/src/queries/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1934,7 +1934,7 @@ export type CachedSessionAttributionExplorerQueryResponse = CachedQueryResponse<

export interface ErrorTrackingQuery extends DataNode<ErrorTrackingQueryResponse> {
kind: NodeKind.ErrorTrackingQuery
fingerprint?: string[]
issueId?: string
select?: HogQLExpression[]
order?: 'last_seen' | 'first_seen' | 'occurrences' | 'users' | 'sessions'
dateRange: DateRange
Expand All @@ -1945,14 +1945,13 @@ export interface ErrorTrackingQuery extends DataNode<ErrorTrackingQueryResponse>
limit?: integer
}

export interface ErrorTrackingGroup {
fingerprint: string[]
exception_type: string | null
merged_fingerprints: string[][]
export interface ErrorTrackingIssue {
id: string
name: string | null
description: string | null
occurrences: number
sessions: number
users: number
description: string | null
/** @format date-time */
first_seen: string
/** @format date-time */
Expand All @@ -1963,7 +1962,7 @@ export interface ErrorTrackingGroup {
status: 'archived' | 'active' | 'resolved' | 'pending_release'
}

export interface ErrorTrackingQueryResponse extends AnalyticsQueryResponseBase<ErrorTrackingGroup[]> {
export interface ErrorTrackingQueryResponse extends AnalyticsQueryResponseBase<ErrorTrackingIssue[]> {
hasMore?: boolean
limit?: integer
offset?: integer
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/scenes/error-tracking/AssigneeSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import { LemonButton, LemonButtonProps, ProfilePicture } from '@posthog/lemon-ui
import { MemberSelect } from 'lib/components/MemberSelect'
import { fullName } from 'lib/utils'

import { ErrorTrackingGroup } from '../../queries/schema'
import { ErrorTrackingIssue } from '../../queries/schema'

export const AssigneeSelect = ({
assignee,
onChange,
showName = false,
...buttonProps
}: {
assignee: ErrorTrackingGroup['assignee']
assignee: ErrorTrackingIssue['assignee']
onChange: (userId: number | null) => void
showName?: boolean
} & Partial<Pick<LemonButtonProps, 'type'>>): JSX.Element => {
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/scenes/error-tracking/ErrorTracking.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.ErrorTracking__group {
.ErrorTracking__issue {
height: calc(100vh - 12rem);
min-height: 25rem;
}
3 changes: 1 addition & 2 deletions frontend/src/scenes/error-tracking/ErrorTracking.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { mswDecorator } from '~/mocks/browser'
import { NodeKind } from '~/queries/schema'

import { errorTrackingEventsQueryResponse, errorTrackingQueryResponse } from './__mocks__/error_tracking_query'
import { stringifiedFingerprint } from './utils'

const meta: Meta = {
title: 'Scenes-App/ErrorTracking',
Expand Down Expand Up @@ -41,7 +40,7 @@ export function ListPage(): JSX.Element {

export function GroupPage(): JSX.Element {
useEffect(() => {
router.actions.push(urls.errorTrackingGroup(stringifiedFingerprint(['TypeError'])))
router.actions.push(urls.errorTrackingIssue('id'))
}, [])
return <App />
}
33 changes: 15 additions & 18 deletions frontend/src/scenes/error-tracking/ErrorTrackingGroupScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ import './ErrorTracking.scss'
import { LemonButton, LemonDivider } from '@posthog/lemon-ui'
import { useActions, useValues } from 'kea'
import { PageHeader } from 'lib/components/PageHeader'
import { base64Decode } from 'lib/utils'
import { useEffect } from 'react'
import { SceneExport } from 'scenes/sceneTypes'

import { ErrorTrackingGroup } from '~/queries/schema'
import { ErrorTrackingIssue } from '~/queries/schema'

import { AssigneeSelect } from './AssigneeSelect'
import ErrorTrackingFilters from './ErrorTrackingFilters'
Expand All @@ -18,48 +17,46 @@ import { SymbolSetUploadModal } from './SymbolSetUploadModal'
export const scene: SceneExport = {
component: ErrorTrackingGroupScene,
logic: errorTrackingGroupSceneLogic,
paramsToProps: ({ params: { fingerprint } }): (typeof errorTrackingGroupSceneLogic)['props'] => ({
fingerprint: JSON.parse(base64Decode(decodeURIComponent(fingerprint))),
}),
paramsToProps: ({ params: { id } }): (typeof errorTrackingGroupSceneLogic)['props'] => ({ id }),
}

const STATUS_LABEL: Record<ErrorTrackingGroup['status'], string> = {
const STATUS_LABEL: Record<ErrorTrackingIssue['status'], string> = {
active: 'Active',
archived: 'Archived',
resolved: 'Resolved',
pending_release: 'Pending release',
}

export function ErrorTrackingGroupScene(): JSX.Element {
const { group, groupLoading, hasGroupActions } = useValues(errorTrackingGroupSceneLogic)
const { updateGroup, loadGroup } = useActions(errorTrackingGroupSceneLogic)
const { issue, issueLoading, hasGroupActions } = useValues(errorTrackingGroupSceneLogic)
const { updateIssue, loadIssue } = useActions(errorTrackingGroupSceneLogic)

useEffect(() => {
// don't like doing this but scene logics do not unmount after being loaded
// so this refreshes the group on each page visit in case any changes occurred
if (!groupLoading) {
loadGroup()
if (!issueLoading) {
loadIssue()
}
}, [])

return (
<>
<PageHeader
buttons={
group && hasGroupActions ? (
group.status === 'active' ? (
issue && hasGroupActions ? (
issue.status === 'active' ? (
<div className="flex divide-x gap-x-2">
<AssigneeSelect
assignee={group.assignee}
onChange={(assignee) => updateGroup({ assignee })}
assignee={issue.assignee}
onChange={(assignee) => updateIssue({ assignee })}
type="secondary"
showName
/>
<div className="flex pl-2 gap-x-2">
<LemonButton type="secondary" onClick={() => updateGroup({ status: 'archived' })}>
<LemonButton type="secondary" onClick={() => updateIssue({ status: 'archived' })}>
Archive
</LemonButton>
<LemonButton type="primary" onClick={() => updateGroup({ status: 'resolved' })}>
<LemonButton type="primary" onClick={() => updateIssue({ status: 'resolved' })}>
Resolve
</LemonButton>
</div>
Expand All @@ -68,10 +65,10 @@ export function ErrorTrackingGroupScene(): JSX.Element {
<LemonButton
type="secondary"
className="upcasefirst-letter:uppercase"
onClick={() => updateGroup({ status: 'active' })}
onClick={() => updateIssue({ status: 'active' })}
tooltip="Mark as active"
>
{STATUS_LABEL[group.status]}
{STATUS_LABEL[issue.status]}
</LemonButton>
)
) : (
Expand Down
Loading

0 comments on commit 218bfdf

Please sign in to comment.