chore(data-warehouse): Updated data warehouse icons to be backend driven (#37962)

This commit is contained in:
Tom Owers
2025-09-15 15:44:17 +01:00
committed by GitHub
parent f64a80b167
commit 65f13a7b60
44 changed files with 120 additions and 60 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 250 KiB

After

Width:  |  Height:  |  Size: 250 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 52 KiB

View File

@@ -23215,6 +23215,9 @@
},
"type": "array"
},
"iconPath": {
"type": "string"
},
"label": {
"type": "string"
},
@@ -23225,7 +23228,7 @@
"type": "boolean"
}
},
"required": ["name", "caption", "fields"],
"required": ["name", "caption", "fields", "iconPath"],
"type": "object"
},
"SourceFieldConfig": {

View File

@@ -3867,6 +3867,7 @@ export interface SourceConfig {
existingSource?: boolean
unreleasedSource?: boolean
betaSource?: boolean
iconPath: string
featureFlag?: string
}

View File

@@ -43,7 +43,7 @@ export const nonHogFunctionTemplatesLogic = kea<nonHogFunctionTemplatesLogicType
id: `managed-${connector.name}`,
type: 'source',
name: connector.name,
icon_url: DATA_WAREHOUSE_SOURCE_ICON_MAP[connector.name],
icon_url: connector.iconPath,
status: connector.unreleasedSource ? 'coming_soon' : connector.betaSource ? 'beta' : 'stable',
description: (
<>

View File

@@ -13,6 +13,7 @@ describe('sourceWizardLogic', () => {
const res = sourceWizardLogic.buildKeaFormDefaultFromSourceDetails({
Test: {
name: 'Stripe',
iconPath: '',
caption: null,
fields: [
{
@@ -34,6 +35,7 @@ describe('sourceWizardLogic', () => {
const res = sourceWizardLogic.buildKeaFormDefaultFromSourceDetails({
Test: {
name: 'Stripe',
iconPath: '',
caption: null,
fields: [
{
@@ -56,6 +58,7 @@ describe('sourceWizardLogic', () => {
const res = sourceWizardLogic.buildKeaFormDefaultFromSourceDetails({
Test: {
name: 'Stripe',
iconPath: '',
caption: null,
fields: [
{
@@ -92,6 +95,7 @@ describe('sourceWizardLogic', () => {
const res = sourceWizardLogic.buildKeaFormDefaultFromSourceDetails({
Test: {
name: 'Stripe',
iconPath: '',
caption: null,
fields: [
{
@@ -121,6 +125,7 @@ describe('sourceWizardLogic', () => {
const res = sourceWizardLogic.buildKeaFormDefaultFromSourceDetails({
Test: {
name: 'Stripe',
iconPath: '',
caption: null,
fields: [
{

View File

@@ -1,39 +1,20 @@
import { useValues } from 'kea'
import { useMemo } from 'react'
import { LemonSkeleton } from '@posthog/lemon-ui'
import { Link } from 'lib/lemon-ui/Link'
import { Tooltip } from 'lib/lemon-ui/Tooltip'
import { getDataWarehouseSourceUrl } from 'scenes/data-warehouse/settings/DataWarehouseManagedSourcesTable'
import BlushingHog from 'public/hedgehog/blushing-hog.png'
import IconPostHog from 'public/posthog-icon.svg'
import IconGoogleSheets from 'public/services/Google_Sheets.svg'
import IconMongodb from 'public/services/Mongodb.svg'
import IconAwsS3 from 'public/services/aws-s3.png'
import Iconazure from 'public/services/azure.png'
import IconBigQuery from 'public/services/bigquery.png'
import IconBraze from 'public/services/braze.png'
import IconChargebee from 'public/services/chargebee.png'
import IconCloudflare from 'public/services/cloudflare.png'
import IconDoIt from 'public/services/doit.svg'
import IconGoogleAds from 'public/services/google-ads.png'
import IconGoogleCloudStorage from 'public/services/google-cloud-storage.png'
import IconHubspot from 'public/services/hubspot.png'
import IconKlaviyo from 'public/services/klaviyo.png'
import IconLinkedIn from 'public/services/linkedin.png'
import IconMailchimp from 'public/services/mailchimp.png'
import IconMailjet from 'public/services/mailjet.png'
import IconMetaAds from 'public/services/meta-ads.png'
import IconMySQL from 'public/services/mysql.png'
import IconPolar from 'public/services/polar.png'
import IconPostgres from 'public/services/postgres.png'
import IconReddit from 'public/services/reddit.png'
import IconRedshift from 'public/services/redshift.png'
import IconRevenueCat from 'public/services/revenuecat.png'
import IconSalesforce from 'public/services/salesforce.png'
import IconSnowflake from 'public/services/snowflake.png'
import IconMSSQL from 'public/services/sql-azure.png'
import IconStripe from 'public/services/stripe.png'
import IconTemporalIO from 'public/services/temporal.png'
import IconVitally from 'public/services/vitally.png'
import IconZendesk from 'public/services/zendesk.png'
import { availableSourcesDataLogic } from '../new/availableSourcesDataLogic'
/**
* In some cases we don't have the backend telling us what provider we have for blob storage, so we can have some
@@ -73,38 +54,12 @@ const SIZE_PX_MAP = {
}
export const DATA_WAREHOUSE_SOURCE_ICON_MAP: Record<string, string> = {
Stripe: IconStripe,
Hubspot: IconHubspot,
Zendesk: IconZendesk,
Postgres: IconPostgres,
MySQL: IconMySQL,
Snowflake: IconSnowflake,
aws: IconAwsS3,
'google-cloud': IconGoogleCloudStorage,
'cloudflare-r2': IconCloudflare,
azure: Iconazure,
Salesforce: IconSalesforce,
MSSQL: IconMSSQL,
Vitally: IconVitally,
BigQuery: IconBigQuery,
Chargebee: IconChargebee,
RevenueCat: IconRevenueCat,
Polar: IconPolar,
BlushingHog: BlushingHog, // fallback, we don't know what this is
PostHog: IconPostHog,
GoogleAds: IconGoogleAds,
MetaAds: IconMetaAds,
Klaviyo: IconKlaviyo,
Mailchimp: IconMailchimp,
Braze: IconBraze,
Mailjet: IconMailjet,
Redshift: IconRedshift,
GoogleSheets: IconGoogleSheets,
MongoDB: IconMongodb,
TemporalIO: IconTemporalIO,
DoIt: IconDoIt,
LinkedinAds: IconLinkedIn,
RedditAds: IconReddit,
}
export function DataWarehouseSourceIcon({
@@ -117,10 +72,32 @@ export function DataWarehouseSourceIcon({
size?: 'xsmall' | 'small' | 'medium'
sizePx?: number
disableTooltip?: boolean
}): JSX.Element {
const sizePx = sizePxProps ?? SIZE_PX_MAP[size]
}): JSX.Element | null {
const { availableSources, availableSourcesLoading } = useValues(availableSourcesDataLogic)
const icon = DATA_WAREHOUSE_SOURCE_ICON_MAP[type]
const icon = useMemo(() => {
if (!availableSources) {
return null
}
const sourceConfig = availableSources[type]
if (sourceConfig) {
return sourceConfig.iconPath
}
const icon = DATA_WAREHOUSE_SOURCE_ICON_MAP[type]
return icon ?? null
}, [availableSources, type])
if (availableSourcesLoading || !availableSources) {
return <LemonSkeleton />
}
if (!icon) {
return null
}
const sizePx = sizePxProps ?? SIZE_PX_MAP[size]
if (disableTooltip) {
return (

View File

@@ -4,7 +4,6 @@ import { router } from 'kea-router'
import { useDelayedOnMountEffect } from 'lib/hooks/useOnMountEffect'
import { App } from 'scenes/App'
import empty from 'scenes/data-pipelines/__mocks__/empty.json'
import { urls } from 'scenes/urls'
import { mswDecorator, useStorybookMocks } from '~/mocks/browser'
@@ -36,7 +35,19 @@ const meta: Meta = {
'/api/billing/': {
...billingJson,
},
'/api/environments/:team_id/external_data_sources/wizard': empty,
'/api/environments/:team_id/external_data_sources/wizard': () => {
return [
200,
{
Stripe: {
name: 'Stripe',
iconPath: '/static/services/stripe.png',
fields: [],
caption: '',
},
},
]
},
},
patch: {
'/api/environments/@current/add_product_intent/': {},

View File

@@ -14664,6 +14664,7 @@ class SourceConfig(BaseModel):
SourceFieldSSHTunnelConfig,
]
]
iconPath: str
label: Optional[str] = None
name: ExternalDataSourceType
unreleasedSource: Optional[bool] = None

View File

@@ -8,7 +8,7 @@ Adding a new source should be pretty simple. We've refactored the sources so tha
4. Define the fields you'd like to collect via the `get_source_config()` method. Look at the other sources in `posthog/temporal/data_imports/sources` for examples. More info on the type of fields available is below
5. Generate the config class by running `pnpm generate:source-configs`. This will add a new class to the `posthog/temporal/data_imports/sources/generated_configs.py` file. Update all references of `Config` in the below template to your new generated class
6. Implement the logic of your source. More info on how to do this is below.
7. Add a new icon for your source in `frontend/src/scenes/data-warehouse/settings/DataWarehouseSourceIcon.tsx` - follow the existing convention here
7. Add a new icon for your source - add the icon file in `frontend/public/services/` and add the path to the `SourceConfig` (note: the path should be `/static/services/<source_name>.png`) - this is rendered in the frontend by `frontend/src/scenes/data-warehouse/settings/DataWarehouseSourceIcon.tsx` -
8. **Register your source** in `posthog/temporal/data_imports/sources/__init__.py`:
- Add import: `from .your_source.source import YourSourceClass`
- Add to `__all__` list: `"YourSourceClass"`

View File

@@ -153,6 +153,7 @@ class BigQuerySource(BaseSource[BigQuerySourceConfig]):
return SourceConfig(
name=SchemaExternalDataSourceType.BIG_QUERY,
caption="",
iconPath="/static/services/bigquery.png",
fields=cast(
list[FieldType],
[

View File

@@ -22,6 +22,7 @@ class BrazeSource(BaseSource[BrazeSourceConfig]):
return SourceConfig(
name=SchemaExternalDataSourceType.BRAZE,
label="Braze",
iconPath="/static/services/braze.png",
caption="",
fields=cast(list[FieldType], []),
unreleasedSource=True,

View File

@@ -69,6 +69,7 @@ class ChargebeeSource(BaseSource[ChargebeeSourceConfig]):
return SourceConfig(
name=SchemaExternalDataSourceType.CHARGEBEE,
caption="",
iconPath="/static/services/chargebee.png",
fields=cast(
list[FieldType],
[

View File

@@ -34,6 +34,7 @@ class TestSourceConfigGenerator(ClickhouseTestMixin):
config = SourceConfig(
name=SchemaExternalDataSourceType.STRIPE,
caption="",
iconPath="",
fields=cast(
list[FieldType],
[
@@ -136,6 +137,7 @@ class TestSourceConfigGenerator(ClickhouseTestMixin):
config = SourceConfig(
name=SchemaExternalDataSourceType.STRIPE,
caption="",
iconPath="",
fields=cast(
list[FieldType],
[
@@ -158,6 +160,7 @@ class TestSourceConfigGenerator(ClickhouseTestMixin):
config = SourceConfig(
name=SchemaExternalDataSourceType.STRIPE,
caption="",
iconPath="",
fields=cast(
list[FieldType],
[
@@ -179,6 +182,7 @@ class TestSourceConfigGenerator(ClickhouseTestMixin):
config = SourceConfig(
name=SchemaExternalDataSourceType.STRIPE,
caption="",
iconPath="",
fields=cast(
list[FieldType],
[
@@ -200,6 +204,7 @@ class TestSourceConfigGenerator(ClickhouseTestMixin):
config = SourceConfig(
name=SchemaExternalDataSourceType.STRIPE,
caption="",
iconPath="",
fields=cast(
list[FieldType],
[
@@ -236,6 +241,7 @@ class TestSourceConfigGenerator(ClickhouseTestMixin):
config = SourceConfig(
name=SchemaExternalDataSourceType.STRIPE,
caption="",
iconPath="",
fields=cast(
list[FieldType],
[
@@ -259,6 +265,7 @@ class TestSourceConfigGenerator(ClickhouseTestMixin):
config = SourceConfig(
name=SchemaExternalDataSourceType.STRIPE,
caption="",
iconPath="",
fields=cast(
list[FieldType],
[
@@ -282,6 +289,7 @@ class TestSourceConfigGenerator(ClickhouseTestMixin):
config = SourceConfig(
name=SchemaExternalDataSourceType.STRIPE,
caption="",
iconPath="",
fields=cast(
list[FieldType],
[
@@ -303,6 +311,7 @@ class TestSourceConfigGenerator(ClickhouseTestMixin):
config = SourceConfig(
name=SchemaExternalDataSourceType.STRIPE,
caption="",
iconPath="",
fields=cast(
list[FieldType],
[
@@ -361,6 +370,7 @@ class TestSourceConfigGenerator(ClickhouseTestMixin):
config = SourceConfig(
name=SchemaExternalDataSourceType.STRIPE,
caption="",
iconPath="",
fields=cast(
list[FieldType],
[
@@ -384,6 +394,7 @@ class TestSourceConfigGenerator(ClickhouseTestMixin):
config = SourceConfig(
name=SchemaExternalDataSourceType.STRIPE,
caption="",
iconPath="",
fields=cast(
list[FieldType],
[
@@ -400,6 +411,7 @@ class TestSourceConfigGenerator(ClickhouseTestMixin):
config = SourceConfig(
name=SchemaExternalDataSourceType.STRIPE,
caption="",
iconPath="",
fields=cast(
list[FieldType],
[
@@ -421,6 +433,7 @@ class TestSourceConfigGenerator(ClickhouseTestMixin):
config = SourceConfig(
name=SchemaExternalDataSourceType.STRIPE,
caption="",
iconPath="",
fields=cast(
list[FieldType],
[

View File

@@ -52,6 +52,7 @@ class DoItSource(BaseSource[DoItSourceConfig]):
name=SchemaExternalDataSourceType.DO_IT,
label="DoIt",
caption="",
iconPath="/static/services/doit.svg",
fields=cast(
list[FieldType],
[

View File

@@ -85,6 +85,7 @@ class GoogleAdsSource(BaseSource[GoogleAdsSourceConfig | GoogleAdsServiceAccount
label="Google Ads",
caption="Ensure you have granted PostHog access to your Google Ads account, learn how to do this in [the docs](https://posthog.com/docs/cdp/sources/google-ads).",
betaSource=True,
iconPath="/static/services/google-ads.png",
fields=cast(
list[FieldType],
[

View File

@@ -81,6 +81,7 @@ class GoogleSheetsSource(BaseSource[GoogleSheetsSourceConfig]):
label="Google Sheets",
caption="Ensure you have granted PostHog access to your Google Sheet as instructed in the [documentation](https://posthog.com/docs/cdp/sources/google-sheets)",
betaSource=True,
iconPath="/static/services/Google_Sheets.svg",
fields=cast(
list[FieldType],
[

View File

@@ -37,6 +37,7 @@ class HubspotSource(BaseSource[HubspotSourceConfig | HubspotSourceOldConfig], OA
return SourceConfig(
name=SchemaExternalDataSourceType.HUBSPOT,
caption="Select an existing Hubspot account to link to PostHog or create a new connection",
iconPath="/static/services/hubspot.png",
fields=cast(
list[FieldType],
[

View File

@@ -23,6 +23,7 @@ class KlaviyoSource(BaseSource[KlaviyoSourceConfig]):
name=SchemaExternalDataSourceType.KLAVIYO,
label="Klaviyo",
caption="",
iconPath="/static/services/klaviyo.png",
fields=cast(list[FieldType], []),
unreleasedSource=True,
)

View File

@@ -37,6 +37,7 @@ class LinkedInAdsSource(BaseSource[LinkedinAdsSourceConfig]):
label="LinkedIn Ads",
caption="Ensure you have granted PostHog access to your LinkedIn Ads account, learn how to do this in [the documentation](https://posthog.com/docs/cdp/sources/linkedin-ads).",
betaSource=True,
iconPath="/static/services/linkedin.png",
fields=cast(
list[FieldType],
[

View File

@@ -23,6 +23,7 @@ class MailchimpSource(BaseSource[MailchimpSourceConfig]):
name=SchemaExternalDataSourceType.MAILCHIMP,
label="Mailchimp",
caption="",
iconPath="/static/services/mailchimp.png",
fields=cast(list[FieldType], []),
unreleasedSource=True,
)

View File

@@ -23,6 +23,7 @@ class MailJetSource(BaseSource[MailjetSourceConfig]):
name=SchemaExternalDataSourceType.MAILJET,
label="Mailjet",
caption="",
iconPath="/static/services/mailjet.png",
fields=cast(list[FieldType], []),
unreleasedSource=True,
)

View File

@@ -54,6 +54,7 @@ class MetaAdsSource(BaseSource[MetaAdsSourceConfig]):
name=SchemaExternalDataSourceType.META_ADS,
label="Meta Ads",
caption="Ensure you have granted PostHog access to your Meta Ads account, learn how to do this in the [documentation](https://posthog.com/docs/cdp/sources/meta-ads).",
iconPath="/static/services/meta-ads.png",
fields=cast(
list[FieldType],
[

View File

@@ -101,6 +101,7 @@ class MongoDBSource(BaseSource[MongoDBSourceConfig], ValidateDatabaseHostMixin):
label="MongoDB",
caption="Enter your MongoDB connection string to automatically pull your MongoDB data into the PostHog Data warehouse.",
betaSource=True,
iconPath="/static/services/Mongodb.svg",
fields=cast(
list[FieldType],
[

View File

@@ -43,6 +43,7 @@ class MSSQLSource(BaseSource[MSSQLSourceConfig], SSHTunnelMixin, ValidateDatabas
name=SchemaExternalDataSourceType.MSSQL,
label="Microsoft SQL Server",
caption="Enter your Microsoft SQL Server/Azure SQL Server credentials to automatically pull your SQL data into the PostHog Data warehouse.",
iconPath="/static/services/sql-azure.png",
fields=cast(
list[FieldType],
[

View File

@@ -39,6 +39,7 @@ class MySQLSource(BaseSource[MySQLSourceConfig], SSHTunnelMixin, ValidateDatabas
return SourceConfig(
name=SchemaExternalDataSourceType.MY_SQL,
caption="Enter your MySQL/MariaDB credentials to automatically pull your MySQL data into the PostHog Data warehouse.",
iconPath="/static/services/mysql.png",
fields=cast(
list[FieldType],
[

View File

@@ -23,6 +23,7 @@ class PolarSource(BaseSource[PolarSourceConfig]):
name=SchemaExternalDataSourceType.POLAR,
label="Polar",
caption="",
iconPath="/static/services/polar.png",
fields=cast(list[FieldType], []),
unreleasedSource=True,
)

View File

@@ -46,6 +46,7 @@ class PostgresSource(BaseSource[PostgresSourceConfig], SSHTunnelMixin, ValidateD
return SourceConfig(
name=SchemaExternalDataSourceType.POSTGRES,
caption="Enter your Postgres credentials to automatically pull your Postgres data into the PostHog Data warehouse",
iconPath="/static/services/postgres.png",
fields=cast(
list[FieldType],
[

View File

@@ -31,6 +31,7 @@ class RedditAdsSource(BaseSource[RedditAdsSourceConfig], OAuthMixin):
return SourceConfig(
name=SchemaExternalDataSourceType.REDDIT_ADS,
label="Reddit Ads",
iconPath="/static/services/reddit.png",
caption="Collect campaign data, ad performance, and advertising metrics from Reddit Ads. Ensure you have granted PostHog access to your Reddit Ads account, learn how to do this in [the documentation](https://posthog.com/docs/cdp/sources/reddit-ads).",
betaSource=True,
fields=cast(

View File

@@ -23,6 +23,7 @@ class RedshiftSource(BaseSource[RedshiftSourceConfig]):
name=SchemaExternalDataSourceType.REDSHIFT,
label="Redshift",
caption="",
iconPath="/static/services/redshift.png",
fields=cast(list[FieldType], []),
unreleasedSource=True,
)

View File

@@ -23,6 +23,7 @@ class RevenueCatSource(BaseSource[RevenueCatSourceConfig]):
name=SchemaExternalDataSourceType.REVENUE_CAT,
label="RevenueCat",
caption="",
iconPath="/static/services/revenuecat.png",
fields=cast(list[FieldType], []),
unreleasedSource=True,
)

View File

@@ -43,6 +43,7 @@ class SalesforceSource(BaseSource[SalesforceSourceConfig], OAuthMixin):
return SourceConfig(
name=SchemaExternalDataSourceType.SALESFORCE,
caption="Select an existing Salesforce account to link to PostHog or create a new connection",
iconPath="/static/services/salesforce.png",
fields=cast(
list[FieldType],
[

View File

@@ -44,6 +44,7 @@ class SnowflakeSource(BaseSource[SnowflakeSourceConfig]):
return SourceConfig(
name=SchemaExternalDataSourceType.SNOWFLAKE,
caption="Enter your Snowflake credentials to automatically pull your Snowflake data into the PostHog Data warehouse.",
iconPath="/static/services/snowflake.png",
fields=cast(
list[FieldType],
[

View File

@@ -43,6 +43,7 @@ Currently, **read permissions are required** for the following resources:
- Under the **Core** resource type, select *read* for **Balance transaction sources**, **Charges**, **Customer**, **Product**, **Disputes**, and **Payouts**
- Under the **Billing** resource type, select *read* for **Invoice**, **Price**, **Subscription**, and **Credit notes**
- Under the **Connected** resource type, select *read* for the **entire resource**""",
iconPath="/static/services/stripe.png",
fields=cast(
list[FieldType],
[

View File

@@ -56,6 +56,7 @@ class TemporalIOSource(BaseSource[TemporalIOSourceConfig]):
name=SchemaExternalDataSourceType.TEMPORAL_IO,
label="Temporal.io",
caption="",
iconPath="/static/services/temporal.png",
fields=cast(
list[FieldType],
[

View File

@@ -85,6 +85,7 @@ class VitallySource(BaseSource[VitallySourceConfig]):
return SourceConfig(
name=SchemaExternalDataSourceType.VITALLY,
caption="",
iconPath="/static/services/vitally.png",
fields=cast(
list[FieldType],
[

View File

@@ -56,6 +56,7 @@ class ZendeskSource(BaseSource[ZendeskSourceConfig]):
return SourceConfig(
name=SchemaExternalDataSourceType.ZENDESK,
caption="Enter your Zendesk API key to automatically pull your Zendesk support data into the PostHog Data warehouse.",
iconPath="/static/services/zendesk.png",
fields=cast(
list[FieldType],
[

View File

@@ -32,6 +32,19 @@ const meta: Meta = {
},
]
},
'/api/environments/:team_id/external_data_sources/wizard': () => {
return [
200,
{
Stripe: {
name: 'Stripe',
iconPath: '/static/services/stripe.png',
fields: [],
caption: '',
},
},
]
},
},
}),
],

View File

@@ -39,6 +39,16 @@ const meta: Meta = {
},
]
},
'/api/environments/:team_id/external_data_sources/wizard': () => {
return [
200,
{
Stripe: {
iconPath: '/static/services/stripe.png',
},
},
]
},
},
post: { '/api/environments/:team_id/query': () => [200, DatabaseSchemaQuery] },
}),