Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Gate exports by data pipelines feature availability #19561

Merged
merged 11 commits into from
Jan 16, 2024
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
Loading