Skip to content

Commit

Permalink
Merge branch 'master' into tom/sql-missing-cursor
Browse files Browse the repository at this point in the history
  • Loading branch information
Gilbert09 authored Sep 4, 2024
2 parents b45bd90 + a5f1deb commit 0531597
Show file tree
Hide file tree
Showing 174 changed files with 3,406 additions and 2,172 deletions.
7 changes: 7 additions & 0 deletions bin/upgrade-hobby
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ else
exit
fi

if [ "$REGISTRY_URL" == "" ]
then
export REGISTRY_URL="posthog/posthog"
fi

export POSTHOG_APP_TAG="${POSTHOG_APP_TAG:-latest}"

echo "Checking for named postgres and clickhouse volumes to avoid data loss when upgrading from < 1.39"
if docker volume ls | grep -Pzoq 'clickhouse-data\n(.|\n)*postgres-data\n'
then
Expand Down
26 changes: 8 additions & 18 deletions ee/billing/quota_limiting.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def org_quota_limited_until(
if organization.never_drop_data or trust_score == 15:
return None

team_tokens = get_team_attribute_by_quota_resource(organization, resource)
team_tokens = get_team_attribute_by_quota_resource(organization)
team_being_limited = any(x in previously_quota_limited_team_tokens for x in team_tokens)

if team_being_limited:
Expand Down Expand Up @@ -237,7 +237,7 @@ def sync_org_quota_limits(organization: Organization):
previously_quota_limited_team_tokens = list_limited_team_attributes(
resource, QuotaLimitingCaches.QUOTA_LIMITER_CACHE_KEY
)
team_attributes = get_team_attribute_by_quota_resource(organization, resource)
team_attributes = get_team_attribute_by_quota_resource(organization)
result = org_quota_limited_until(organization, resource, previously_quota_limited_team_tokens)

if result:
Expand All @@ -264,24 +264,14 @@ def sync_org_quota_limits(organization: Organization):
remove_limited_team_tokens(resource, team_attributes, QuotaLimitingCaches.QUOTA_LIMITING_SUSPENDED_KEY)


def get_team_attribute_by_quota_resource(organization: Organization, resource: QuotaResource):
if resource in [QuotaResource.EVENTS, QuotaResource.RECORDINGS]:
team_tokens: list[str] = [x for x in list(organization.teams.values_list("api_token", flat=True)) if x]
def get_team_attribute_by_quota_resource(organization: Organization):
team_tokens: list[str] = [x for x in list(organization.teams.values_list("api_token", flat=True)) if x]

if not team_tokens:
capture_exception(Exception(f"quota_limiting: No team tokens found for organization: {organization.id}"))
return
if not team_tokens:
capture_exception(Exception(f"quota_limiting: No team tokens found for organization: {organization.id}"))
return

return team_tokens

if resource == QuotaResource.ROWS_SYNCED:
team_ids: list[str] = [x for x in list(organization.teams.values_list("id", flat=True)) if x]

if not team_ids:
capture_exception(Exception(f"quota_limiting: No team ids found for organization: {organization.id}"))
return

return team_ids
return team_tokens


def set_org_usage_summary(
Expand Down
6 changes: 3 additions & 3 deletions ee/billing/test/test_quota_limiting.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def test_quota_limiting_feature_flag_enabled(self, patch_feature_enabled, patch_

patch_capture.reset_mock()
# Add this org to the redis cache.
team_tokens = get_team_attribute_by_quota_resource(self.organization, QuotaResource.EVENTS)
team_tokens = get_team_attribute_by_quota_resource(self.organization)
add_limited_team_tokens(
QuotaResource.EVENTS,
{x: 1612137599 for x in team_tokens},
Expand Down Expand Up @@ -715,7 +715,7 @@ def test_sync_org_quota_limits(self):
# rows_synced uses teams, not tokens
assert sorted(
list_limited_team_attributes(QuotaResource.ROWS_SYNCED, QuotaLimitingCaches.QUOTA_LIMITER_CACHE_KEY)
) == sorted(["1337", str(self.team.pk), str(other_team.pk)])
) == sorted(["1337", str(self.team.api_token), str(other_team.api_token)])

self.organization.usage["events"]["usage"] = 80
self.organization.usage["rows_synced"]["usage"] = 36
Expand Down Expand Up @@ -748,7 +748,7 @@ def test_sync_org_quota_limits(self):
list_limited_team_attributes(
QuotaResource.ROWS_SYNCED, QuotaLimitingCaches.QUOTA_LIMITING_SUSPENDED_KEY
)
) == sorted([str(self.team.pk), str(other_team.pk)])
) == sorted([str(self.team.api_token), str(other_team.api_token)])

self.organization.usage["events"]["usage"] = 80
self.organization.usage["rows_synced"]["usage"] = 36
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.
21 changes: 18 additions & 3 deletions frontend/src/layout/navigation-3000/components/TopBar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,14 @@
.TopBar3000__trail {
display: flex;
align-items: center;
height: 1rem;
margin-top: calc(0.25rem * (1 - var(--breadcrumbs-compaction-rate)));
overflow: visible;

.TopBar3000:not(.TopBar3000--compact) & {
// 1rem of trail height ensures nice tight spacing in the full or transitioning state,
// but we don't want it in the compact state, as it causes title edit buttons to be cut off at top&bottom
height: 1rem;
}
}

.TopBar3000__here {
Expand All @@ -65,7 +70,12 @@
font-size: 1rem;
font-weight: 700;
line-height: 1.2;
visibility: var(--breadcrumbs-title-large-visibility);

.TopBar3000--compact & {
// It wouldn't be necessary to set visibility, but for some reason without this positioning
// of breadcrumbs becomes borked when entering title editing mode
visibility: hidden;
}

> * {
position: absolute;
Expand All @@ -90,7 +100,12 @@
&.TopBar3000__breadcrumb--here {
flex-shrink: 1;
cursor: default;
visibility: var(--breadcrumbs-title-small-visibility);

.TopBar3000--full & {
// It wouldn't be necessary to set visibility, but for some reason without this positioning
// of breadcrumbs becomes borked when entering title editing mode
visibility: hidden;
}

> * {
opacity: 1;
Expand Down
16 changes: 6 additions & 10 deletions frontend/src/layout/navigation-3000/components/TopBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,13 @@ export function TopBar(): JSX.Element | null {

return breadcrumbs.length ? (
<div
className="TopBar3000"
className={clsx(
'TopBar3000',
effectiveCompactionRate === 0 && 'TopBar3000--full',
effectiveCompactionRate === 1 && 'TopBar3000--compact'
)}
// eslint-disable-next-line react/forbid-dom-props
style={
{
'--breadcrumbs-compaction-rate': effectiveCompactionRate,
// It wouldn't be necessary to set visibility, but for some reason without this positioning
// of breadcrumbs becomes borked when entering title editing mode
'--breadcrumbs-title-large-visibility': effectiveCompactionRate === 1 ? 'hidden' : 'visible',
'--breadcrumbs-title-small-visibility': effectiveCompactionRate === 0 ? 'hidden' : 'visible',
} as React.CSSProperties
}
style={{ '--breadcrumbs-compaction-rate': effectiveCompactionRate } as React.CSSProperties}
>
<div className="TopBar3000__content">
{mobileLayout && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export const dataManagementSidebarLogic = kea<dataManagementSidebarLogicType>([
menuItems: [
{
label: 'View recordings',
to: urls.replay(ReplayTabs.Recent, {
to: urls.replay(ReplayTabs.Home, {
filter_group: {
type: FilterLogicalOperator.And,
values: [
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/lib/colors.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { captureException } from '@sentry/react'

import { LifecycleToggle } from '~/types'

import { LemonTagType } from './lemon-ui/LemonTag'
Expand Down Expand Up @@ -39,7 +41,9 @@ export const tagColors: LemonTagType[] = [
export function getColorVar(variable: string): string {
const colorValue = getComputedStyle(document.body).getPropertyValue('--' + variable)
if (!colorValue) {
throw new Error(`Couldn't find color variable --${variable}`)
captureException(new Error(`Couldn't find color variable --${variable}`))
// Fall back to black or white depending on the theme
return document.body.getAttribute('theme') === 'light' ? '#000' : '#fff'
}
return colorValue.trim()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,6 @@
outline: 1px solid var(--primary-3000);
}

&.react-draggable::after {
// During dashboard layout editing, we need an overlay to prevent accidental interaction with card content
position: absolute;
inset: 0;
z-index: var(--z-content-overlay);
content: '';
}

.ErrorBoundary {
width: 100%;
height: 100%;
Expand Down
12 changes: 6 additions & 6 deletions frontend/src/lib/components/Cards/handles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ export function ResizeHandle1D({ orientation }: { orientation: 'horizontal' | 'v
return (
<div className={clsx('handle', orientation)}>
<svg fill="none" height="24" viewBox="0 0 16 24" width="16" xmlns="http://www.w3.org/2000/svg">
<rect fill="#fff" height="23" rx="3.5" width="15" x=".5" y=".5" />
<g fill="#5375ff">
<rect fill="var(--bg-light)" height="23" rx="3.5" width="15" x=".5" y=".5" />
<g fill="var(--primary)">
<rect height="2" rx=".25" width="2" x="5" y="5" />
<rect height="2" rx=".25" width="2" x="9" y="5" />
<rect height="2" rx=".25" width="2" x="5" y="9" />
Expand All @@ -16,7 +16,7 @@ export function ResizeHandle1D({ orientation }: { orientation: 'horizontal' | 'v
<rect height="2" rx=".25" width="2" x="5" y="13" />
<rect height="2" rx=".25" width="2" x="5" y="17" />
</g>
<rect height="23" rx="3.5" stroke="#d9d9d9" width="15" x=".5" y=".5" />
<rect height="23" rx="3.5" stroke="var(--border)" width="15" x=".5" y=".5" />
</svg>
</div>
)
Expand All @@ -27,16 +27,16 @@ export function ResizeHandle2D(): JSX.Element {
return (
<div className="handle corner">
<svg fill="none" height="18" viewBox="0 0 18 18" width="18" xmlns="http://www.w3.org/2000/svg">
<rect fill="#fff" height="17" rx="3.5" width="17" x=".5" y=".5" />
<g fill="#5375ff">
<rect fill="var(--bg-light)" height="17" rx="3.5" width="17" x=".5" y=".5" />
<g fill="var(--primary)">
<rect height="2" rx=".25" width="2" x="8" y="8" />
<rect height="2" rx=".25" width="2" x="8" y="12" />
<rect height="2" rx=".25" width="2" x="12" y="4" />
<rect height="2" rx=".25" width="2" x="4" y="12" />
<rect height="2" rx=".25" width="2" x="12" y="8" />
<rect height="2" rx=".25" width="2" x="12" y="12" />
</g>
<rect height="17" rx="3.5" stroke="#d9d9d9" width="17" x=".5" y=".5" />
<rect height="17" rx="3.5" stroke="var(--border)" width="17" x=".5" y=".5" />
</svg>
</div>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { LemonBanner, Spinner } from '@posthog/lemon-ui'
import { useActions, useValues } from 'kea'
import { useEffect } from 'react'
import useResizeObserver from 'use-resize-observer'

import { ToolbarUserIntent } from '~/types'

import { appEditorUrl } from '../AuthorizedUrlList/authorizedUrlListLogic'
import { iframedToolbarBrowserLogic } from './iframedToolbarBrowserLogic'

function IframeErrorOverlay(): JSX.Element | null {
const logic = iframedToolbarBrowserLogic()
const { iframeBanner } = useValues(logic)
return iframeBanner ? (
<div className="absolute flex flex-col w-full h-full bg-blend-overlay items-start py-4 px-8 pointer-events-none">
<LemonBanner className="w-full" type={iframeBanner.level}>
{iframeBanner.message}. Your site might not allow being embedded in an iframe. You can click "Open in
toolbar" above to visit your site and view the heatmap there.
</LemonBanner>
</div>
) : null
}

function LoadingOverlay(): JSX.Element | null {
const logic = iframedToolbarBrowserLogic()
const { loading } = useValues(logic)
return loading ? (
<div className="absolute flex flex-col w-full h-full items-center justify-center pointer-events-none">
<Spinner className="text-5xl" textColored={true} />
</div>
) : null
}

export function IframedToolbarBrowser({
iframeRef,
userIntent,
}: {
iframeRef?: React.MutableRefObject<HTMLIFrameElement | null>
userIntent: ToolbarUserIntent
}): JSX.Element | null {
const logic = iframedToolbarBrowserLogic()

const { browserUrl } = useValues(logic)
const { onIframeLoad, setIframeWidth } = useActions(logic)

const { width: iframeWidth } = useResizeObserver<HTMLIFrameElement>({ ref: iframeRef })
useEffect(() => {
setIframeWidth(iframeWidth ?? null)
}, [iframeWidth])

return browserUrl ? (
<div className="relative flex-1 w-full h-full">
<IframeErrorOverlay />
<LoadingOverlay />
<iframe
ref={iframeRef}
className="w-full h-full"
src={appEditorUrl(browserUrl, {
userIntent: userIntent,
})}
// eslint-disable-next-line react/forbid-dom-props
style={{
background: '#FFF',
}}
onLoad={onIframeLoad}
// these two sandbox values are necessary so that the site and toolbar can run
// this is a very loose sandbox,
// but we specify it so that at least other capabilities are denied
sandbox="allow-scripts allow-same-origin"
// we don't allow things such as camera access though
allow=""
/>
</div>
) : null
}
Loading

0 comments on commit 0531597

Please sign in to comment.