Skip to content

Commit

Permalink
Merge branch 'master' into intercom-destination
Browse files Browse the repository at this point in the history
  • Loading branch information
MarconLP authored Mar 4, 2025
2 parents db83575 + cc26a43 commit 03191c6
Show file tree
Hide file tree
Showing 118 changed files with 9,912 additions and 661 deletions.
5 changes: 3 additions & 2 deletions dags/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@ def create_resource(self, context: dagster.InitResourceContext) -> ClickhouseClu
context.log,
client_settings=self.client_settings,
retry_policy=RetryPolicy(
max_attempts=4,
max_attempts=8,
delay=ExponentialBackoff(20),
exceptions=lambda e: (
isinstance(e, Error)
and e.code in (ErrorCodes.NETWORK_ERROR, ErrorCodes.TOO_MANY_SIMULTANEOUS_QUERIES)
and e.code
in (ErrorCodes.NETWORK_ERROR, ErrorCodes.TOO_MANY_SIMULTANEOUS_QUERIES, ErrorCodes.NOT_ENOUGH_SPACE)
),
),
)
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.
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.
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.
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.
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.
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.
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.
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.
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.
2 changes: 1 addition & 1 deletion frontend/src/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -915,7 +915,7 @@ class ApiRequest {
// Resource Access Permissions

public featureFlagAccessPermissions(flagId: FeatureFlagType['id']): ApiRequest {
return this.featureFlag(flagId, ApiConfig.getCurrentTeamId()).addPathComponent('role_access')
return this.featureFlag(flagId).addPathComponent('role_access')
}

public featureFlagAccessPermissionsDetail(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -528,5 +528,223 @@ describe('the activity log logic', () => {
'peter changed the filter conditions to apply to 76% of Initial Browser = Chrome , and 99% of Initial Browser Version = 100 on with two changes'
)
})

it('can handle changing variants from a multivariate flag', async () => {
const logic = await featureFlagsTestSetup('test flag', 'updated', [
{
type: ActivityScope.FEATURE_FLAG,
action: 'changed',
field: 'filters',
before: {
groups: [
{
properties: [],
rollout_percentage: 75,
},
],
multivariate: {
variants: [
{ key: 'control', rollout_percentage: 50 },
{ key: 'test-1', rollout_percentage: 50 },
],
},
},
after: {
groups: [
{
properties: [],
rollout_percentage: 75,
},
],
multivariate: {
variants: [
{ key: 'control', rollout_percentage: 60 },
{ key: 'test-1', rollout_percentage: 40 },
],
},
},
},
])

const actual = logic.values.humanizedActivity
expect(render(<>{actual[0].description}</>).container).toHaveTextContent(
'peter changed the rollout percentage for the variants to control: 60%, and test-1: 40% on test flag'
)
})

it('can handle removing variant from a multivariate flag', async () => {
const logic = await featureFlagsTestSetup('test flag', 'updated', [
{
type: ActivityScope.FEATURE_FLAG,
action: 'changed',
field: 'filters',
before: {
groups: [
{
properties: [],
rollout_percentage: 75,
},
],
multivariate: {
variants: [
{ key: 'control', rollout_percentage: 33 },
{ key: 'test-1', rollout_percentage: 33 },
{ key: 'test-2', rollout_percentage: 34 },
],
},
},
after: {
groups: [
{
properties: [],
rollout_percentage: 75,
},
],
multivariate: {
variants: [
{ key: 'control', rollout_percentage: 50 },
{ key: 'test-1', rollout_percentage: 50 },
],
},
},
},
])

const actual = logic.values.humanizedActivity
expect(render(<>{actual[0].description}</>).container).toHaveTextContent(
'peter changed the rollout percentage for the variants to control: 50%, and test-1: 50%, and removed variant test-2 on test flag'
)
})

it('can handle removing more than one variant from a multivariate flag', async () => {
const logic = await featureFlagsTestSetup('test flag', 'updated', [
{
type: ActivityScope.FEATURE_FLAG,
action: 'changed',
field: 'filters',
before: {
groups: [
{
properties: [],
rollout_percentage: 75,
},
],
multivariate: {
variants: [
{ key: 'control', rollout_percentage: 33 },
{ key: 'test-1', rollout_percentage: 33 },
{ key: 'test-2', rollout_percentage: 34 },
{ key: 'test-3', rollout_percentage: 34 },
],
},
},
after: {
groups: [
{
properties: [],
rollout_percentage: 75,
},
],
multivariate: {
variants: [
{ key: 'control', rollout_percentage: 50 },
{ key: 'test-1', rollout_percentage: 50 },
],
},
},
},
])

const actual = logic.values.humanizedActivity
expect(render(<>{actual[0].description}</>).container).toHaveTextContent(
'peter changed the rollout percentage for the variants to control: 50%, and test-1: 50%, and removed variants test-2, and test-3 on test flag'
)
})

it.each([
{
name: 'null multivariate',
after: { multivariate: null },
},
{
name: 'empty variants array',
after: { multivariate: { variants: [] } },
},
{
name: 'undefined multivariate',
after: { multivariate: undefined },
},
])('can handle removing all variants when $name', async ({ after }) => {
const logic = await featureFlagsTestSetup('test flag', 'updated', [
{
type: ActivityScope.FEATURE_FLAG,
action: 'changed',
field: 'filters',
before: {
groups: [
{
properties: [],
rollout_percentage: 75,
},
],
multivariate: {
variants: [
{ key: 'control', rollout_percentage: 33 },
{ key: 'test-1', rollout_percentage: 33 },
],
},
},
after: {
groups: [
{
properties: [],
rollout_percentage: 75,
},
],
...after,
},
},
])

const actual = logic.values.humanizedActivity
expect(render(<>{actual[0].description}</>).container).toHaveTextContent(
'peter removed all variants on test flag'
)
})

it('can handle removing the last variant from a multivariate flag', async () => {
const logic = await featureFlagsTestSetup('test flag', 'updated', [
{
type: ActivityScope.FEATURE_FLAG,
action: 'changed',
field: 'filters',
before: {
groups: [
{
properties: [],
rollout_percentage: 75,
},
],
multivariate: {
variants: [{ key: 'control', rollout_percentage: 100 }],
},
},
after: {
groups: [
{
properties: [],
rollout_percentage: 75,
},
],
multivariate: null,
},
},
])

const actual = logic.values.humanizedActivity
expect(render(<>{actual[0].description}</>).container).toHaveTextContent(
'peter removed the last variant on test flag'
)
})
})
})
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
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
Expand Down Expand Up @@ -78,10 +75,8 @@ export function PathRegexModal({ filter, isOpen, onSave, onClose }: PathRegexMod
</div>

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

<div className="flex flex-1 justify-end gap-2">
<LemonButton type="secondary" onClick={onClose}>
Expand Down
20 changes: 20 additions & 0 deletions frontend/src/lib/components/Sparkline.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Meta, StoryFn, StoryObj } from '@storybook/react'

