Skip to content

Commit

Permalink
feat: error tracking filtering (#22988)
Browse files Browse the repository at this point in the history
  • Loading branch information
daibhin authored Jun 17, 2024
1 parent cbc7e88 commit e3481ae
Show file tree
Hide file tree
Showing 15 changed files with 255 additions and 111 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.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { IconPlusSmall } from '@posthog/icons'
import { LemonButton, LemonDropdown, Popover } from '@posthog/lemon-ui'
import { LemonButton, LemonButtonProps, LemonDropdown, Popover } from '@posthog/lemon-ui'
import { BindLogic, useActions, useValues } from 'kea'
import { useState } from 'react'

Expand Down Expand Up @@ -132,7 +132,7 @@ const Value = ({
)
}

const AddFilterButton = (): JSX.Element => {
const AddFilterButton = (props: Omit<LemonButtonProps, 'onClick' | 'sideAction' | 'icon'>): JSX.Element => {
const [dropdownOpen, setDropdownOpen] = useState<boolean>(false)

const { taxonomicGroupTypes } = useValues(universalFiltersLogic)
Expand All @@ -153,11 +153,10 @@ const AddFilterButton = (): JSX.Element => {
onClickOutside={() => setDropdownOpen(false)}
>
<LemonButton
type="secondary"
size="small"
icon={<IconPlusSmall />}
sideIcon={null}
onClick={() => setDropdownOpen(!dropdownOpen)}
{...props}
>
Add filter
</LemonButton>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/lib/lemon-ui/LemonSwitch/LemonSwitch.scss
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

&.LemonSwitch--small {
gap: 0.5rem;
min-height: 2rem;
min-height: calc(1.875rem + 3px); // Small size button height + button shadow height
padding: 0 0.5rem;
}
}
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/lib/lemon-ui/LemonSwitch/LemonSwitch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface LemonSwitchProps {
labelClassName?: string
id?: string
fullWidth?: boolean
size?: 'small' | 'medium'
bordered?: boolean
disabled?: boolean
/** Like plain `disabled`, except we enforce a reason to be shown in the tooltip. */
Expand All @@ -34,6 +35,7 @@ export const LemonSwitch: React.FunctionComponent<LemonSwitchProps & React.RefAt
checked,
fullWidth,
bordered,
size = 'medium',
disabled,
disabledReason,
label,
Expand Down Expand Up @@ -94,7 +96,7 @@ export const LemonSwitch: React.FunctionComponent<LemonSwitchProps & React.RefAt
return (
<div
ref={ref}
className={clsx('LemonSwitch', className, {
className={clsx('LemonSwitch', className, `LemonSwitch--${size}`, {
'LemonSwitch--checked': checked,
'LemonSwitch--active': isActive,
'LemonSwitch--bordered': bordered,
Expand Down
53 changes: 24 additions & 29 deletions frontend/src/queries/nodes/DataTable/renderColumn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,17 +110,16 @@ export function renderColumn(

if (value === '$autocapture' && eventRecord) {
return autoCaptureEventToDescription(eventRecord)
} else {
const content = <PropertyKeyInfo value={value} type={TaxonomicFilterGroupType.Events} />
const $sentry_url = eventRecord?.properties?.$sentry_url
return $sentry_url ? (
<Link to={$sentry_url} target="_blank">
{content}
</Link>
) : (
content
)
}
const content = <PropertyKeyInfo value={value} type={TaxonomicFilterGroupType.Events} />
const $sentry_url = eventRecord?.properties?.$sentry_url
return $sentry_url ? (
<Link to={$sentry_url} target="_blank">
{content}
</Link>
) : (
content
)
} else if (key === 'timestamp' || key === 'created_at' || key === 'session_start' || key === 'session_end') {
return <TZLabel time={value} showSeconds />
} else if (!Array.isArray(record) && key.startsWith('properties.')) {
Expand Down Expand Up @@ -250,6 +249,9 @@ export function renderColumn(
const columnName = trimQuotes(key.substring(16)) // 16 = "context.columns.".length
const Component = context?.columns?.[columnName]?.render
return Component ? <Component record={record} columnName={columnName} value={value} query={query} /> : ''
} else if (context?.columns?.[key]) {
const Component = context?.columns?.[key]?.render
return Component ? <Component record={record} columnName={key} value={value} query={query} /> : ''
} else if (key === 'id' && (isPersonsNode(query.source) || isActorsQuery(query.source))) {
return (
<CopyToClipboardInline
Expand All @@ -263,25 +265,18 @@ export function renderColumn(
} else if (key.startsWith('user.') && isTimeToSeeDataSessionsQuery(query.source)) {
const [parent, child] = key.split('.')
return typeof record === 'object' ? record[parent][child] : 'unknown'
} else {
if (typeof value === 'object') {
return <JSONViewer src={value} name={null} collapsed={Object.keys(value).length > 10 ? 0 : 1} />
} else if (
typeof value === 'string' &&
((value.startsWith('{') && value.endsWith('}')) || (value.startsWith('[') && value.endsWith(']')))
) {
try {
return (
<JSONViewer
src={JSON.parse(value)}
name={null}
collapsed={Object.keys(value).length > 10 ? 0 : 1}
/>
)
} catch (e) {
// do nothing
}
}
if (typeof value === 'object') {
return <JSONViewer src={value} name={null} collapsed={Object.keys(value).length > 10 ? 0 : 1} />
} else if (
typeof value === 'string' &&
((value.startsWith('{') && value.endsWith('}')) || (value.startsWith('[') && value.endsWith(']')))
) {
try {
return <JSONViewer src={JSON.parse(value)} name={null} collapsed={Object.keys(value).length > 10 ? 0 : 1} />
} catch (e) {
// do nothing
}
return String(value)
}
return String(value)
}
10 changes: 8 additions & 2 deletions frontend/src/queries/nodes/DataTable/renderColumnMeta.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import { isHogQLQuery, trimQuotes } from '~/queries/utils'

export interface ColumnMeta {
title?: JSX.Element | string
width?: number
width?: string | number
align?: 'left' | 'right' | 'center'
}

export function renderColumnMeta(key: string, query: DataTableNode, context?: QueryContext): ColumnMeta {
let width: number | undefined
let width: string | number | undefined
let title: JSX.Element | string | undefined
const queryFeatures = getQueryFeatures(query.source)
let align: ColumnMeta['align']
Expand Down Expand Up @@ -66,6 +66,12 @@ export function renderColumnMeta(key: string, query: DataTableNode, context?: Qu
title = queryFeatures.has(QueryFeature.selectAndOrderByColumns) ? extractExpressionComment(key) : key
}

const specifiedWidth = context?.columns?.[key]?.width

if (specifiedWidth) {
width = specifiedWidth
}

if (queryFeatures.has(QueryFeature.selectAndOrderByColumns) && !query.allowSorting) {
const sortKey = queryFeatures.has(QueryFeature.selectAndOrderByColumns)
? (query.source as EventsQuery)?.orderBy?.[0]
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/queries/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2804,6 +2804,10 @@
"enum": ["actions", "events", "data_warehouse", "new_entity"],
"type": "string"
},
"ErrorTrackingOrder": {
"enum": ["last_seen", "first_seen", "unique_occurrences", "unique_users", "unique_sessions"],
"type": "string"
},
"EventDefinition": {
"additionalProperties": false,
"properties": {
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/queries/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1189,6 +1189,8 @@ export interface WebTopClicksQueryResponse extends AnalyticsQueryResponseBase<un

export type CachedWebTopClicksQueryResponse = CachedQueryResponse<WebTopClicksQueryResponse>

export type ErrorTrackingOrder = 'last_seen' | 'first_seen' | 'unique_occurrences' | 'unique_users' | 'unique_sessions'

export enum WebStatsBreakdown {
Page = 'Page',
InitialPage = 'InitialPage',
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/queries/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export interface QueryContext {
rowProps?: (record: unknown) => Omit<HTMLProps<HTMLTableRowElement>, 'key'>
/** chart-specific rendering context **/
chartRenderingMetadata?: ChartRenderingMetadata
/** Wether queries should always be refreshed. */
/** Whether queries should always be refreshed. */
alwaysRefresh?: boolean
}

Expand Down Expand Up @@ -49,4 +49,5 @@ interface QueryContextColumn {
renderTitle?: QueryContextColumnTitleComponent
render?: QueryContextColumnComponent
align?: 'left' | 'right' | 'center' // default is left
width?: string
}
Loading

0 comments on commit e3481ae

Please sign in to comment.