Skip to content

Commit

Permalink
feat: Add AI Regex Helper to path cleaning (#28512)
Browse files Browse the repository at this point in the history
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
rafaeelaudibert and github-actions[bot] authored Feb 11, 2025
1 parent 7990817 commit 039d09b
Show file tree
Hide file tree
Showing 8 changed files with 260 additions and 196 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { IconPlus } from '@posthog/icons'
import { LemonButton } from 'lib/lemon-ui/LemonButton'
import { Popover } from 'lib/lemon-ui/Popover/Popover'
import { useState } from 'react'

import { PathCleaningFilter } from '~/types'

import { PathRegexPopover } from './PathRegexPopover'
import { PathRegexModal } from './PathRegexModal'

type PathCleanFilterAddItemButtonProps = {
onAdd: (filter: PathCleaningFilter) => void
Expand All @@ -14,29 +13,25 @@ type PathCleanFilterAddItemButtonProps = {
export function PathCleanFilterAddItemButton({ onAdd }: PathCleanFilterAddItemButtonProps): JSX.Element {
const [visible, setVisible] = useState(false)
return (
<Popover
visible={visible}
onClickOutside={() => setVisible(false)}
overlay={
<PathRegexPopover
onSave={(filter: PathCleaningFilter) => {
onAdd(filter)
setVisible(false)
}}
onCancel={() => setVisible(false)}
isNew
/>
}
>
<>
<PathRegexModal
isOpen={visible}
onClose={() => setVisible(false)}
onSave={(filter: PathCleaningFilter) => {
onAdd(filter)
setVisible(false)
}}
/>

<LemonButton
onClick={() => setVisible(!visible)}
onClick={() => setVisible(true)}
type="secondary"
size="small"
icon={<IconPlus />}
sideIcon={null}
>
Add rule
</LemonButton>
</Popover>
</>
)
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { useSortable } from '@dnd-kit/sortable'
import { CSS } from '@dnd-kit/utilities'
import { IconArrowCircleRight } from '@posthog/icons'
import { LemonSnack, Popover, Tooltip } from '@posthog/lemon-ui'
import { LemonSnack, Tooltip } from '@posthog/lemon-ui'
import clsx from 'clsx'
import { isValidRegexp } from 'lib/utils/regexp'
import { useState } from 'react'

import { PathCleaningFilter } from '~/types'

import { PathRegexPopover } from './PathRegexPopover'
import { PathRegexModal } from './PathRegexModal'

interface PathCleanFilterItem {
filter: PathCleaningFilter
Expand All @@ -24,21 +24,18 @@ export function PathCleanFilterItem({ filter, onChange, onRemove }: PathCleanFil
const isInvalidRegex = !isValidRegexp(regex)

return (
<Popover
visible={visible}
onClickOutside={() => setVisible(false)}
overlay={
<PathRegexPopover
<>
{visible && (
<PathRegexModal
filter={filter}
isOpen={visible}
onClose={() => setVisible(false)}
onSave={(filter: PathCleaningFilter) => {
onChange(filter)
setVisible(false)
}}
onCancel={() => setVisible(false)}
/>
}
>
{/* required for popover placement */}
)}
<div
className="relative"
ref={setNodeRef}
Expand All @@ -63,7 +60,7 @@ export function PathCleanFilterItem({ filter, onChange, onRemove }: PathCleanFil
</LemonSnack>
</Tooltip>
</div>
</Popover>
</>
)
}

Expand Down
103 changes: 103 additions & 0 deletions frontend/src/lib/components/PathCleanFilters/PathRegexModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { LemonButton, LemonInput, LemonModal, Link } from '@posthog/lemon-ui'
import { FEATURE_FLAGS } from 'lib/constants'
import { isValidRegexp } from 'lib/utils/regexp'
import { useState } from 'react'
import { AiRegexHelperButton } from 'scenes/session-recordings/components/AiRegexHelper/AiRegexHelper'
import { AiRegexHelper } from 'scenes/session-recordings/components/AiRegexHelper/AiRegexHelper'

import { PathCleaningFilter } from '~/types'

import { FlaggedFeature } from '../FlaggedFeature'

export interface PathRegexModalProps {
isOpen: boolean
onSave: (filter: PathCleaningFilter) => void
onClose: () => void
filter?: PathCleaningFilter
}

export function PathRegexModal({ filter, isOpen, onSave, onClose }: PathRegexModalProps): JSX.Element {
const [alias, setAlias] = useState(filter?.alias ?? '')
const [regex, setRegex] = useState(filter?.regex ?? '')

const isNew = !filter
const disabledReason = !alias
? 'Alias is required'
: !regex
? 'Regex is required'
: !isValidRegexp(regex)
? 'Malformed regex'
: null

return (
<LemonModal isOpen={isOpen} onClose={onClose}>
<LemonModal.Header>
{isNew ? <b>Add Path Cleaning Rule</b> : <b>Edit Path Cleaning Rule</b>}
</LemonModal.Header>

<LemonModal.Content>
<div className="px-2 py-1" data-attr="path-regex-modal-content">
<div className="space-y-2">
<div>
<span>Alias</span>
<LemonInput
value={alias}
onChange={(alias) => setAlias(alias)}
onPressEnter={() => false}
/>
<div className="text-muted">
We suggest you use <code>&lt;id&gt;</code> or <code>&lt;slug&gt;</code> to indicate a
dynamic part of the path.
</div>
</div>
<div>
<span>Regex</span>
<LemonInput
value={regex}
onChange={(regex) => setRegex(regex)}
onPressEnter={() => false}
/>
<p className="text-secondary">
<span>
Example:{' '}
<span className="font-mono text-accent-primary text-xs">
/merchant/\d+/dashboard$
</span>{' '}
(no need to escape slashes)
</span>{' '}
<br />
<span>
We use the{' '}
<Link to="https://github.com/google/re2/wiki/Syntax" target="_blank">
re2
</Link>{' '}
syntax.
</span>
</p>
</div>
</div>

<div className="flex space-between mt-3">
<FlaggedFeature flag={FEATURE_FLAGS.PATH_CLEANING_AI_REGEX}>
<AiRegexHelper onApply={setRegex} />
<AiRegexHelperButton />
</FlaggedFeature>

<div className="flex flex-1 justify-end gap-2">
<LemonButton type="secondary" onClick={onClose}>
Cancel
</LemonButton>
<LemonButton
type="primary"
onClick={() => onSave({ alias, regex })}
disabledReason={disabledReason}
>
Save
</LemonButton>
</div>
</div>
</div>
</LemonModal.Content>
</LemonModal>
)
}
73 changes: 0 additions & 73 deletions frontend/src/lib/components/PathCleanFilters/PathRegexPopover.tsx

This file was deleted.

1 change: 1 addition & 0 deletions frontend/src/lib/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ export const FEATURE_FLAGS = {
WEB_ANALYTICS_IMPROVED_PATH_CLEANING: 'web-analytics-improved-path-cleaning', // owner: @rafaeelaudibert #team-web-analytics
EXPERIMENTAL_DASHBOARD_ITEM_RENDERING: 'experimental-dashboard-item-rendering', // owner: @thmsobrmlr #team-product-analytics
RECORDINGS_AI_FILTER: 'recordings-ai-filter', // owner: @veryayskiy #team-replay
PATH_CLEANING_AI_REGEX: 'path-cleaning-ai-regex', // owner: @rafaeelaudibert #team-web-analytics
} as const
export type FeatureFlagKey = (typeof FEATURE_FLAGS)[keyof typeof FEATURE_FLAGS]

Expand Down
Loading

0 comments on commit 039d09b

Please sign in to comment.