import { Sparkline } from './Sparkline'

type Story = StoryObj<typeof Sparkline>
const meta: Meta<typeof Sparkline> = {
title: 'Components/Sparkline',
component: Sparkline,
}
export default meta

const Template: StoryFn<typeof Sparkline> = (args) => {
return <Sparkline {...args} className="w-full" />
}

export const BarChart: Story = Template.bind({})
BarChart.args = {
data: [10, 5, 3, 30, 22, 10, 2],
labels: ['Mon', 'Tue', 'Wed', 'Thurs', 'Fri', 'Sat', 'Sun'],
}
2 changes: 2 additions & 0 deletions frontend/src/lib/components/Sparkline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export function Sparkline({
borderColor: color,
borderWidth: type === 'line' ? 2 : 0,
pointRadius: 0,
borderRadius: 2,
}
}),
},
Expand Down Expand Up @@ -116,6 +117,7 @@ export function Sparkline({
display: true,
tickLength: 0,
},
border: { display: false },
alignToPixels: true,
afterFit: (axis) => {
// Remove unneccessary padding
Expand Down
6 changes: 0 additions & 6 deletions frontend/src/lib/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,6 @@ export const FEATURE_FLAGS = {
WEB_ANALYTICS_FOR_MOBILE: 'web-analytics-for-mobile', // owner: @robbie-c #team-web-analytics
REPLAY_FLAGS_FILTERS: 'replay-flags-filters', // owner: @pauldambra #team-replay
REPLAY_LANDING_PAGE: 'replay-landing-page', // owner :#team-replay
WEB_VITALS: 'web-vitals', // owner: @rafaeelaudibert #team-web-analytics
WEB_VITALS_TOOLBAR: 'web-vitals-toolbar', // owner: @rafaeelaudibert #team-web-analytics
WEB_REVENUE_TRACKING: 'web-revenue-tracking', // owner: @robbie-c #team-web-analytics
LLM_OBSERVABILITY: 'llm-observability', // owner: #team-ai-product-manager
ONBOARDING_SESSION_REPLAY_SEPARATE_STEP: 'onboarding-session-replay-separate-step', // owner: @joshsny #team-growth
Expand All @@ -244,15 +242,11 @@ export const FEATURE_FLAGS = {
TREE_VIEW: 'tree-view', // owner: @mariusandra #team-devex
EXPERIMENTS_NEW_QUERY_RUNNER: 'experiments-new-query-runner', // owner: #team-experiments
RECORDINGS_AI_REGEX: 'recordings-ai-regex', // owner: @veryayskiy #team-replay
PATH_CLEANING_AI_REGEX: 'path-cleaning-ai-regex', // owner: @rafaeelaudibert #team-web-analytics
EXPERIMENTS_NEW_QUERY_RUNNER_AA_TEST: 'experiments-new-query-runner-aa-test', // #team-experiments
WEB_ANALYTICS_TABLE_SORTING: 'web-analytics-table-sorting', // owner: @rafaeelaudibert #team-web-analytics
ONBOARDING_DATA_WAREHOUSE_FOR_PRODUCT_ANALYTICS: 'onboarding-data-warehouse-for-product-analytics', // owner: @joshsny #team-growth
DELAYED_LOADING_ANIMATION: 'delayed-loading-animation', // owner: @raquelmsmith
PROJECTED_TOTAL_AMOUNT: 'projected-total-amount', // owner: @zach
SESSION_RECORDINGS_PLAYLIST_COUNT_COLUMN: 'session-recordings-playlist-count-column', // owner: @pauldambra #team-replay
WEB_ANALYTICS_DOMAIN_DROPDOWN: 'web-analytics-domain-dropdown', // owner: @rafaeelaudibert #team-web-analytics
ONBOARDING_AUTHORIZED_DOMAINS: 'onboarding-authorized-domains', // owner: @rafaeelaudibert #team-web-analytics
} as const
export type FeatureFlagKey = (typeof FEATURE_FLAGS)[keyof typeof FEATURE_FLAGS]

Expand Down
7 changes: 6 additions & 1 deletion frontend/src/queries/nodes/DataTable/DataTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import {
isHogQlAggregation,
isHogQLQuery,
isInsightActorsQuery,
isRevenueExampleEventsQuery,
taxonomicEventFilterToHogQL,
taxonomicPersonFilterToHogQL,
} from '~/queries/utils'
Expand Down Expand Up @@ -560,7 +561,11 @@ export function DataTable({
expandable && columnsInResponse?.includes('*')
? {
expandedRowRender: function renderExpand({ result }) {
if (isEventsQuery(query.source) && Array.isArray(result)) {
if (
(isEventsQuery(query.source) ||
isRevenueExampleEventsQuery(query.source)) &&
Array.isArray(result)
) {
return (
<EventDetails
event={result[columnsInResponse.indexOf('*')] ?? {}}
Expand Down
8 changes: 7 additions & 1 deletion frontend/src/queries/nodes/DataTable/queryFeatures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
isEventsQuery,
isHogQLQuery,
isPersonsNode,
isRevenueExampleEventsQuery,
isSessionAttributionExplorerQuery,
isTracesQuery,
isWebExternalClicksQuery,
Expand Down Expand Up @@ -33,7 +34,12 @@ export enum QueryFeature {
export function getQueryFeatures(query: Node): Set<QueryFeature> {
const features = new Set<QueryFeature>()

if (isHogQLQuery(query) || isEventsQuery(query) || isSessionAttributionExplorerQuery(query)) {
if (
isHogQLQuery(query) ||
isEventsQuery(query) ||
isSessionAttributionExplorerQuery(query) ||
isRevenueExampleEventsQuery(query)
) {
features.add(QueryFeature.dateRangePicker)
features.add(QueryFeature.columnsInResponse)
features.add(QueryFeature.eventPropertyFilters)
Expand Down
Loading

0 comments on commit 03191c6

Please sign in to comment.