Skip to content

Commit

Permalink
Merge branch 'master' into fix/encryption-env-hobby
Browse files Browse the repository at this point in the history
  • Loading branch information
pauldambra authored Oct 9, 2024
2 parents 97bad3f + 376279d commit c97cd3b
Show file tree
Hide file tree
Showing 32 changed files with 1,012 additions and 3,675 deletions.
15 changes: 12 additions & 3 deletions cypress.e2e.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export default defineConfig({
// cypress default is 'top' this means sometimes the element is underneath the top navbar
// not what a human would do... so, set it to center to avoid this weird behavior
scrollBehavior: 'center',
retries: {runMode: 2},
retries: { runMode: 2 },
e2e: {
// We've imported your old cypress plugins here.
// You may want to clean this up later by importing these.
Expand Down Expand Up @@ -101,11 +101,19 @@ export default defineConfig({
.on('error', (err) => console.log('Redis client error', err))
.connect()
// Clear cache
for await (const key of redisClient.scanIterator({ TYPE: 'string', MATCH: '*cache*', COUNT: 500 })) {
for await (const key of redisClient.scanIterator({
TYPE: 'string',
MATCH: '*cache*',
COUNT: 500,
})) {
await redisClient.del(key)
}
// Also clear the more ephemeral async query statuses
for await (const key of redisClient.scanIterator({ TYPE: 'string', MATCH: 'query_async*', COUNT: 500 })) {
for await (const key of redisClient.scanIterator({
TYPE: 'string',
MATCH: 'query_async*',
COUNT: 500,
})) {
await redisClient.del(key)
}
await redisClient.quit()
Expand All @@ -117,5 +125,6 @@ export default defineConfig({
},
baseUrl: 'http://localhost:8000',
specPattern: 'cypress/e2e/**/*.{js,jsx,ts,tsx}',
chromeWebSecurity: false,
},
})
16 changes: 8 additions & 8 deletions docker/clickhouse/user_defined_function.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<functions>
<function>
<type>executable</type>
<type>executable_pool</type>
<name>aggregate_funnel</name>
<return_type>Array(Tuple(Int8, Nullable(String), Array(Float64), Array(Array(UUID))))</return_type>
<return_name>result</return_name>
Expand Down Expand Up @@ -34,7 +34,7 @@
</function>

<function>
<type>executable</type>
<type>executable_pool</type>
<name>aggregate_funnel_cohort</name>
<return_type>Array(Tuple(Int8, UInt64, Array(Float64), Array(Array(UUID))))</return_type>
<return_name>result</return_name>
Expand Down Expand Up @@ -68,7 +68,7 @@
</function>

<function>
<type>executable</type>
<type>executable_pool</type>
<name>aggregate_funnel_array</name>
<return_type>Array(Tuple(Int8, Array(String), Array(Float64), Array(Array(UUID))))</return_type>
<return_name>result</return_name>
Expand Down Expand Up @@ -102,7 +102,7 @@
</function>

<function>
<type>executable</type>
<type>executable_pool</type>
<name>aggregate_funnel_test</name>
<return_type>String</return_type>
<return_name>result</return_name>
Expand Down Expand Up @@ -136,7 +136,7 @@
</function>

<function>
<type>executable</type>
<type>executable_pool</type>
<name>aggregate_funnel_trends</name>
<return_type>Array(Tuple(DateTime, Int8, Nullable(String)))</return_type>
<return_name>result</return_name>
Expand Down Expand Up @@ -178,7 +178,7 @@
</function>

<function>
<type>executable</type>
<type>executable_pool</type>
<name>aggregate_funnel_array_trends</name>
<!-- Return type for trends is a start interval time, a success flag (1 or -1), and a breakdown value -->
<return_type>Array(Tuple(DateTime, Int8, Array(String)))</return_type>
Expand Down Expand Up @@ -217,7 +217,7 @@
</function>

<function>
<type>executable</type>
<type>executable_pool</type>
<name>aggregate_funnel_cohort_trends</name>
<!-- Return type for trends is a start interval time, a success flag (1 or -1), and a breakdown value -->
<return_type>Array(Tuple(DateTime, Int8, UInt64))</return_type>
Expand Down Expand Up @@ -256,7 +256,7 @@
</function>

<function>
<type>executable</type>
<type>executable_pool</type>
<name>aggregate_funnel_array_trends_test</name>
<return_type>String</return_type>
<return_name>result</return_name>
Expand Down
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.
30 changes: 30 additions & 0 deletions frontend/src/lib/components/Hogfetti/Hogfetti.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { LemonBanner, LemonButton } from '@posthog/lemon-ui'
import { Meta } from '@storybook/react'

import { useHogfetti } from './Hogfetti'

const meta: Meta = {
title: 'Components/Hogfetti',
}
export default meta

export function Hogfetti(): JSX.Element {
const { trigger, HogfettiComponent } = useHogfetti()

const handleClick = (): void => {
trigger()
}

return (
<>
<HogfettiComponent />
<LemonButton type="secondary" onClick={handleClick}>
Trigger Hogfetti
</LemonButton>
<LemonBanner type="warning" className="mt-4">
The rendering in Storybook is not the same as in the app so it may appear laggy here but it should be
working as expected in the app.
</LemonBanner>
</>
)
}
165 changes: 165 additions & 0 deletions frontend/src/lib/components/Hogfetti/Hogfetti.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import {
BlushingHog,
DetectiveHog,
ExperimentsHog,
ExplorerHog,
FeatureFlagHog,
HeartHog,
HospitalHog,
ListHog,
MailHog,
MicrophoneHog,
PoliceHog,
ProfessorHog,
ReadingHog,
RunningHog,
SleepingHog,
SpaceHog,
StarHog,
SupportHeroHog,
SurprisedHog,
TronHog,
WavingHog,
XRayHog,
XRayHog2,
} from 'lib/components/hedgehogs'
import React, { useCallback, useEffect, useState } from 'react'

export type HogComponent = React.ComponentType<{ width: number; height: number }>

const images: HogComponent[] = [
SurprisedHog,
XRayHog,
XRayHog2,
HospitalHog,
BlushingHog,
ExplorerHog,
RunningHog,
SpaceHog,
TronHog,
HeartHog,
StarHog,
PoliceHog,
SleepingHog,
ProfessorHog,
SupportHeroHog,
DetectiveHog,
MailHog,
FeatureFlagHog,
ExperimentsHog,
ListHog,
WavingHog,
ReadingHog,
MicrophoneHog,
]

interface Particle {
x: number
y: number
vx: number
vy: number
size: number
imageIndex: number
opacity: number
}

interface HogfettiOptions {
count?: number
power?: number
duration?: number
maxSize?: number
}

interface HogfettiHook {
trigger: () => void
HogfettiComponent: React.FC
}

export const useHogfetti = (options: HogfettiOptions = {}): HogfettiHook => {
const [particleSets, setParticleSets] = useState<Particle[][]>([])
const [dimensions, setDimensions] = useState({ width: window.innerWidth, height: window.innerHeight })

useEffect(() => {
const handleResize = (): void => {
setDimensions({ width: window.innerWidth, height: window.innerHeight })
}

window.addEventListener('resize', handleResize)
return () => window.removeEventListener('resize', handleResize)
}, [])

const { count = 50, power = 5, duration = 2000, maxSize = 60 } = options

const createParticle = (centerX: number, centerY: number): Particle => {
const angle = Math.random() * Math.PI * 2
const velocity = Math.random() * power + 2
return {
x: centerX,
y: centerY,
vx: Math.cos(angle) * velocity,
vy: Math.sin(angle) * velocity,
size: Math.random() * (maxSize - 20) + 20,
imageIndex: Math.floor(Math.random() * images.length),
opacity: 1,
}
}

const trigger = useCallback((): void => {
const centerX = Math.random() * dimensions.width
const centerY = Math.random() * dimensions.height

const newParticles = Array.from({ length: count }, () => createParticle(centerX, centerY))
setParticleSets((prev) => [...prev, newParticles])

const startTime = Date.now()
const animationFrame = (): void => {
const elapsed = Date.now() - startTime
if (elapsed < duration) {
setParticleSets((prevSets) =>
prevSets.map((set) =>
set.map((particle) => ({
...particle,
x: particle.x + particle.vx,
y: particle.y + particle.vy,
vy: particle.vy + 0.1, // Gravity effect
vx: particle.vx * 0.99, // Air resistance
opacity: 1 - elapsed / duration,
}))
)
)
requestAnimationFrame(animationFrame)
} else {
setParticleSets((prev) => prev.slice(1))
}
}
requestAnimationFrame(animationFrame)
}, [count, power, duration, maxSize, dimensions])

const HogfettiComponent: React.FC = () => (
// eslint-disable-next-line react/forbid-dom-props
<div className="fixed top-0 left-0 w-full h-full pointer-events-none" style={{ zIndex: 9999 }}>
{particleSets.flatMap((set, setIndex) =>
set.map((particle, particleIndex) => {
const HogComponent = images[particle.imageIndex]
return (
<div
key={`${setIndex}-${particleIndex}`}
className="absolute"
// eslint-disable-next-line react/forbid-dom-props
style={{
left: `${particle.x}px`,
top: `${particle.y}px`,
opacity: particle.opacity,
transition: 'opacity 0.1s linear',
}}
>
<HogComponent width={particle.size} height={particle.size} />
</div>
)
})
)}
</div>
)

return { trigger, HogfettiComponent }
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export function OperatorValueSelect({
}: OperatorValueSelectProps): JSX.Element {
const propertyDefinition = propertyDefinitions.find((pd) => pd.name === propertyKey)

const isCohortProperty = propertyKey === 'id'
const isCohortProperty = propertyKey === 'id' && type === PropertyFilterType.Cohort

// DateTime properties should not default to Exact
const isDateTimeProperty = propertyDefinition?.property_type == PropertyType.DateTime
Expand Down
Loading

0 comments on commit c97cd3b

Please sign in to comment.