Skip to content

Commit

Permalink
feat: Gate exports by data pipelines feature availability (#19561)
Browse files Browse the repository at this point in the history
* feat: Gate exports by data pipelines feature availability

* storybook

* Update UI snapshots for `chromium` (1)

* add paygate to batch exports page

* fix story

* get rid of old array

* Update UI snapshots for `webkit` (2)

* Update UI snapshots for `chromium` (1)

* Update UI snapshots for `chromium` (2)

---------

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Raquel Smith <[email protected]>
  • Loading branch information
3 people authored Jan 16, 2024
1 parent 61b42fa commit 9baf0b8
Show file tree
Hide file tree
Showing 21 changed files with 120 additions and 45 deletions.
Binary file modified frontend/__snapshots__/scenes-app-apps--installed--dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/scenes-app-apps--installed--light.png
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: 2 additions & 0 deletions frontend/src/lib/api.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ export const MOCK_DEFAULT_PLUGIN: PluginType = {
},
metrics: {},
public_jobs: {},
// urls are hard-coded in frontend/src/scenes/pipeline/utils.tsx so it must be one of those URLs for tests to work
url: 'https://github.com/PostHog/downsampling-plugin',
}

export const MOCK_DEFAULT_PLUGIN_CONFIG: PluginConfigWithPluginInfo = {
Expand Down
9 changes: 7 additions & 2 deletions frontend/src/lib/components/PayGateMini/PayGateMini.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type PayGateSupportedFeatures =
| AvailableFeature.PATHS_ADVANCED
| AvailableFeature.SURVEYS_STYLING
| AvailableFeature.SURVEYS_TEXT_HTML
| AvailableFeature.DATA_PIPELINES

export interface PayGateMiniProps {
feature: PayGateSupportedFeatures
Expand Down Expand Up @@ -83,6 +84,11 @@ const FEATURE_SUMMARIES: Record<
umbrella: 'surveys customization',
docsHref: 'https://posthog.com/docs/surveys',
},
[AvailableFeature.DATA_PIPELINES]: {
description: 'Create export workflows to send your data to a destination of your choice.',
umbrella: 'data pipelines',
docsHref: 'https://posthog.com/docs/data-pipelines',
},
}

