Skip to content

Commit

Permalink
Merge branch 'master' into fix/drop-constraint-for-well-known-users
Browse files Browse the repository at this point in the history
  • Loading branch information
tomasfarias authored Nov 14, 2023
2 parents 4487fa7 + 12a7872 commit a157b3b
Show file tree
Hide file tree
Showing 72 changed files with 1,540 additions and 152 deletions.
2 changes: 1 addition & 1 deletion cypress/e2e/exports.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe('Exporting Insights', () => {
)
cy.visit(urls.insightNew())
// apply filter
cy.get('[data-attr=insight-filters-add-filter-group]').click()
cy.get('[data-attr$=add-filter-group]').click()
cy.get('[data-attr=property-select-toggle-0]').click()
cy.get('[data-attr=taxonomic-filter-searchfield]').click()
cy.get('[data-attr=prop-filter-event_properties-1]').click({ force: true })
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/retention.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe('Retention', () => {
// cy.get('[data-attr=insight-retention-add-filter-group]').click()
// cy.get('[data-attr=property-select-toggle-0]').click()

cy.get('[data-attr=insight-filters-add-filter-group]').click()
cy.get('[data-attr$=add-filter-group]').click()
cy.get('[data-attr=property-select-toggle-0]').click()
cy.get('[data-attr=taxonomic-filter-searchfield]').click()
cy.get('[data-attr=taxonomic-filter-searchfield]').type('is_demo')
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/trends.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ describe('Trends', () => {
cy.get('.taxonomic-infinite-list').find('.taxonomic-list-row').contains('Pageview').click({ force: true })
cy.get('[data-attr=trend-element-subject-0]').should('have.text', 'Pageview')

cy.get('[data-attr=insight-filters-add-filter-group]').click()
cy.get('[data-attr$=add-filter-group]').click()
cy.get('[data-attr=property-select-toggle-0]').click()
cy.get('[data-attr=taxonomic-filter-searchfield]').click()
cy.get('[data-attr=prop-filter-event_properties-1]').click({ force: true })
Expand Down
2 changes: 1 addition & 1 deletion cypress/productAnalytics/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export function interceptInsightLoad(insightType: string): string {

export const insight = {
applyFilter: (): void => {
cy.get('[data-attr=insight-filters-add-filter-group]').click()
cy.get('[data-attr$=add-filter-group]').click()
cy.get('[data-attr=property-select-toggle-0]').click()
cy.get('[data-attr=taxonomic-filter-searchfield]').click()
cy.get('[data-attr=prop-filter-event_properties-1]').click({ force: true })
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.
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.
22 changes: 22 additions & 0 deletions frontend/src/layout/FeaturePreviews/featurePreviewsLogic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { supportLogic } from 'lib/components/Support/supportLogic'
import { userLogic } from 'scenes/userLogic'
import { FEATURE_FLAGS, FeatureFlagKey } from 'lib/constants'
import type { featurePreviewsLogicType } from './featurePreviewsLogicType'
import { actionToUrl, router, urlToAction } from 'kea-router'

/** Features that can only be toggled if you fall under the `${flagKey}-preview` flag */
export const CONSTRAINED_PREVIEWS: Set<FeatureFlagKey> = new Set([FEATURE_FLAGS.POSTHOG_3000])
Expand Down Expand Up @@ -107,4 +108,25 @@ export const featurePreviewsLogic = kea<featurePreviewsLogicType>([
}),
],
}),
urlToAction(({ actions }) => ({
'*': (_, _search, hashParams) => {
if (hashParams['panel'] === 'feature-previews') {
actions.showFeaturePreviewsModal()
}
},
})),
actionToUrl(() => {
return {
showFeaturePreviewsModal: () => {
const hashParams = router.values.hashParams
hashParams['panel'] = 'feature-previews'
return [router.values.location.pathname, router.values.searchParams, hashParams]
},
hideFeaturePreviewsModal: () => {
const hashParams = router.values.hashParams
delete hashParams['panel']
return [router.values.location.pathname, router.values.searchParams, hashParams]
},
}
}),
])
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { LemonButton, Tooltip } from '@posthog/lemon-ui'
import { useActions } from 'kea'
import { IconClose } from 'lib/lemon-ui/icons'
import { sidePanelStateLogic } from '../sidePanelStateLogic'

export function SidePanelPaneHeader({ children }: { children: React.ReactNode }): JSX.Element {
const { closeSidePanel } = useActions(sidePanelStateLogic)

return (
<header className="border-b flex-0 p-1 flex items-center justify-end gap-1 h-10">
{children}
<Tooltip placement="bottomRight" title="Close this side panel">
<LemonButton size="small" sideIcon={<IconClose />} onClick={() => closeSidePanel()} />
</Tooltip>
</header>
)
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,98 @@
import { useValues } from 'kea'
import { sidePanelDocsLogic } from './sidePanelDocsLogic'
import { useActions, useValues } from 'kea'
import { POSTHOG_WEBSITE_ORIGIN, sidePanelDocsLogic } from './sidePanelDocsLogic'
import { useEffect, useRef, useState } from 'react'
import clsx from 'clsx'
import { SidePanelPaneHeader } from '../components/SidePanelPane'
import { LemonButton, LemonSkeleton } from '@posthog/lemon-ui'
import { IconExternal } from '@posthog/icons'
import { themeLogic } from '../../themeLogic'

function SidePanelDocsSkeleton(): JSX.Element {
return (
<div className="absolute inset-0 p-4 space-y-2">
<LemonSkeleton className="w-full h-10 mb-12" />
<LemonSkeleton className="w-1/3 h-8" />
<LemonSkeleton className="w-1/2 h-4 mb-10" />
<LemonSkeleton className="w-full h-4" />
<LemonSkeleton className="w-full h-4 opacity-80" />
<LemonSkeleton className="w-full h-4 opacity-60" />
<LemonSkeleton className="w-full h-4 opacity-40" />
<LemonSkeleton className="w-1/2 h-4 opacity-20" />
</div>
)
}

export const SidePanelDocs = (): JSX.Element => {
const { path } = useValues(sidePanelDocsLogic)
const { iframeSrc, currentUrl } = useValues(sidePanelDocsLogic)
const { updatePath, unmountIframe, closeSidePanel, handleExternalUrl } = useActions(sidePanelDocsLogic)
const ref = useRef<HTMLIFrameElement>(null)
const [ready, setReady] = useState(false)
const { isDarkModeOn } = useValues(themeLogic)

useEffect(() => {
ref.current?.contentWindow?.postMessage(
{
type: 'theme-toggle',
isDarkModeOn,
},
'*'
)
}, [isDarkModeOn, ref.current])

useEffect(() => {
const onMessage = (event: MessageEvent): void => {
if (event.origin === POSTHOG_WEBSITE_ORIGIN) {
if (event.data.type === 'internal-navigation') {
updatePath(event.data.url)
return
}
if (event.data.type === 'docs-ready') {
setReady(true)
return
}

if (event.data.type === 'external-navigation') {
// This should only be triggered for app|eu.posthog.com links
handleExternalUrl(event.data.url)
return
}

console.warn('Unhandled iframe message from Docs:', event.data)
}
}

window.addEventListener('message', onMessage)

return () => window.removeEventListener('message', onMessage)
}, [ref.current])

useEffect(() => {
window.addEventListener('beforeunload', unmountIframe)

return () => {
window.removeEventListener('beforeunload', unmountIframe)
unmountIframe()
}
}, [])

// NOTE: Currently we can't detect url changes from the iframe
return (
<div className="w-full h-full overflow-hidden">
<iframe src={`https://posthog.com${path ?? ''}`} title="Docs" className="w-full h-full" />
</div>
<>
<SidePanelPaneHeader>
<LemonButton
size="small"
sideIcon={<IconExternal />}
to={currentUrl}
targetBlank
onClick={() => closeSidePanel()}
>
Open in new tab
</LemonButton>
</SidePanelPaneHeader>
<div className="relative flex-1">
<iframe src={iframeSrc} title="Docs" className={clsx('w-full h-full', !ready && 'hidden')} ref={ref} />

{!ready && <SidePanelDocsSkeleton />}
</div>
</>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import { useActions, useValues } from 'kea'
import { sidePanelSettingsLogic } from './sidePanelSettingsLogic'
import { Settings } from 'scenes/settings/Settings'
import { LemonButton } from '@posthog/lemon-ui'
import { IconOpenInNew } from 'lib/lemon-ui/icons'
import { urls } from 'scenes/urls'
import { SettingsLogicProps, settingsLogic } from 'scenes/settings/settingsLogic'
import { useEffect } from 'react'
import { SidePanelPaneHeader } from '../components/SidePanelPane'
import { IconExternal } from '@posthog/icons'

export const SidePanelSettings = (): JSX.Element => {
const { settings } = useValues(sidePanelSettingsLogic)
Expand All @@ -26,19 +27,16 @@ export const SidePanelSettings = (): JSX.Element => {

return (
<div className="flex flex-col overflow-hidden">
<div className="border-b flex-0 p-1 flex items-center justify-end gap-2">
<SidePanelPaneHeader>
<LemonButton
size="small"
to={urls.settings(settings.sectionId ?? settings.settingLevelId, settings.settingId)}
onClick={() => closeSidePanel()}
icon={<IconOpenInNew />}
sideIcon={<IconExternal />}
>
All settings
</LemonButton>
<LemonButton size="small" onClick={() => closeSidePanel()}>
Done
</LemonButton>
</div>
</SidePanelPaneHeader>
<div className="flex-1 p-4 overflow-y-auto">
<Settings {...settingsLogicProps} />
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
import { actions, kea, reducers, path, listeners, connect } from 'kea'
import { actions, kea, reducers, path, listeners, connect, selectors } from 'kea'

import type { sidePanelDocsLogicType } from './sidePanelDocsLogicType'
import { sidePanelStateLogic } from '../sidePanelStateLogic'
import { SidePanelTab } from '~/types'
import { router } from 'kea-router'

const POSTHOG_COM_DOMAIN = 'https://posthog.com'
export const POSTHOG_WEBSITE_ORIGIN = 'https://posthog.com'

const sanitizePath = (path: string): string => {
return path[0] === '/' ? path : `/${path}`
}

export const getPathFromUrl = (urlOrPath: string): string => {
// NOTE: This is not a perfect function - it is mostly meant for the specific use cases of these docs
try {
const url = new URL(urlOrPath)
return url.pathname + url.search + url.hash
} catch (e) {
return urlOrPath
}
}

export const sidePanelDocsLogic = kea<sidePanelDocsLogicType>([
path(['scenes', 'navigation', 'sidepanel', 'sidePanelDocsLogic']),
Expand All @@ -14,32 +29,56 @@ export const sidePanelDocsLogic = kea<sidePanelDocsLogicType>([

actions({
openDocsPage: (urlOrPath: string) => ({ urlOrPath }),
updatePath: (path: string) => ({ path }),
setInitialPath: (path: string) => ({ path }),
unmountIframe: true,
handleExternalUrl: (urlOrPath: string) => ({ urlOrPath }),
}),

reducers(() => ({
path: [
currentPath: [
null as string | null,
{
updatePath: (_, { path }) => sanitizePath(path),
},
],
initialPath: [
'/docs' as string,
{ persist: true },
{
openDocsPage: (_, { urlOrPath }) => {
let path = urlOrPath
try {
const url = new URL(urlOrPath)
if (url.origin === POSTHOG_COM_DOMAIN) {
path = url.pathname + url.search
}
} catch (e) {
// not a valid URL, continue
}

return path[0] === '/' ? path : `/${path}`
},
setInitialPath: (_, { path }) => sanitizePath(path),
},
],
})),

listeners(({ actions }) => ({
openDocsPage: () => {
selectors({
iframeSrc: [
(s) => [s.initialPath],
(initialPath) => {
return `${POSTHOG_WEBSITE_ORIGIN}${initialPath ?? ''}`
},
],
currentUrl: [
(s) => [s.currentPath],
(currentPath) => {
return `${POSTHOG_WEBSITE_ORIGIN}${currentPath ?? ''}`
},
],
}),

listeners(({ actions, values }) => ({
openDocsPage: ({ urlOrPath }) => {
actions.setInitialPath(getPathFromUrl(urlOrPath))
actions.openSidePanel(SidePanelTab.Docs)
},

unmountIframe: () => {
// Update the initialPath so that next time we load it is the same as last time
actions.setInitialPath(values.currentPath ?? '/docs')
},

handleExternalUrl: ({ urlOrPath }) => {
router.actions.push(getPathFromUrl(urlOrPath))
},
})),
])
21 changes: 18 additions & 3 deletions frontend/src/lib/components/Support/supportLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,9 +309,21 @@ export const supportLogic = kea<supportLogicType>([

urlToAction(({ actions, values }) => ({
'*': (_, _search, hashParams) => {
if ('supportModal' in hashParams && !values.isSupportFormOpen) {
if (values.isSupportFormOpen) {
return
}

// Legacy supportModal param
if ('supportModal' in hashParams) {
const [kind, area] = (hashParams['supportModal'] || '').split(':')

actions.openSupportForm(
Object.keys(SUPPORT_KIND_TO_SUBJECT).includes(kind) ? kind : null,
Object.keys(TARGET_AREA_TO_NAME).includes(area) ? area : null
)
} else if ((hashParams['panel'] as string | undefined)?.startsWith('support')) {
const [kind, area] = hashParams['panel'].split(':').slice(1)

actions.openSupportForm(
Object.keys(SUPPORT_KIND_TO_SUBJECT).includes(kind) ? kind : null,
Object.keys(TARGET_AREA_TO_NAME).includes(area) ? area : null
Expand All @@ -322,7 +334,8 @@ export const supportLogic = kea<supportLogicType>([
actionToUrl(({ values }) => {
const updateUrl = (): any => {
const hashParams = router.values.hashParams
hashParams['supportModal'] = `${values.sendSupportRequest.kind || ''}:${
delete hashParams['supportModal'] // legacy value
hashParams['panel'] = `support:${values.sendSupportRequest.kind || ''}:${
values.sendSupportRequest.target_area || ''
}`
return [router.values.location.pathname, router.values.searchParams, hashParams]
Expand All @@ -332,7 +345,9 @@ export const supportLogic = kea<supportLogicType>([
setSendSupportRequestValue: () => updateUrl(),
closeSupportForm: () => {
const hashParams = router.values.hashParams
delete hashParams['supportModal']
delete hashParams['supportModal'] // legacy value
delete hashParams['panel']

return [router.values.location.pathname, router.values.searchParams, hashParams]
},
}
Expand Down
18 changes: 18 additions & 0 deletions frontend/src/lib/lemon-ui/LemonTable/columnUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,21 @@ export function createdByColumn<T extends { created_by?: UserBasicType | null }>
),
}
}

export function updatedAtColumn<T extends { updated_at?: string | Dayjs | null }>(): LemonTableColumn<T, 'updated_at'> {
return {
title: 'Updated',
dataIndex: 'updated_at',
render: function RenderCreatedAt(updated_at) {
return updated_at ? (
<div className="whitespace-nowrap text-right">
<TZLabel time={updated_at} />
</div>
) : (
<span className="text-muted"></span>
)
},
align: 'right',
sorter: (a, b) => dayjs(a.updated_at || 0).diff(b.updated_at || 0),
}
}
Loading

0 comments on commit a157b3b

Please sign in to comment.