Skip to content

Commit

Permalink
fiddling
Browse files Browse the repository at this point in the history
  • Loading branch information
pauldambra committed Nov 29, 2024
1 parent cb03639 commit 03e52ca
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,10 @@ export function ReadOnlyDisplay(): JSX.Element {
return <HTMLElementsDisplay elements={EXAMPLE_ELEMENTS} />
}

export function SmallReadOnlyDisplay(): JSX.Element {
return <HTMLElementsDisplay elements={EXAMPLE_ELEMENTS} size="small" />
}

export function WithoutCentralHighlightDisplay(): JSX.Element {
return <HTMLElementsDisplay elements={EXAMPLE_ELEMENTS} highlight={false} />
}
Expand Down Expand Up @@ -212,3 +216,15 @@ export function EditableDisplayWithPreselection(): JSX.Element {
export function WithUniquenessCheck(): JSX.Element {
return <HTMLElementsDisplay elements={EXAMPLE_ELEMENTS} highlight={false} editable={true} checkUniqueness={true} />
}

export function SmallWithUniquenessCheck(): JSX.Element {
return (
<HTMLElementsDisplay
elements={EXAMPLE_ELEMENTS}
highlight={false}
editable={true}
checkUniqueness={true}
size="small"
/>
)
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import clsx from 'clsx'
import { useActions, useValues } from 'kea'
import { htmlElementsDisplayLogic } from 'lib/components/HTMLElementsDisplay/htmlElementsDisplayLogic'
import { ParsedCSSSelector } from 'lib/components/HTMLElementsDisplay/preselectWithCSS'
Expand All @@ -13,7 +14,13 @@ function indent(level: number): string {
return Array(level).fill(' ').join('')
}

function CloseAllTags({ elements }: { elements: ElementType[] }): JSX.Element {
function CloseAllTags({
elements,
size = 'small',
}: {
elements: ElementType[]
size?: 'small' | 'xsmall'
}): JSX.Element {
return (
<>
{[...elements]
Expand All @@ -28,7 +35,10 @@ function CloseAllTags({ elements }: { elements: ElementType[] }): JSX.Element {
}}
>
<pre
className="whitespace-pre-wrap break-all p-0 m-0 rounded-none text-text-3000 text-sm"
className={clsx(
'whitespace-pre-wrap break-all p-0 m-0 rounded-none text-text-3000',
size === 'xsmall' ? 'text-xs' : 'text-sm'
)}
key={index}
>
{indent(elements.length - index - 2)}
Expand All @@ -47,13 +57,15 @@ function Tags({
editable,
onChange,
selectedText,
size = 'small',
}: {
elements: ElementType[]
parsedCSSSelectors: Record<number, ParsedCSSSelector>
highlight: boolean
editable: boolean
onChange: (i: number, s: ParsedCSSSelector) => void
selectedText?: string
size?: 'small' | 'xsmall'
}): JSX.Element {
return (
<>
Expand All @@ -78,6 +90,7 @@ function Tags({
highlight={highlight}
parsedCSSSelector={parsedCSSSelectors[index]}
selectedText={selectedText}
size={size}
/>
</Fade>
)
Expand All @@ -92,6 +105,7 @@ interface HTMLElementsDisplayPropsBase {
elements: ElementType[]
highlight?: boolean
selectedText?: string
size?: 'small' | 'xsmall'
}

type HTMLElementsDisplayProps =
Expand Down Expand Up @@ -119,6 +133,7 @@ export function HTMLElementsDisplay({
highlight = true,
editable = false,
checkUniqueness = false,
size = 'small',
}: HTMLElementsDisplayProps): JSX.Element {
const [key] = useState(() => `HtmlElementsDisplay.${uniqueNode++}`)

Expand All @@ -137,12 +152,12 @@ export function HTMLElementsDisplay({
const { setParsedSelectors, showAdditionalElements } = useActions(logic)

return (
<div className="flex flex-col gap-1">
<div className={clsx('flex flex-col gap-1', size === 'xsmall' && 'text-xxs')}>
{editable && !!parsedElements.length && (
<div className="flex flex-col gap-2 mb-2">
<div>Selector:</div>
<div className="w-full border rounded bg-bg-3000 px-4 py-2 select-text">
<pre className="m-0">{chosenSelector}</pre>
<pre className={clsx('m-0', size === 'xsmall' ? 'text-xxs' : 'text-sm')}>{chosenSelector}</pre>
</div>
</div>
)}
Expand All @@ -161,7 +176,10 @@ export function HTMLElementsDisplay({
<>
{elementsToShowDepth ? (
<pre
className="p-1 m-0 opacity-50 text-text-3000 text-sm cursor-pointer"
className={clsx(
'p-1 m-0 opacity-50 text-text-3000 cursor-pointer',
size === 'xsmall' ? 'text-xxs' : 'text-sm'
)}
data-attr="elements-display-show-more-of-chain"
onClick={showAdditionalElements}
>
Expand All @@ -177,8 +195,9 @@ export function HTMLElementsDisplay({
parsedCSSSelectors={parsedSelectors}
onChange={(index, s) => setParsedSelectors({ ...parsedSelectors, [index]: s })}
selectedText={selectedText}
size={size}
/>
<CloseAllTags elements={parsedElements} />
<CloseAllTags elements={parsedElements} size={size} />
</>
) : (
<div>No elements to display</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ export function SelectableElement({
highlight,
parsedCSSSelector,
selectedText,
size = 'small',
}: {
element: ElementType
isDeepestChild: boolean
Expand All @@ -202,6 +203,7 @@ export function SelectableElement({
highlight?: boolean
parsedCSSSelector?: ParsedCSSSelector
selectedText?: string
size?: 'small' | 'xsmall'
}): JSX.Element {
const setParsedCSSSelector = (newParsedCSSSelector: ParsedCSSSelector): void => {
if (!objectsEqual(newParsedCSSSelector, parsedCSSSelector)) {
Expand All @@ -212,8 +214,9 @@ export function SelectableElement({
return (
<pre
className={clsx(
'p-0 m-0 rounded whitespace-pre-wrap break-all text-text-3000 text-sm',
isDeepestChild && highlight ? 'bg-brand-red' : 'bg-transparent'
'p-0 m-0 rounded whitespace-pre-wrap break-all text-text-3000',
isDeepestChild && highlight ? 'bg-brand-red' : 'bg-transparent',
size === 'xsmall' ? 'text-xs' : 'text-sm'
)}
>
{indent}
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/lib/taxonomy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,16 @@ export const CORE_FILTER_DEFINITIONS_BY_GROUP = {
description: <span>Session recording network payload capture config.</span>,
examples: ['{"recordHeaders": false}'],
},
$configured_session_timeout_ms: {
label: 'Configured session timeout',
description: <span>Configured session timeout in milliseconds.</span>,
examples: ['1800000'],
},
$replay_script_config: {
label: 'Replay script config',
description: <span>Sets an alternative recorder script for the web sdk.</span>,
examples: ['{"script": "recorder-next""}'],
},
$session_recording_url_trigger_activated_session: {
label: 'Session recording URL trigger activated session',
description: (
Expand Down
62 changes: 62 additions & 0 deletions frontend/src/lib/utils/event-property-utls.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { Tooltip } from 'lib/lemon-ui/Tooltip'

import { ElementType } from '~/types'

export function autocaptureToImage(
elements: ElementType[]
): null | { src: string | undefined; width: string | undefined; height: string | undefined } {
const find = elements.find((el) => el.tag_name === 'img')
const image = {
src: find?.attributes?.attr__src,
width: find?.attributes?.attr__width,
height: find?.attributes?.attr__height,
}
return image.src ? image : null
}

export function AutocaptureImageTab({ elements }: { elements: ElementType[] }): JSX.Element | null {
const img = autocaptureToImage(elements)
if (img) {
return (
<div className="flex bg-bg-3000 items-center justify-center relative border-2">
{/* Transparent grid background */}
<div className="ImagePreview__background absolute h-full w-full" />

<img
className="relative z-10 max-h-100 object-contain"
src={img.src}
alt="Autocapture image src"
height={img.height || 'auto'}
width={img.width || 'auto'}
/>
</div>
)
}

return null
}

export function AutocapturePreviewImage({
elements,
imgPreviewHeight = '40',
}: {
elements: ElementType[]
imgPreviewHeight?: string
}): JSX.Element | null {
const img = autocaptureToImage(elements)
if (img) {
return (
<Tooltip title={<AutocaptureImageTab elements={elements} />}>
<img
className="max-h-10"
src={img.src}
alt="Autocapture image src"
height={imgPreviewHeight}
width="auto"
/>
</Tooltip>
)
}

return null
}
9 changes: 9 additions & 0 deletions frontend/src/scenes/activity/explore/EventDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { LemonTableProps } from 'lib/lemon-ui/LemonTable'
import { LemonTabs } from 'lib/lemon-ui/LemonTabs'
import { CORE_FILTER_DEFINITIONS_BY_GROUP, KNOWN_PROMOTED_PROPERTY_PARENTS } from 'lib/taxonomy'
import { pluralize } from 'lib/utils'
import { AutocaptureImageTab, autocaptureToImage } from 'lib/utils/event-property-utls'
import { useState } from 'react'

import { EventType, PropertyDefinitionType } from '~/types'
Expand Down Expand Up @@ -110,6 +111,14 @@ export function EventDetails({ event, tableProps }: EventDetailsProps): JSX.Elem
})
}

if (event.elements && autocaptureToImage(event.elements)) {
tabs.push({
key: 'image',
label: 'Image',
content: <AutocaptureImageTab elements={event.elements} />,
})
}

if (event.event === '$exception') {
tabs.push({
key: 'exception',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import './ImagePreview.scss'

import { LemonButton, LemonDivider, LemonTabs, Tooltip } from '@posthog/lemon-ui'
import { LemonButton, LemonDivider, LemonTabs } from '@posthog/lemon-ui'
import { useValues } from 'kea'
import { ErrorDisplay } from 'lib/components/Errors/ErrorDisplay'
import { HTMLElementsDisplay } from 'lib/components/HTMLElementsDisplay/HTMLElementsDisplay'
import { PropertyKeyInfo } from 'lib/components/PropertyKeyInfo'
import { TaxonomicFilterGroupType } from 'lib/components/TaxonomicFilter/types'
import { TitledSnack } from 'lib/components/TitledSnack'
import { IconOpenInNew } from 'lib/lemon-ui/icons'
import { Spinner } from 'lib/lemon-ui/Spinner'
import { CORE_FILTER_DEFINITIONS_BY_GROUP, POSTHOG_EVENT_PROMOTED_PROPERTIES } from 'lib/taxonomy'
import { autoCaptureEventToDescription, capitalizeFirstLetter, isString } from 'lib/utils'
import { AutocaptureImageTab, AutocapturePreviewImage, autocaptureToImage } from 'lib/utils/event-property-utls'
import { useState } from 'react'
import { insightUrlForEvent } from 'scenes/insights/utils'
import { eventPropertyFilteringLogic } from 'scenes/session-recordings/player/inspector/components/eventPropertyFilteringLogic'
import { DEFAULT_INSPECTOR_ROW_HEIGHT } from 'scenes/session-recordings/player/inspector/PlayerInspectorList'

import { ElementType } from '~/types'

import { InspectorListItemEvent } from '../playerInspectorLogic'
import { SimpleKeyValueList } from './SimpleKeyValueList'
Expand Down Expand Up @@ -56,53 +55,6 @@ function SummarizeWebVitals({ properties }: { properties: Record<string, any> })
)
}

function autocaptureToImage(
elements: ElementType[]
): null | { src: string | undefined; width: string | undefined; height: string | undefined } {
const find = elements.find((el) => el.tag_name === 'img')
const image = {
src: find?.attributes?.attr__src,
width: find?.attributes?.attr__width,
height: find?.attributes?.attr__height,
}
return image.src ? image : null
}

function AutocaptureImage({ item }: ItemEventProps): JSX.Element | null {
const img = autocaptureToImage(item.data.elements)
if (img) {
return (
<Tooltip
title={
<div className="flex bg-bg-3000 items-center justify-center relative border-2">
{/* Transparent grid background */}
<div className="ImagePreview__background absolute h-full w-full" />

{/* Image preview */}
<img
className="relative z-10 max-h-100 object-contain"
src={img.src}
alt="Autocapture image src"
height={img.height || 'auto'}
width={img.width || 'auto'}
/>
</div>
}
>
<img
className="max-h-10"
src={img.src}
alt="Autocapture image src"
height={DEFAULT_INSPECTOR_ROW_HEIGHT}
width="auto"
/>
</Tooltip>
)
}

return null
}

export function ItemEvent({ item }: ItemEventProps): JSX.Element {
const subValue =
item.data.event === '$pageview' ? (
Expand All @@ -112,7 +64,7 @@ export function ItemEvent({ item }: ItemEventProps): JSX.Element {
) : item.data.event === '$web_vitals' ? (
<SummarizeWebVitals properties={item.data.properties} />
) : item.data.elements.length ? (
<AutocaptureImage item={item} />
<AutocapturePreviewImage elements={item.data.elements} />
) : null

return (
Expand Down Expand Up @@ -140,7 +92,7 @@ export function ItemEvent({ item }: ItemEventProps): JSX.Element {
}

export function ItemEventDetail({ item }: ItemEventProps): JSX.Element {
const [activeTab, setActiveTab] = useState<'properties' | 'flags' | 'raw'>('properties')
const [activeTab, setActiveTab] = useState<'properties' | 'flags' | 'image' | 'elements' | 'raw'>('properties')

const insightUrl = insightUrlForEvent(item.data)
const { filterProperties } = useValues(eventPropertyFilteringLogic)
Expand Down Expand Up @@ -207,6 +159,26 @@ export function ItemEventDetail({ item }: ItemEventProps): JSX.Element {
<SimpleKeyValueList item={featureFlagProperties} promotedKeys={promotedKeys} />
),
},
item.data.elements && item.data.elements.length > 0
? {
key: 'elements',
label: 'Elements',
content: (
<HTMLElementsDisplay
size="xsmall"
elements={item.data.elements}
selectedText={item.data.properties['$selected_content']}
/>
),
}
: null,
autocaptureToImage(item.data.elements)
? {
key: 'image',
label: 'Image',
content: <AutocaptureImageTab elements={item.data.elements} />,
}
: null,
{
key: 'raw',
label: 'Raw',
Expand Down

0 comments on commit 03e52ca

Please sign in to comment.