/** A sort of paywall for premium features.
Expand Down Expand Up @@ -143,8 +149,7 @@ export function PayGateMini({
? '/organization/billing'
: undefined
}
type="secondary"
fullWidth
type="primary"
center
>
{gateVariant === 'add-card'
Expand Down
1 change: 1 addition & 0 deletions frontend/src/lib/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ export const FEATURE_MINIMUM_PLAN: Partial<Record<AvailableFeature, LicensePlan>
[AvailableFeature.SURVEYS_STYLING]: LicensePlan.Scale,
[AvailableFeature.SURVEYS_MULTIPLE_QUESTIONS]: LicensePlan.Scale,
[AvailableFeature.SURVEYS_TEXT_HTML]: LicensePlan.Scale,
[AvailableFeature.DATA_PIPELINES]: LicensePlan.Scale,
}

export const ENTITY_MATCH_TYPE = 'entities'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,17 @@ import { Field } from 'lib/forms/Field'
import { LemonButton } from 'lib/lemon-ui/LemonButton'
import { LemonCalendarSelectInput } from 'lib/lemon-ui/LemonCalendar/LemonCalendarSelect'
import { LemonModal } from 'lib/lemon-ui/LemonModal'
import { userLogic } from 'scenes/userLogic'

import { AvailableFeature } from '~/types'

import { batchExportLogic } from './batchExportLogic'

export function BatchExportBackfillModal(): JSX.Element {
const { hasAvailableFeature } = useValues(userLogic)
if (!hasAvailableFeature(AvailableFeature.DATA_PIPELINES)) {
return <></>
}
const { batchExportConfig, isBackfillModalOpen, isBackfillFormSubmitting } = useValues(batchExportLogic)
const { closeBackfillModal } = useActions(batchExportLogic)

Expand Down
7 changes: 7 additions & 0 deletions frontend/src/scenes/batch_exports/BatchExportEditForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,17 @@ import { LemonSelectMultiple } from 'lib/lemon-ui/LemonSelectMultiple/LemonSelec
import { LemonSkeleton } from 'lib/lemon-ui/LemonSkeleton'
import { Tooltip } from 'lib/lemon-ui/Tooltip'
import { featureFlagLogic } from 'lib/logic/featureFlagLogic'
import { userLogic } from 'scenes/userLogic'

import { AvailableFeature } from '~/types'

import { batchExportsEditLogic, BatchExportsEditLogicProps } from './batchExportEditLogic'

export function BatchExportsEditForm(props: BatchExportsEditLogicProps): JSX.Element {
const { hasAvailableFeature } = useValues(userLogic)
if (!hasAvailableFeature(AvailableFeature.DATA_PIPELINES)) {
return <></>
}
const logic = batchExportsEditLogic(props)
const { isNew, batchExportConfigForm, isBatchExportConfigFormSubmitting, batchExportConfigLoading } =
useValues(logic)
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/scenes/batch_exports/BatchExportEditScene.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { useValues } from 'kea'
import { PageHeader } from 'lib/components/PageHeader'
import { SceneExport } from 'scenes/sceneTypes'
import { userLogic } from 'scenes/userLogic'

import { AvailableFeature } from '~/types'

import { BatchExportsEditForm } from './BatchExportEditForm'
import { BatchExportsEditLogicProps } from './batchExportEditLogic'
Expand All @@ -15,6 +18,10 @@ export const scene: SceneExport = {
}

export function BatchExportsEditScene(): JSX.Element {
const { hasAvailableFeature } = useValues(userLogic)
if (!hasAvailableFeature(AvailableFeature.DATA_PIPELINES)) {
return <></>
}
const { id } = useValues(batchExportsEditSceneLogic)

return (
Expand Down
7 changes: 6 additions & 1 deletion frontend/src/scenes/batch_exports/BatchExportScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ import { useEffect, useState } from 'react'
import { PipelineAppLogLevel } from 'scenes/pipeline/pipelineAppLogsLogic'
import { SceneExport } from 'scenes/sceneTypes'
import { urls } from 'scenes/urls'
import { userLogic } from 'scenes/userLogic'

import { BatchExportLogEntry } from '~/types'
import { AvailableFeature, BatchExportLogEntry } from '~/types'

import { BatchExportBackfillModal } from './BatchExportBackfillModal'
import { batchExportLogic, BatchExportLogicProps, BatchExportTab } from './batchExportLogic'
Expand All @@ -44,6 +45,10 @@ export const scene: SceneExport = {
}

export function RunsTab(): JSX.Element {
const { hasAvailableFeature } = useValues(userLogic)
if (!hasAvailableFeature(AvailableFeature.DATA_PIPELINES)) {
return <></>
}
const {
batchExportRunsResponse,
batchExportConfig,
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/scenes/batch_exports/BatchExports.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { App } from 'scenes/App'
import { urls } from 'scenes/urls'

import { mswDecorator } from '~/mocks/browser'
import { useAvailableFeatures } from '~/mocks/features'
import { AvailableFeature } from '~/types'

import { createExportServiceHandlers } from './__mocks__/api-mocks'

Expand Down Expand Up @@ -84,6 +86,7 @@ export default {
} as Meta

export const Exports: StoryFn = () => {
useAvailableFeatures([AvailableFeature.DATA_PIPELINES])
useEffect(() => {
router.actions.push(urls.batchExports())
})
Expand All @@ -96,13 +99,15 @@ Exports.parameters = {
}

export const CreateExport: StoryFn = () => {
useAvailableFeatures([AvailableFeature.DATA_PIPELINES])
useEffect(() => {
router.actions.push(urls.batchExportNew())
})
return <App />
}

export const ViewExport: StoryFn = () => {
useAvailableFeatures([AvailableFeature.DATA_PIPELINES])
useEffect(() => {
router.actions.push(urls.batchExport('1'))
})
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/scenes/batch_exports/BatchExportsListScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import { IconEllipsis } from 'lib/lemon-ui/icons'
import { LemonMenu, LemonMenuItems } from 'lib/lemon-ui/LemonMenu'
import { SceneExport } from 'scenes/sceneTypes'
import { urls } from 'scenes/urls'
import { userLogic } from 'scenes/userLogic'

import { AvailableFeature } from '~/types'

import { batchExportsListLogic } from './batchExportsListLogic'
import { BatchExportRunIcon, BatchExportTag } from './components'
Expand All @@ -14,6 +17,10 @@ export const scene: SceneExport = {
}

export function BatchExportsListScene(): JSX.Element {
const { hasAvailableFeature } = useValues(userLogic)
if (!hasAvailableFeature(AvailableFeature.DATA_PIPELINES)) {
return <></>
}
return (
<>
<PageHeader
Expand Down
38 changes: 1 addition & 37 deletions frontend/src/scenes/pipeline/appsManagementLogic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,43 +10,7 @@ import { PluginInstallationType, PluginType } from '~/types'

import type { appsManagementLogicType } from './appsManagementLogicType'
import { getInitialCode, SourcePluginKind } from './sourceAppInitialCode'
import { loadPaginatedResults } from './utils'

const GLOBAL_PLUGINS = new Set([
// frontend apps
'https://github.com/PostHog/bug-report-app',
'https://github.com/PostHog/early-access-features-app',
'https://github.com/PostHog/notification-bar-app',
'https://github.com/PostHog/pineapple-mode-app',
// filtering apps
'https://github.com/PostHog/downsampling-plugin',
'https://github.com/PostHog/posthog-filter-out-plugin',
// transformation apps
'https://github.com/PostHog/language-url-splitter-app',
'https://github.com/PostHog/posthog-app-url-parameters-to-event-properties',
'https://github.com/PostHog/posthog-plugin-geoip',
'https://github.com/PostHog/posthog-url-normalizer-plugin',
'https://github.com/PostHog/property-filter-plugin',
'https://github.com/PostHog/semver-flattener-plugin',
'https://github.com/PostHog/taxonomy-plugin',
'https://github.com/PostHog/timestamp-parser-plugin',
'https://github.com/PostHog/user-agent-plugin',
// export apps
'https://github.com/PostHog/customerio-plugin',
'https://github.com/PostHog/hubspot-plugin',
'https://github.com/PostHog/pace-posthog-integration',
'https://github.com/PostHog/posthog-avo-plugin',
'https://github.com/PostHog/posthog-engage-so-plugin',
'https://github.com/PostHog/posthog-intercom-plugin',
'https://github.com/PostHog/posthog-laudspeaker-app',
'https://github.com/PostHog/posthog-patterns-app',
'https://github.com/PostHog/posthog-twilio-plugin',
'https://github.com/PostHog/posthog-variance-plugin',
'https://github.com/PostHog/rudderstack-posthog-plugin',
'https://github.com/PostHog/salesforce-plugin',
'https://github.com/PostHog/sendgrid-plugin',
'https://github.com/posthog/posthog-plugin-replicator',
])
import { GLOBAL_PLUGINS, loadPaginatedResults } from './utils'

function capturePluginEvent(event: string, plugin: PluginType, type: PluginInstallationType): void {
posthog.capture(event, {
Expand Down
41 changes: 41 additions & 0 deletions frontend/src/scenes/pipeline/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,47 @@ import { BatchExportConfiguration, PluginConfigTypeNew, PluginLogEntryType, Plug

import { PipelineAppLogLevel } from './pipelineAppLogsLogic'

const PLUGINS_ALLOWED_WITHOUT_DATA_PIPELINES_ARR = [
// frontend apps
'https://github.com/PostHog/bug-report-app',
'https://github.com/PostHog/early-access-features-app',
'https://github.com/PostHog/notification-bar-app',
'https://github.com/PostHog/pineapple-mode-app',
// filtering apps
'https://github.com/PostHog/downsampling-plugin',
'https://github.com/PostHog/posthog-filter-out-plugin',
// transformation apps
'https://github.com/PostHog/language-url-splitter-app',
'https://github.com/PostHog/posthog-app-url-parameters-to-event-properties',
'https://github.com/PostHog/posthog-plugin-geoip',
'https://github.com/PostHog/posthog-url-normalizer-plugin',
'https://github.com/PostHog/property-filter-plugin',
'https://github.com/PostHog/semver-flattener-plugin',
'https://github.com/PostHog/taxonomy-plugin',
'https://github.com/PostHog/timestamp-parser-plugin',
'https://github.com/PostHog/user-agent-plugin',
]
export const PLUGINS_ALLOWED_WITHOUT_DATA_PIPELINES = new Set([...PLUGINS_ALLOWED_WITHOUT_DATA_PIPELINES_ARR])

const GLOBAL_EXPORT_PLUGINS = [
// export apps
'https://github.com/PostHog/customerio-plugin',
'https://github.com/PostHog/hubspot-plugin',
'https://github.com/PostHog/pace-posthog-integration',
'https://github.com/PostHog/posthog-avo-plugin',
'https://github.com/PostHog/posthog-engage-so-plugin',
'https://github.com/PostHog/posthog-intercom-plugin',
'https://github.com/PostHog/posthog-laudspeaker-app',
'https://github.com/PostHog/posthog-patterns-app',
'https://github.com/PostHog/posthog-twilio-plugin',
'https://github.com/PostHog/posthog-variance-plugin',
'https://github.com/PostHog/rudderstack-posthog-plugin',
'https://github.com/PostHog/salesforce-plugin',
'https://github.com/PostHog/sendgrid-plugin',
'https://github.com/posthog/posthog-plugin-replicator',
]
export const GLOBAL_PLUGINS = new Set([...PLUGINS_ALLOWED_WITHOUT_DATA_PIPELINES_ARR, ...GLOBAL_EXPORT_PLUGINS])

export function capturePluginEvent(event: string, plugin: PluginType, pluginConfig: PluginConfigTypeNew): void {
posthog.capture(event, {
plugin_id: plugin.id,
Expand Down
13 changes: 10 additions & 3 deletions frontend/src/scenes/plugins/AppsScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { SceneExport } from 'scenes/sceneTypes'
import { urls } from 'scenes/urls'
import { userLogic } from 'scenes/userLogic'

import { AvailableFeature } from '~/types'
import { ActivityScope } from '~/types'

import { canGloballyManagePlugins, canViewPlugins } from './access'
Expand All @@ -25,10 +26,12 @@ export const scene: SceneExport = {
}

export function AppsScene(): JSX.Element | null {
const { user } = useValues(userLogic)
const { user, hasAvailableFeature } = useValues(userLogic)
const { pluginTab } = useValues(pluginsLogic)
const { setPluginTab } = useActions(pluginsLogic)

const hasDataPipelines = hasAvailableFeature(AvailableFeature.DATA_PIPELINES)

useEffect(() => {
if (!canViewPlugins(user?.organization)) {
window.location.href = '/'
Expand All @@ -44,7 +47,7 @@ export function AppsScene(): JSX.Element | null {
<PageHeader
tabbedPage
buttons={
pluginTab === PluginTab.BatchExports ? (
hasDataPipelines && pluginTab === PluginTab.BatchExports ? (
<LemonButton type="primary" to={urls.batchExportNew()}>
Create export workflow
</LemonButton>
Expand All @@ -57,7 +60,11 @@ export function AppsScene(): JSX.Element | null {
onChange={(newKey) => setPluginTab(newKey)}
tabs={[
{ key: PluginTab.Apps, label: 'Apps', content: <AppsTab /> },
{ key: PluginTab.BatchExports, label: 'Batch Exports', content: <BatchExportsTab /> },
{
key: PluginTab.BatchExports,
label: 'Batch Exports',
content: <BatchExportsTab />,
},
{
key: PluginTab.History,
label: 'History',
Expand Down
11 changes: 10 additions & 1 deletion frontend/src/scenes/plugins/tabs/apps/AppView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import { useActions, useValues } from 'kea'
import { IconEllipsis, IconErrorOutline, IconLegend, IconLink, IconSettings } from 'lib/lemon-ui/icons'
import { LemonMenu, LemonMenuItem } from 'lib/lemon-ui/LemonMenu'
import { Tooltip } from 'lib/lemon-ui/Tooltip'
import { PLUGINS_ALLOWED_WITHOUT_DATA_PIPELINES } from 'scenes/pipeline/utils'
import { PluginImage } from 'scenes/plugins/plugin/PluginImage'
import { SuccessRateBadge } from 'scenes/plugins/plugin/SuccessRateBadge'
import { pluginsLogic } from 'scenes/plugins/pluginsLogic'
import { PluginRepositoryEntry, PluginTypeWithConfig } from 'scenes/plugins/types'
import { urls } from 'scenes/urls'
import { userLogic } from 'scenes/userLogic'

import { PluginType } from '~/types'
import { AvailableFeature, PluginType } from '~/types'

import { PluginTags } from './components'

Expand All @@ -20,6 +22,13 @@ export function AppView({
}): JSX.Element {
const { showAppMetricsForPlugin, sortableEnabledPlugins } = useValues(pluginsLogic)
const { editPlugin, toggleEnabled, openReorderModal } = useActions(pluginsLogic)
const { hasAvailableFeature } = useValues(userLogic)
if (!hasAvailableFeature(AvailableFeature.DATA_PIPELINES)) {
// If the app isn't in the allowed apps list don't show it
if (!plugin.url || !PLUGINS_ALLOWED_WITHOUT_DATA_PIPELINES.has(plugin.url)) {
return <></>
}
}

const pluginConfig = 'pluginConfig' in plugin ? plugin.pluginConfig : null
const isConfigured = !!pluginConfig?.id
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { PayGateMini } from 'lib/components/PayGateMini/PayGateMini'
import { BatchExportsList } from 'scenes/batch_exports/BatchExportsListScene'

import { AvailableFeature } from '~/types'

export function BatchExportsTab(): JSX.Element {
return <BatchExportsList />
return (
<PayGateMini feature={AvailableFeature.DATA_PIPELINES}>
<BatchExportsList />
</PayGateMini>
)
}
1 change: 1 addition & 0 deletions frontend/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export enum AvailableFeature {
SURVEYS_STYLING = 'surveys_styling',
SURVEYS_TEXT_HTML = 'surveys_text_html',
SURVEYS_MULTIPLE_QUESTIONS = 'surveys_multiple_questions',
DATA_PIPELINES = 'data_pipelines',
SESSION_REPLAY_SAMPLING = 'session_replay_sampling',
RECORDING_DURATION_MINIMUM = 'replay_recording_duration_minimum',
FEATURE_FLAG_BASED_RECORDING = 'replay_feature_flag_based_recording',
Expand Down

0 comments on commit 9baf0b8

Please sign in to comment.