chore(plux): fixed product icons (#37718)

This commit is contained in:
Adam Leith
2025-09-08 16:47:35 +01:00
committed by GitHub
parent 61a50ac951
commit fd7fc7938c
72 changed files with 476 additions and 302 deletions

View File

@@ -9,6 +9,7 @@ import { fileSystemTypes } from '~/products'
import { FileSystemType } from '~/types'
import { panelLayoutLogic } from '../panelLayoutLogic'
import { iconForType } from './defaultTree'
import { projectTreeLogic } from './projectTreeLogic'
const missingProductTypes: { value: string; label: string; icon?: React.ReactNode; flag?: string }[] = [
@@ -24,7 +25,7 @@ const productTypesMapped = [
([key, value]): { value: string; label: string; icon: React.ReactNode; flag?: string } => ({
value: value.filterKey || key,
label: value.name,
icon: value.icon,
icon: iconForType(value.iconType),
flag: value.flag,
})
),

View File

@@ -5,29 +5,36 @@ import {
IconApp,
IconApps,
IconBook,
IconChevronRight,
IconBug,
IconCursor,
IconDashboard,
IconDatabase,
IconExternal,
IconFlask,
IconFunnels,
IconGraph,
IconHandMoney,
IconHogQL,
IconLifecycle,
IconLive,
IconMessage,
IconNotebook,
IconNotification,
IconPeople,
IconPieChart,
IconPiggyBank,
IconPlug,
IconRetention,
IconRewindPlay,
IconRocket,
IconServer,
IconStickiness,
IconToggle,
IconTrends,
IconUserPaths,
IconWarning,
} from '@posthog/icons'
import { FEATURE_FLAGS } from 'lib/constants'
import { IconCohort } from 'lib/lemon-ui/icons'
import { urls } from 'scenes/urls'
import {
@@ -41,110 +48,160 @@ import { FileSystemIconType, FileSystemImport } from '~/queries/schema/schema-ge
import { FileSystemIconColor, PipelineStage, PipelineTab } from '~/types'
const iconTypes: Record<FileSystemIconType, { icon: JSX.Element; iconColor?: FileSystemIconColor }> = {
ai: {
icon: <IconAI />,
iconColor: ['var(--color-product-max-ai-light)'],
dashboard: {
icon: <IconDashboard />,
iconColor: ['var(--color-product-dashboards-light)'],
},
cursor: {
icon: <IconCursor />,
llm_analytics: {
icon: <IconAI />,
iconColor: ['var(--color-product-llm-analytics-light)'],
},
product_analytics: {
icon: <IconGraph />,
iconColor: ['var(--color-product-product-analytics-light)'],
},
revenue_analytics: {
icon: <IconPiggyBank />,
iconColor: ['var(--color-product-revenue-analytics-light)', 'var(--color-product-revenue-analytics-dark)'],
},
web_analytics: {
icon: <IconPieChart />,
iconColor: ['var(--color-product-web-analytics-light)', 'var(--color-product-web-analytics-dark)'],
},
sql_editor: {
icon: <IconServer />,
iconColor: ['var(--color-product-data-warehouse-light)'],
},
error_tracking: {
icon: <IconWarning />,
iconColor: ['var(--color-product-error-tracking-light)', 'var(--color-product-error-tracking-dark)'],
},
heatmap: {
icon: <IconApp />,
iconColor: ['var(--color-product-heatmaps-light)', 'var(--color-product-heatmaps-dark)'],
},
database: {
icon: <IconDatabase />,
iconColor: ['var(--color-product-data-warehouse-light)'],
session_replay: {
icon: <IconRewindPlay />,
iconColor: ['var(--color-product-session-replay-light)', 'var(--color-product-session-replay-dark)'],
},
definitions: {
icon: <IconApps />,
survey: {
icon: <IconMessage />,
iconColor: ['var(--color-product-surveys-light)'],
},
folder: {
icon: <IconChevronRight />,
user_interview: {
icon: <IconApp />,
iconColor: ['var(--color-product-user-interviews-light)'],
},
handMoney: {
icon: <IconHandMoney />,
task: {
icon: <IconBug />,
},
live: {
logs: {
icon: <IconLive />,
iconColor: ['var(--color-product-logs-light)'],
},
notification: {
icon: <IconNotification />,
iconColor: ['var(--product-notification-light)'],
early_access_feature: {
icon: <IconRocket />,
iconColor: [
'var(--color-product-early-access-features-light)',
'var(--color-product-early-access-features-dark)',
],
},
pieChart: {
icon: <IconPieChart />,
iconColor: ['var(--color-product-web-analytics-light)', 'var(--color-product-web-analytics-dark)'],
experiment: {
icon: <IconFlask />,
iconColor: ['var(--color-product-experiments-light)'],
},
piggyBank: {
icon: <IconPiggyBank />,
iconColor: ['var(--color-product-revenue-analytics-light)', 'var(--color-product-revenue-analytics-dark)'],
feature_flag: {
icon: <IconToggle />,
iconColor: ['var(--color-product-feature-flags-light)'],
},
plug: {
data_pipeline: {
icon: <IconPlug />,
iconColor: ['var(--color-product-data-pipeline-light)'],
},
sql: {
icon: <IconServer />,
data_warehouse: {
icon: <IconDatabase />,
iconColor: ['var(--color-product-data-warehouse-light)'],
},
warning: {
link: {
icon: <IconExternal />,
iconColor: ['var(--color-product-links-light)', 'var(--color-product-links-dark)'],
},
messaging: {
icon: <IconMessage />,
iconColor: ['var(--color-product-messaging-light)', 'var(--color-product-messaging-dark)'],
},
notebook: {
icon: <IconNotebook />,
},
action: {
icon: <IconCursor />,
},
comment: {
icon: <IconNotification />,
},
annotation: {
icon: <IconNotification />,
},
event_definition: {
icon: <IconApps />,
},
property_definition: {
icon: <IconApps />,
},
ingestion_warning: {
icon: <IconWarning />,
},
errorTracking: {
icon: <IconWarning />,
iconColor: ['var(--color-product-error-tracking-light)', 'var(--color-product-error-tracking-dark)'],
person: {
icon: <IconPeople />,
},
insightFunnel: {
cohort: {
icon: <IconPeople />,
},
group: {
icon: <IconPeople />,
},
insight_funnel: {
icon: <IconFunnels />,
iconColor: ['var(--color-insight-funnel-light)'],
},
insightTrends: {
insight_trend: {
icon: <IconTrends />,
iconColor: ['var(--color-insight-trends-light)'],
},
insightRetention: {
insight_retention: {
icon: <IconRetention />,
iconColor: ['var(--color-insight-retention-light)'],
},
insightUserPaths: {
insight_user_path: {
icon: <IconUserPaths />,
iconColor: ['var(--color-insight-user-paths-light)', 'var(--color-user-paths-dark)'],
},
insightLifecycle: {
insight_lifecycle: {
icon: <IconLifecycle />,
iconColor: ['var(--color-insight-lifecycle-light)'],
},
insightStickiness: {
insight_stickiness: {
icon: <IconStickiness />,
iconColor: ['var(--color-insight-stickiness-light)'],
},
insightHogQL: {
insight_hogql: {
icon: <IconHogQL />,
iconColor: ['var(--color-insight-sql-light)'],
},
cohort: {
icon: <IconCohort />,
},
insight: {
icon: <IconGraph />,
iconColor: ['var(--color-product-product-analytics-light)'],
},
}
const getIconColor = (type?: string, colorOverride?: FileSystemIconColor): FileSystemIconColor => {
// Get the official icon color
const iconTypeColor = type && iconTypes[type as keyof typeof iconTypes]?.iconColor
// fallback: Get the file system color
// Manifest color takes precedence
const fileSystemColor = (fileSystemTypes as unknown as Record<string, { iconColor?: FileSystemIconColor }>)[
type as keyof typeof fileSystemTypes
]?.iconColor
// Fallback to iconTypes if no manifest color is provided
const iconTypeColor = type && iconTypes[type as keyof typeof iconTypes]?.iconColor
// If we have a color override, use it
// Otherwise, use the official icon color, then the file system color and finally if all else is undefined use the inherited default color
const color = colorOverride ?? iconTypeColor ?? fileSystemColor ?? ['currentColor', 'currentColor']
// Otherwise, use the above colors in order of precedence
const color = colorOverride ?? fileSystemColor ?? iconTypeColor ?? ['currentColor', 'currentColor']
return color.length === 1 ? [color[0], color[0]] : (color as FileSystemIconColor)
}
@@ -177,7 +234,7 @@ export const ProductIconWrapper = ({ type, children, colorOverride }: ProductIco
)
}
export function iconForType(type?: string, colorOverride?: FileSystemIconColor): JSX.Element {
export function iconForType(type?: FileSystemIconType, colorOverride?: FileSystemIconColor): JSX.Element {
if (!type) {
return (
<ProductIconWrapper type={type} colorOverride={colorOverride}>
@@ -186,12 +243,12 @@ export function iconForType(type?: string, colorOverride?: FileSystemIconColor):
)
}
// Then check fileSystemTypes
if (type in fileSystemTypes && fileSystemTypes[type as keyof typeof fileSystemTypes]?.icon) {
const IconElement = fileSystemTypes[type as keyof typeof fileSystemTypes].icon
// Check if the type exists in fileSystemTypes manifest and resolve iconType from there
const fileSystemType = fileSystemTypes[type as keyof typeof fileSystemTypes]
if (fileSystemType?.iconType && fileSystemType.iconType in iconTypes) {
return (
<ProductIconWrapper type={type} colorOverride={colorOverride}>
{IconElement}
<ProductIconWrapper type={fileSystemType.iconType} colorOverride={colorOverride}>
{iconTypes[fileSystemType.iconType as keyof typeof iconTypes].icon}
</ProductIconWrapper>
)
}
@@ -228,21 +285,29 @@ export const getDefaultTreeNew = (): FileSystemImport[] =>
path: `Data/Source`,
type: 'hog_function/source',
href: urls.pipelineNodeNew(PipelineStage.Source),
icon: <IconPlug />,
iconColor: ['var(--color-product-data-pipeline-light)'] as FileSystemIconColor,
},
{
path: `Data/Destination`,
type: 'hog_function/destination',
href: urls.pipelineNodeNew(PipelineStage.Destination),
icon: <IconPlug />,
iconColor: ['var(--color-product-data-pipeline-light)'] as FileSystemIconColor,
},
{
path: `Data/Transformation`,
type: 'hog_function/transformation',
href: urls.pipelineNodeNew(PipelineStage.Transformation),
icon: <IconPlug />,
iconColor: ['var(--color-product-data-pipeline-light)'] as FileSystemIconColor,
},
{
path: `Data/Site app`,
type: 'hog_function/site_app',
href: urls.pipelineNodeNew(PipelineStage.SiteApp),
icon: <IconPlug />,
iconColor: ['var(--color-product-data-pipeline-light)'] as FileSystemIconColor,
},
].sort((a, b) => a.path.localeCompare(b.path, undefined, { sensitivity: 'accent' }))
@@ -251,31 +316,31 @@ export const getDefaultTreeData = (): FileSystemImport[] => [
{
path: 'Event definitions',
category: 'Definitions',
iconType: 'definitions',
iconType: 'event_definition',
href: urls.eventDefinitions(),
},
{
path: 'Property definitions',
category: 'Definitions',
iconType: 'definitions',
iconType: 'property_definition',
href: urls.propertyDefinitions(),
},
{
path: 'Annotations',
category: 'Metadata',
iconType: 'notification',
iconType: 'annotation',
href: urls.annotations(),
},
{
path: 'Comments',
category: 'Metadata',
iconType: 'notification',
iconType: 'comment',
href: urls.comments(),
},
{
path: 'Ingestion warnings',
category: 'Pipeline',
iconType: 'warning',
iconType: 'ingestion_warning',
href: urls.ingestionWarnings(),
flag: FEATURE_FLAGS.INGESTION_WARNINGS_ENABLED,
},
@@ -283,21 +348,21 @@ export const getDefaultTreeData = (): FileSystemImport[] => [
path: `Sources`,
category: 'Pipeline',
type: 'hog_function/source',
iconType: 'plug',
iconType: 'data_pipeline',
href: urls.pipeline(PipelineTab.Sources),
} as FileSystemImport,
{
path: `Transformations`,
category: 'Pipeline',
type: 'hog_function/transformation',
iconType: 'plug',
iconType: 'data_pipeline',
href: urls.pipeline(PipelineTab.Transformations),
} as FileSystemImport,
{
path: `Destinations`,
category: 'Pipeline',
type: 'hog_function/destination',
iconType: 'plug',
iconType: 'data_pipeline',
href: urls.pipeline(PipelineTab.Destinations),
} as FileSystemImport,
]
@@ -309,31 +374,41 @@ export const getDefaultTreeProducts = (): FileSystemImport[] =>
path: 'Dashboards',
category: 'Analytics',
type: 'dashboard',
iconType: 'dashboard' as FileSystemIconType,
iconColor: ['var(--color-product-dashboards-light)'] as FileSystemIconColor,
href: urls.dashboards(),
},
{
path: 'Notebooks',
category: 'Tools',
type: 'notebook',
iconType: 'notebook' as FileSystemIconType,
href: urls.notebooks(),
},
{
path: `Data pipelines`,
category: 'Tools',
type: 'hog_function',
iconType: 'plug',
iconType: 'data_pipeline' as FileSystemIconType,
iconColor: ['var(--color-product-data-pipeline-light)'] as FileSystemIconColor,
href: urls.pipeline(),
} as FileSystemImport,
{
path: `SQL editor`,
category: 'Analytics',
type: 'sql',
iconType: 'sql_editor' as FileSystemIconType,
iconColor: ['var(--color-product-data-warehouse-light)'] as FileSystemIconColor,
href: urls.sqlEditor(),
} as FileSystemImport,
{
path: 'Heatmaps',
category: 'Behavior',
iconType: 'heatmap',
iconType: 'heatmap' as FileSystemIconType,
iconColor: [
'var(--color-product-heatmaps-light)',
'var(--color-product-heatmaps-dark)',
] as FileSystemIconColor,
href: urls.heatmaps(),
flag: FEATURE_FLAGS.HEATMAPS_UI,
tags: ['alpha'],
@@ -355,14 +430,14 @@ export const getDefaultTreePersons = (): FileSystemImport[] => [
{
path: 'Persons',
category: 'People',
iconType: 'cohort',
iconType: 'person' as FileSystemIconType,
href: urls.persons(),
visualOrder: 10,
},
{
path: 'Cohorts',
category: 'People',
type: 'cohort',
type: 'cohort' as FileSystemIconType,
href: urls.cohorts(),
visualOrder: 20,
},

View File

@@ -34,7 +34,7 @@ import {
} from '~/layout/panel-layout/ProjectTree/utils'
import { FEATURE_FLAGS } from '~/lib/constants'
import { groupsModel } from '~/models/groupsModel'
import { FileSystemEntry, FileSystemImport } from '~/queries/schema/schema-general'
import { FileSystemEntry, FileSystemIconType, FileSystemImport } from '~/queries/schema/schema-general'
import { UserBasicType } from '~/types'
import type { projectTreeDataLogicType } from './projectTreeDataLogicType'
@@ -571,7 +571,7 @@ export const projectTreeDataLogic = kea<projectTreeDataLogicType>([
{
path: 'Groups',
category: 'Groups',
iconType: 'cohort',
iconType: 'group',
href: urls.groups(0),
visualOrder: 30,
},
@@ -579,7 +579,7 @@ export const projectTreeDataLogic = kea<projectTreeDataLogicType>([
: Array.from(groupTypes.values()).map((groupType) => ({
path: capitalizeFirstLetter(aggregationLabel(groupType.group_type_index).plural),
category: 'Groups',
iconType: 'cohort',
iconType: 'group',
href: urls.groups(groupType.group_type_index),
visualOrder: 30 + groupType.group_type_index,
}))
@@ -594,7 +594,7 @@ export const projectTreeDataLogic = kea<projectTreeDataLogicType>([
path: shortcut.path,
type: shortcut.type,
category: 'Saved Views',
iconType: 'database' as const,
iconType: 'group' as FileSystemIconType,
href: shortcut.href || '',
visualOrder: 100,
shortcut: true,

View File

@@ -5,7 +5,7 @@ import { TreeDataItem } from 'lib/lemon-ui/LemonTree/LemonTree'
import { SearchHighlightMultiple } from '~/layout/navigation-3000/components/SearchHighlight'
import { RecentResults, SearchResults } from '~/layout/panel-layout/ProjectTree/projectTreeLogic'
import { FileSystemEntry, FileSystemImport } from '~/queries/schema/schema-general'
import { FileSystemEntry, FileSystemIconType, FileSystemImport } from '~/queries/schema/schema-general'
import { UserBasicType } from '~/types'
import { iconForType } from './defaultTree'
@@ -101,7 +101,10 @@ export function convertFileSystemEntryToTreeDataItem({
const displayName = <SearchHighlightMultiple string={itemName} substring={searchTerm ?? ''} />
const user: UserBasicType | undefined = item.meta?.created_by ? users?.[item.meta.created_by] : undefined
const icon = iconForType('iconType' in item ? item.iconType : item.type)
const icon = iconForType(
('iconType' in item ? item.iconType : undefined) || (item.type as FileSystemIconType),
'iconColor' in item ? item.iconColor : undefined
)
const node: TreeDataItem = {
id: nodeId,
name: itemName,

View File

@@ -11,20 +11,16 @@ import { TextareaPrimitive } from 'lib/ui/TextareaPrimitive/TextareaPrimitive'
import { WrappingLoadingSkeleton } from 'lib/ui/WrappingLoadingSkeleton/WrappingLoadingSkeleton'
import { cn } from 'lib/utils/css-classes'
import { fileSystemTypes } from '~/products'
import { FileSystemIconType } from '~/queries/schema/schema-general'
import { FileSystemIconColor } from '~/types'
import '../../panel-layout/ProjectTree/defaultTree'
import { ProductIconWrapper } from '../../panel-layout/ProjectTree/defaultTree'
import { iconForType } from '../../panel-layout/ProjectTree/defaultTree'
import { ProductIconWrapper, iconForType } from '../../panel-layout/ProjectTree/defaultTree'
type ResourceType = {
to?: string
tooltip?: string
/** example: 'action' */
type: keyof typeof fileSystemTypes | string
/** example: 'actions' */
typePlural: string
type: FileSystemIconType | string
/** If your resource type matches a product in fileSystemTypes, you can use this to override the icon */
forceIcon?: JSX.Element
/** If your resource type matches a product in fileSystemTypes, you can use this to override the product's icon color */
@@ -85,7 +81,7 @@ export function SceneTitleSection({
{resourceType.forceIcon}
</ProductIconWrapper>
) : (
iconForType(resourceType.type)
iconForType(resourceType.type ? (resourceType.type as FileSystemIconType) : undefined)
)
return (
<div className="@container/scene-title-section">
@@ -114,14 +110,6 @@ export function SceneTitleSection({
</div>
{description !== null && (description || canEdit) && (
<div className="flex gap-2 [&_svg]:size-6 items-center">
{/* <span
className={buttonPrimitiveVariants({
size: 'base',
iconOnly: true,
inert: true,
})}
aria-hidden
/> */}
<SceneDescription
description={description}
markdown={markdown}
@@ -139,7 +127,7 @@ export function SceneTitleSection({
<Link
to={`${docsURL}?utm_medium=in-product&utm_campaign=scene-title-section-docs-link`}
buttonProps={{ variant: 'panel', className: 'rounded-sm' }}
tooltip={`View docs for ${resourceType.typePlural}`}
tooltip={`View docs for ${resourceType.type}`}
className="hidden @lg:block"
>
<IconDocument /> Read the docs
@@ -147,7 +135,7 @@ export function SceneTitleSection({
<Link
to={`${docsURL}?utm_medium=in-product&utm_campaign=scene-title-section-docs-link`}
buttonProps={{ variant: 'panel', className: 'rounded-sm', size: 'lg' }}
tooltip={`View docs for ${resourceType.typePlural}`}
tooltip={`View docs for ${resourceType.type}`}
className="@lg:hidden"
>
<IconDocument />

View File

@@ -10,7 +10,7 @@ import { urls } from 'scenes/urls'
import { getDefaultTreeProducts, iconForType } from '~/layout/panel-layout/ProjectTree/defaultTree'
import { groupsModel } from '~/models/groupsModel'
import { FileSystemImport } from '~/queries/schema/schema-general'
import { FileSystemIconType, FileSystemImport } from '~/queries/schema/schema-general'
import { Group, InsightShortId, PersonType, SearchResponse, SearchableEntity } from '~/types'
import { commandBarLogic } from './commandBarLogic'
@@ -57,7 +57,9 @@ function rankProductTreeItems(treeItems: FileSystemImport[], query: string): Tre
result_id: item.href || item.path,
extra_fields: {
...item,
icon: item.iconType ? iconForType(item.iconType) : iconForType(item.type),
icon: item.iconType
? iconForType(item.iconType as FileSystemIconType)
: iconForType(item.type as FileSystemIconType),
description: `Category: ${item.category}`,
},
rank,

View File

@@ -1,7 +1,7 @@
import { IconBuilding, IconPerson, IconPiggyBank } from '@posthog/icons'
import { IconBuilding, IconPeople, IconPerson, IconPiggyBank } from '@posthog/icons'
import { Tooltip } from 'lib/lemon-ui/Tooltip'
import { IconCohort, IconUnverifiedEvent } from 'lib/lemon-ui/icons'
import { IconUnverifiedEvent } from 'lib/lemon-ui/icons'
import { PropertyFilterType } from '~/types'
@@ -22,7 +22,7 @@ export function PropertyFilterIcon({ type }: { type?: PropertyFilterType }): JSX
case 'cohort':
return (
<Tooltip title="Cohort filter">
<IconCohort />
<IconPeople />
</Tooltip>
)
case 'group':

View File

@@ -12209,32 +12209,65 @@
"required": ["id", "path"],
"type": "object"
},
"FileSystemIconColor": {
"anyOf": [
{
"items": {
"type": "string"
},
"maxItems": 1,
"minItems": 1,
"type": "array"
},
{
"items": {
"type": "string"
},
"maxItems": 2,
"minItems": 2,
"type": "array"
}
]
},
"FileSystemIconType": {
"enum": [
"plug",
"cohort",
"insight",
"definitions",
"warning",
"errorTracking",
"ai",
"cursor",
"dashboard",
"llm_analytics",
"product_analytics",
"revenue_analytics",
"sql_editor",
"web_analytics",
"error_tracking",
"heatmap",
"database",
"folder",
"handMoney",
"live",
"notification",
"pieChart",
"piggyBank",
"sql",
"insightFunnel",
"insightTrends",
"insightRetention",
"insightUserPaths",
"insightLifecycle",
"insightStickiness",
"insightHogQL"
"session_replay",
"survey",
"user_interview",
"early_access_feature",
"experiment",
"feature_flag",
"data_pipeline",
"data_warehouse",
"task",
"link",
"logs",
"messaging",
"notebook",
"action",
"comment",
"annotation",
"event_definition",
"property_definition",
"ingestion_warning",
"person",
"cohort",
"group",
"insight_funnel",
"insight_trend",
"insight_retention",
"insight_user_path",
"insight_lifecycle",
"insight_stickiness",
"insight_hogql"
],
"type": "string"
},
@@ -12260,6 +12293,10 @@
"description": "Object's URL",
"type": "string"
},
"iconColor": {
"$ref": "#/definitions/FileSystemIconColor",
"description": "Color of the icon"
},
"iconType": {
"$ref": "#/definitions/FileSystemIconType"
},

View File

@@ -20,6 +20,7 @@ import {
ExperimentHoldoutType,
ExperimentMetricGoal,
ExperimentMetricMathType,
FileSystemIconColor,
FilterLogicalOperator,
FilterType,
FunnelConversionWindowTimeUnit,
@@ -2354,30 +2355,43 @@ export interface FileSystemEntry {
}
export type FileSystemIconType =
| 'plug'
| 'cohort'
| 'insight'
| 'definitions'
| 'warning'
| 'errorTracking'
| 'ai'
| 'cursor'
| 'dashboard'
| 'llm_analytics'
| 'product_analytics'
| 'revenue_analytics'
| 'sql_editor'
| 'web_analytics'
| 'error_tracking'
| 'heatmap'
| 'database'
| 'folder'
| 'handMoney'
| 'live'
| 'notification'
| 'pieChart'
| 'piggyBank'
| 'sql'
| 'insightFunnel'
| 'insightTrends'
| 'insightRetention'
| 'insightUserPaths'
| 'insightLifecycle'
| 'insightStickiness'
| 'insightHogQL'
| 'session_replay'
| 'survey'
| 'user_interview'
| 'early_access_feature'
| 'experiment'
| 'feature_flag'
| 'data_pipeline'
| 'data_warehouse'
| 'task'
| 'link'
| 'logs'
| 'messaging'
| 'notebook'
| 'action'
| 'comment'
| 'annotation'
| 'event_definition'
| 'property_definition'
| 'ingestion_warning'
| 'person'
| 'cohort'
| 'group'
| 'insight_funnel'
| 'insight_trend'
| 'insight_retention'
| 'insight_user_path'
| 'insight_lifecycle'
| 'insight_stickiness'
| 'insight_hogql'
export interface FileSystemImport extends Omit<FileSystemEntry, 'id'> {
id?: string
iconType?: FileSystemIconType
@@ -2390,6 +2404,8 @@ export interface FileSystemImport extends Omit<FileSystemEntry, 'id'> {
protocol?: string
/** Category label to place this under */
category?: string
/** Color of the icon */
iconColor?: FileSystemIconColor
}
export interface PersistedFolder {

View File

@@ -48,7 +48,6 @@ export function EventsScene({ tabId }: { tabId?: string } = {}): JSX.Element {
description="A catalog of all user interactions with your app or website."
resourceType={{
type: RESOURCE_TYPE,
typePlural: 'events',
forceIcon: <IconApps />,
}}
/>

View File

@@ -105,7 +105,6 @@ export function LiveEventsTable(): JSX.Element {
description="Real-time events from your app or website."
resourceType={{
type: 'live events',
typePlural: 'live events',
forceIcon: <IconLive />,
}}
/>

View File

@@ -154,7 +154,6 @@ export function Annotations(): JSX.Element {
description="Annotations allow you to mark when certain changes happened so you can easily see how they impacted your metrics."
resourceType={{
type: 'annotation',
typePlural: 'annotations',
forceIcon: <IconNotification />,
}}
/>

View File

@@ -224,8 +224,6 @@ export function CohortEdit({ id }: CohortLogicProps): JSX.Element {
resourceType={{
to: urls.cohorts(),
type: RESOURCE_TYPE,
typePlural: 'cohorts',
tooltip: 'Go to all cohorts',
}}
isLoading={cohortLoading}
onNameChange={(value) => {

View File

@@ -173,7 +173,6 @@ export function Cohorts(): JSX.Element {
description="A catalog of identified persons and your created cohorts."
resourceType={{
type: RESOURCE_TYPE,
typePlural: 'cohorts',
}}
docsURL="https://posthog.com/docs/data/cohorts"
/>

View File

@@ -643,7 +643,6 @@ export function DashboardHeader(): JSX.Element | null {
description={dashboard?.description}
resourceType={{
type: 'dashboard',
typePlural: 'dashboards',
}}
onNameChange={(value) => updateDashboard({ id: dashboard?.id, name: value, allowUndo: true })}
onDescriptionChange={(value) =>

View File

@@ -76,7 +76,6 @@ export function Dashboards(): JSX.Element {
description="Create and manage your dashboards"
resourceType={{
type: 'dashboard',
typePlural: 'dashboards',
}}
/>
<SceneDivider />

View File

@@ -1,7 +1,7 @@
import { useActions, useValues } from 'kea'
import { useEffect } from 'react'
import { IconNotification, IconTrash } from '@posthog/icons'
import { IconTrash } from '@posthog/icons'
import { LemonButton, LemonInput, LemonSelect } from '@posthog/lemon-ui'
import { MemberSelect } from 'lib/components/MemberSelect'
@@ -132,8 +132,6 @@ export function Comments(): JSX.Element {
description="Comments allow you to provide context and discussions on various elements in PostHog."
resourceType={{
type: 'comment',
typePlural: 'comments',
forceIcon: <IconNotification />,
}}
/>
<SceneDivider />

View File

@@ -135,7 +135,6 @@ export function EventDefinitionsTable(): JSX.Element {
description="Event definitions are a way to define events that can be used in your app or website."
resourceType={{
type: 'event',
typePlural: 'events',
forceIcon: <IconApps />,
}}
/>

View File

@@ -84,7 +84,6 @@ export function PropertyDefinitionsTable(): JSX.Element {
description="Properties are additional fields you can configure to be sent along with an event capture."
resourceType={{
type: 'property',
typePlural: 'properties',
forceIcon: <IconApps />,
}}
/>

View File

@@ -59,7 +59,6 @@ const ExperimentFormFields = (): JSX.Element => {
description={null}
resourceType={{
type: 'experiment',
typePlural: 'experiments',
}}
canEdit
onNameChange={(name) => {

View File

@@ -118,7 +118,6 @@ export function Info(): JSX.Element {
description={null}
resourceType={{
type: 'experiment',
typePlural: 'experiments',
}}
isLoading={experimentLoading}
onNameChange={(name) => updateExperiment({ name })}

View File

@@ -424,7 +424,6 @@ export function Experiments(): JSX.Element {
docsURL="https://posthog.com/docs/experiments/installation?utm_medium=in-product&utm_campaign=new-experiment"
resourceType={{
type: 'experiment',
typePlural: 'experiments',
}}
/>
<SceneDivider />

View File

@@ -757,7 +757,6 @@ export function FeatureFlag({ id }: FeatureFlagLogicProps): JSX.Element {
description={featureFlag.name}
resourceType={{
type: 'feature_flag',
typePlural: 'Feature flags',
}}
/>
<SceneDivider />

View File

@@ -587,7 +587,6 @@ export function FeatureFlags(): JSX.Element {
description="Use feature flags to safely deploy and roll back new features in an easy-to-manage way. Roll variants out to certain groups, a percentage of users, or everyone all at once."
resourceType={{
type: 'feature_flag',
typePlural: 'Feature flags',
}}
/>
<SceneDivider />

View File

@@ -55,7 +55,6 @@ export function Groups({ groupTypeIndex }: { groupTypeIndex: GroupTypeIndex }):
description="Associate events with a group or entity - such as a company, community, or project. Analyze these events as if they were sent by that entity itself. Great for B2B, marketplaces, and more."
resourceType={{
type: groupTypeName,
typePlural: groupTypeNamePlural,
forceIcon: <IconPeople />,
}}
/>
@@ -95,7 +94,6 @@ export function Groups({ groupTypeIndex }: { groupTypeIndex: GroupTypeIndex }):
description={`A catalog of all ${groupTypeNamePlural} for this project`}
resourceType={{
type: groupTypeName,
typePlural: groupTypeNamePlural,
forceIcon: <IconPeople />,
}}
/>

View File

@@ -310,7 +310,6 @@ export function HeatmapsBrowser(): JSX.Element {
description="See where users are clicking on your website."
resourceType={{
type: 'heatmap',
typePlural: 'Heatmaps',
}}
/>
<SceneDivider />

View File

@@ -856,8 +856,7 @@ export function InsightPageHeader({ insightLogicProps }: { insightLogicProps: In
name={defaultInsightName || ''}
description={insight?.description || ''}
resourceType={{
type: 'insight',
typePlural: 'insights',
type: 'product_analytics',
}}
onNameChange={(name) => {
setInsightMetadata({ name })

View File

@@ -1,20 +1,24 @@
import { actions, kea, key, listeners, path, props, reducers, selectors } from 'kea'
import { actions, connect, kea, key, listeners, path, props, reducers, selectors } from 'kea'
import { router } from 'kea-router'
import { IconDatabase, IconHogQL } from '@posthog/icons'
import { featureFlagLogic } from 'lib/logic/featureFlagLogic'
import {
ProductIconWrapper,
getDefaultTreeData,
getDefaultTreeNew,
getDefaultTreeProducts,
iconForType,
} from '~/layout/panel-layout/ProjectTree/defaultTree'
import { FileSystemIconType, FileSystemImport } from '~/queries/schema/schema-general'
import type { newTabSceneLogicType } from './newTabSceneLogicType'
export interface ItemsGridItem {
category: string
types: { name: string; icon?: JSX.Element; href?: string }[]
types: { name: string; icon?: JSX.Element; href?: string; flag?: string }[]
}
export interface ItemsGridItemSingle {
@@ -22,9 +26,26 @@ export interface ItemsGridItemSingle {
type: { name: string; icon?: JSX.Element; href?: string }
}
function getIconForFileSystemItem(fs: FileSystemImport): JSX.Element {
// If the item has a direct icon property, use it with color wrapper
if ('icon' in fs && fs.icon) {
return (
<ProductIconWrapper type={fs.type} colorOverride={fs.iconColor}>
{fs.icon}
</ProductIconWrapper>
)
}
// Fall back to iconForType for iconType or type
return iconForType('iconType' in fs ? fs.iconType : (fs.type as FileSystemIconType), fs.iconColor)
}
export const newTabSceneLogic = kea<newTabSceneLogicType>([
path(['scenes', 'new-tab', 'newTabSceneLogic']),
props({} as { tabId?: string }),
connect(() => ({
values: [featureFlagLogic, ['featureFlags']],
})),
key((props) => props.tabId || 'default'),
actions({
setSearch: (search: string) => ({ search }),
@@ -59,41 +80,53 @@ export const newTabSceneLogic = kea<newTabSceneLogicType>([
}),
selectors({
itemsGrid: [
() => [],
(): ItemsGridItem[] => {
(s) => [s.featureFlags],
(featureFlags): ItemsGridItem[] => {
const newInsightItems = getDefaultTreeNew()
.filter(({ path }) => path.startsWith('Insight/'))
.map((fs) => ({
href: fs.href,
name: fs.path.substring(8),
icon: iconForType(fs.iconType),
name: 'new ' + fs.path.substring(8),
icon: getIconForFileSystemItem(fs),
flag: fs.flag,
}))
.filter(({ flag }) => !flag || featureFlags[flag as keyof typeof featureFlags])
const newDataItems = getDefaultTreeNew()
.filter(({ path }) => path.startsWith('Data/'))
.map((fs) => ({
href: fs.href,
name: 'Data ' + fs.path.substring(5).toLowerCase(),
icon: iconForType(fs.iconType),
icon: getIconForFileSystemItem(fs),
flag: fs.flag,
}))
.filter(({ flag }) => !flag || featureFlags[flag as keyof typeof featureFlags])
const newOtherItems = getDefaultTreeNew()
.filter(({ path }) => !path.startsWith('Insight/') && !path.startsWith('Data/'))
.map((fs) => ({
href: fs.href,
name: fs.path,
icon: iconForType(fs.iconType),
name: 'new ' + fs.path,
icon: getIconForFileSystemItem(fs),
flag: fs.flag,
}))
.filter(({ flag }) => !flag || featureFlags[flag as keyof typeof featureFlags])
const products = getDefaultTreeProducts().map((fs) => ({
href: fs.href,
name: fs.path,
icon: iconForType(fs.iconType),
}))
const products = getDefaultTreeProducts()
.map((fs) => ({
href: fs.href,
name: fs.path,
icon: getIconForFileSystemItem(fs),
flag: fs.flag,
}))
.filter(({ flag }) => !flag || featureFlags[flag as keyof typeof featureFlags])
const data = getDefaultTreeData().map((fs) => ({
href: fs.href,
name: fs.path,
icon: iconForType(fs.iconType),
}))
const data = getDefaultTreeData()
.map((fs) => ({
href: fs.href,
name: fs.path,
icon: getIconForFileSystemItem(fs),
flag: fs.flag,
}))
.filter(({ flag }) => !flag || featureFlags[flag as keyof typeof featureFlags])
const queryTree: ItemsGridItem[] = [
{

View File

@@ -14,6 +14,7 @@ import {
IconLive,
IconLogomark,
IconNotebook,
IconPeople,
IconPerson,
IconPlaylist,
IconRewindPlay,
@@ -21,7 +22,6 @@ import {
import { Link } from '@posthog/lemon-ui'
import api from 'lib/api'
import { IconCohort } from 'lib/lemon-ui/icons'
import { urls } from 'scenes/urls'
import { openNotebook } from '~/models/notebooksModel'
@@ -112,7 +112,7 @@ const BACKLINK_MAP: BackLinkMapper[] = [
{
type: 'cohorts',
regex: new RegExp(urls.cohort('(.+)')),
icon: <IconCohort />,
icon: <IconPeople />,
getTitle: async (path: string) => {
const id = path.split('/')[2]
const cohort = await api.cohorts.get(Number(id))

View File

@@ -80,7 +80,6 @@ export function PersonsScene({ tabId }: { tabId?: string } = {}): JSX.Element {
description="A catalog of all the people behind your events"
resourceType={{
type: 'person',
typePlural: 'persons',
forceIcon: <IconPeople />,
}}
docsURL="https://posthog.com/docs/data/persons"

View File

@@ -795,8 +795,7 @@ export function SavedInsights(): JSX.Element {
name="Product analytics"
description="Track, analyze, and experiment with user behavior."
resourceType={{
type: 'insight',
typePlural: 'insights',
type: 'product_analytics',
}}
/>
<SceneDivider />

View File

@@ -156,7 +156,7 @@ export const sceneConfigurations: Record<Scene | string, SceneConfig> = {
[Scene.Login]: { onlyUnauthenticated: true },
[Scene.Max]: { projectBased: true, name: 'Max', layout: 'app-raw', hideProjectNotice: true },
[Scene.MoveToPostHogCloud]: { name: 'Move to PostHog Cloud', hideProjectNotice: true },
[Scene.NewTab]: { projectBased: true, name: 'New tab' },
[Scene.NewTab]: { projectBased: true, name: 'New tab', hideProjectNotice: true, layout: 'app-raw' },
[Scene.Notebook]: {
projectBased: true,
hideProjectNotice: true,

View File

@@ -208,8 +208,7 @@ export function SessionRecordingsPlaylistScene(): JSX.Element {
name={playlist.name || ''}
description={playlist.description || ''}
resourceType={{
type: 'session_recording_playlist',
typePlural: 'Session Recordings',
type: 'session_replay',
}}
onNameChange={(name) => {
updatePlaylist({ name })

View File

@@ -288,7 +288,6 @@ export default function SurveyEdit(): JSX.Element {
description={survey.description}
resourceType={{
type: 'survey',
typePlural: 'surveys',
}}
canEdit
onNameChange={(name) => setSurveyValue('name', name)}

View File

@@ -348,7 +348,6 @@ export function SurveyView({ id }: { id: string }): JSX.Element {
description={survey.description}
resourceType={{
type: 'survey',
typePlural: 'surveys',
}}
canEdit
onNameChange={(name) => updateSurvey({ id, name })}

View File

@@ -168,7 +168,6 @@ function Surveys(): JSX.Element {
description="Create surveys to collect feedback from your users"
resourceType={{
type: 'survey',
typePlural: 'surveys',
}}
docsURL="https://posthog.com/docs/surveys?utm_medium=in-product&utm_campaign=new-survey"
/>

View File

@@ -72,7 +72,6 @@ export function ToolbarLaunch(): JSX.Element {
description="PostHog toolbar launches PostHog right in your app or website."
resourceType={{
type: 'toolbar',
typePlural: 'toolbar',
forceIcon: <IconToolbar />,
}}
docsURL="https://posthog.com/docs/toolbar"

View File

@@ -20,7 +20,6 @@ export function WebAnalyticsScene(): JSX.Element {
description="Analyze your web analytics data to understand website performance and user behavior."
resourceType={{
type: 'web',
typePlural: 'Web analytics',
forceIcon: <IconPieChart />,
forceIconColorOverride: [
'var(--color-product-web-analytics-light)',

View File

@@ -24,7 +24,6 @@ export function MarketingAnalyticsSettings({ hideTitle = false }: { hideTitle?:
description={null}
resourceType={{
type: 'marketing',
typePlural: 'marketing',
forceIcon: <IconApps />,
}}
/>

View File

@@ -326,7 +326,7 @@
--color-product-error-tracking-dark: rgb(247 165 1);
--color-product-surveys-light: rgb(243 84 84);
--color-product-data-warehouse-light: rgb(133 103 255);
--color-product-max-ai-light: rgb(182 42 217);
--color-product-llm-analytics-light: rgb(182 42 217);
--color-product-links-light: rgb(143 7 255);
--color-product-revenue-analytics-light: rgb(52 175 102);
--color-product-revenue-analytics-dark: rgb(54 196 111);

View File

@@ -51,6 +51,7 @@ import type {
ExperimentMetric,
ExperimentTrendsQuery,
ExternalDataSourceType,
FileSystemIconType,
FileSystemImport,
HogQLQuery,
HogQLQueryModifiers,
@@ -5597,15 +5598,17 @@ export interface CoreMemory {
export type FileSystemIconColor = [string] | [string, string]
export interface FileSystemType {
icon?: JSX.Element
href?: (ref: string) => string
iconColor?: FileSystemIconColor
// Visual name of the product
name: string
// Flag to determine if the product is enabled
flag?: string
// Used to filter the tree items by product
filterKey?: string
// Icon type of the icon
iconType?: FileSystemIconType
// Color of the icon
iconColor?: FileSystemIconColor
}
export interface ProductManifest {

View File

@@ -326,8 +326,6 @@ export function ActionEdit({ action: loadedAction, id, actionLoading }: ActionEd
resourceType={{
to: urls.actions(),
type: RESOURCE_TYPE,
tooltip: 'Go to all actions',
typePlural: 'actions',
}}
markdown={true}
isLoading={actionLoading}

View File

@@ -24,7 +24,6 @@ export function Actions(): JSX.Element {
description="Combine several related events into one, which you can then analyze in insights and dashboards as if it were a single event."
resourceType={{
type: 'action',
typePlural: 'actions',
}}
docsURL="https://posthog.com/docs/data/actions"
/>

View File

@@ -1,8 +1,8 @@
import { IconCursor } from '@posthog/icons'
import { urls } from 'scenes/urls'
import { ActionType, ProductManifest } from '../../frontend/src/types'
import { FileSystemIconType } from '~/queries/schema/schema-general'
import { ActionType, FileSystemIconColor, ProductManifest } from '../../frontend/src/types'
export const manifest: ProductManifest = {
name: 'Actions',
@@ -47,9 +47,10 @@ export const manifest: ProductManifest = {
fileSystemTypes: {
action: {
name: 'Action',
icon: <IconCursor />,
href: (ref: string) => urls.action(ref),
filterKey: 'action',
iconType: 'action' as FileSystemIconType,
iconColor: ['var(--color-product-actions-light)'] as FileSystemIconColor,
},
},
treeItemsNew: [
@@ -57,14 +58,17 @@ export const manifest: ProductManifest = {
type: 'action',
path: 'Action',
href: urls.createAction(),
iconType: 'action' as FileSystemIconType,
iconColor: ['var(--color-product-actions-light)'] as FileSystemIconColor,
},
],
treeItemsMetadata: [
{
path: 'Actions',
category: 'Definitions',
iconType: 'cursor',
href: urls.actions(),
iconType: 'action' as FileSystemIconType,
iconColor: ['var(--color-product-actions-light)'] as FileSystemIconColor,
},
],
}

View File

@@ -1,8 +1,8 @@
import { IconPeople } from '@posthog/icons'
import { urls } from 'scenes/urls'
import { ProductManifest } from '../../frontend/src/types'
import { FileSystemIconType } from '~/queries/schema/schema-general'
import { FileSystemIconColor, ProductManifest } from '../../frontend/src/types'
export const manifest: ProductManifest = {
name: 'Cohorts',
@@ -13,9 +13,10 @@ export const manifest: ProductManifest = {
fileSystemTypes: {
cohort: {
name: 'Cohort',
icon: <IconPeople />,
iconType: 'cohort' as FileSystemIconType,
href: (ref: string) => urls.cohort(ref),
filterKey: 'cohort',
iconColor: ['var(--color-product-cohorts-light)'] as FileSystemIconColor,
},
},
treeItemsNew: [
@@ -23,6 +24,8 @@ export const manifest: ProductManifest = {
path: `Cohort`,
type: 'cohort',
href: urls.cohort('new'),
iconType: 'cohort' as FileSystemIconType,
iconColor: ['var(--color-product-cohorts-light)'] as FileSystemIconColor,
},
],
treeItemsProducts: [],

View File

@@ -1,10 +1,10 @@
import { combineUrl } from 'kea-router'
import { IconDashboard } from '@posthog/icons'
import { urls } from 'scenes/urls'
import { ProductManifest } from '../../frontend/src/types'
import { FileSystemIconType } from '~/queries/schema/schema-general'
import { FileSystemIconColor, ProductManifest } from '../../frontend/src/types'
export const manifest: ProductManifest = {
name: 'Dashboards',
@@ -24,7 +24,7 @@ export const manifest: ProductManifest = {
fileSystemTypes: {
dashboard: {
name: 'Dashboard',
icon: <IconDashboard />,
iconType: 'dashboard' as FileSystemIconType,
href: (ref: string) => urls.dashboard(ref),
iconColor: ['var(--color-product-dashboards-light)'],
filterKey: 'dashboard',
@@ -35,6 +35,8 @@ export const manifest: ProductManifest = {
path: `Dashboard`,
type: 'dashboard',
href: urls.dashboards() + '#newDashboard=modal',
iconType: 'dashboard' as FileSystemIconType,
iconColor: ['var(--color-product-dashboards-light)'] as FileSystemIconColor,
},
],
}

View File

@@ -1,7 +1,8 @@
import { FEATURE_FLAGS } from 'lib/constants'
import { urls } from 'scenes/urls'
import { ProductManifest } from '~/types'
import { FileSystemIconType } from '~/queries/schema/schema-general'
import { FileSystemIconColor, ProductManifest } from '~/types'
export const manifest: ProductManifest = {
name: 'Data Warehouse',
@@ -24,9 +25,10 @@ export const manifest: ProductManifest = {
{
path: 'Data Warehouse',
category: 'Tools',
iconType: 'database',
href: urls.dataWarehouse(),
flag: FEATURE_FLAGS.DATA_WAREHOUSE_SCENE,
iconType: 'data_warehouse' as FileSystemIconType,
iconColor: ['var(--color-product-data-warehouse-light)'] as FileSystemIconColor,
},
],
}

View File

@@ -284,7 +284,6 @@ export function EarlyAccessFeature({ id }: EarlyAccessFeatureLogicProps): JSX.El
description={earlyAccessFeature.description}
resourceType={{
type: 'early_access_feature',
typePlural: 'Early access features',
}}
canEdit
onNameChange={(value) => {

View File

@@ -42,7 +42,6 @@ export function EarlyAccessFeatures(): JSX.Element {
description="Allow your users to individually enable or disable features that are in public beta."
resourceType={{
type: 'early_access_feature',
typePlural: 'Early access features',
}}
/>
<SceneDivider />

View File

@@ -1,8 +1,8 @@
import { IconRocket } from '@posthog/icons'
import { urls } from 'scenes/urls'
import { ProductManifest } from '../../frontend/src/types'
import { FileSystemIconType } from '~/queries/schema/schema-general'
import { FileSystemIconColor, ProductManifest } from '../../frontend/src/types'
export const manifest: ProductManifest = {
name: 'Early access features',
@@ -36,7 +36,7 @@ export const manifest: ProductManifest = {
fileSystemTypes: {
early_access_feature: {
name: 'Early access feature',
icon: <IconRocket />,
iconType: 'early_access_feature' as FileSystemIconType,
href: (ref: string) => urls.earlyAccessFeature(ref),
iconColor: [
'var(--color-product-early-access-features-light)',
@@ -50,6 +50,11 @@ export const manifest: ProductManifest = {
path: `Early access feature`,
type: 'early_access_feature',
href: urls.earlyAccessFeature('new'),
iconType: 'early_access_feature' as FileSystemIconType,
iconColor: [
'var(--color-product-early-access-features-light)',
'var(--color-product-early-access-features-dark)',
] as FileSystemIconColor,
},
],
treeItemsProducts: [
@@ -58,6 +63,11 @@ export const manifest: ProductManifest = {
category: 'Features',
type: 'early_access_feature',
href: urls.earlyAccessFeatures(),
iconType: 'early_access_feature' as FileSystemIconType,
iconColor: [
'var(--color-product-early-access-features-light)',
'var(--color-product-early-access-features-dark)',
] as FileSystemIconColor,
},
],
}

View File

@@ -180,8 +180,7 @@ const Header = (): JSX.Element => {
name="Error tracking"
description="Track and analyze errors in your website or application to understand and fix issues."
resourceType={{
type: 'errorTracking',
typePlural: 'Error Tracking',
type: 'error_tracking',
}}
/>
<SceneDivider />

View File

@@ -2,7 +2,9 @@ import { combineUrl } from 'kea-router'
import { urls } from 'scenes/urls'
import { ProductManifest } from '../../frontend/src/types'
import { FileSystemIconType } from '~/queries/schema/schema-general'
import { FileSystemIconColor, ProductManifest } from '../../frontend/src/types'
export const manifest: ProductManifest = {
name: 'Error tracking',
@@ -62,7 +64,12 @@ export const manifest: ProductManifest = {
{
path: 'Error tracking',
category: 'Behavior',
iconType: 'errorTracking',
type: 'error_tracking',
iconType: 'error_tracking' as FileSystemIconType,
iconColor: [
'var(--color-product-error-tracking-light)',
'var(--color-product-error-tracking-dark)',
] as FileSystemIconColor,
href: urls.errorTracking(),
},
],

View File

@@ -1,11 +1,9 @@
import { IconFlask } from '@posthog/icons'
import { toParams } from 'lib/utils'
import { urls } from 'scenes/urls'
import { ExperimentMetric } from '~/queries/schema/schema-general'
import { ProductManifest } from '../../frontend/src/types'
import { FileSystemIconColor, ProductManifest } from '../../frontend/src/types'
export const manifest: ProductManifest = {
name: 'Experiments',
@@ -29,7 +27,7 @@ export const manifest: ProductManifest = {
fileSystemTypes: {
experiment: {
name: 'Experiment',
icon: <IconFlask />,
iconType: 'experiment',
href: (ref: string) => urls.experiment(ref),
iconColor: ['var(--color-product-experiments-light)'],
filterKey: 'experiment',
@@ -40,6 +38,8 @@ export const manifest: ProductManifest = {
path: `Experiment`,
type: 'experiment',
href: urls.experiment('new'),
iconType: 'experiment',
iconColor: ['var(--color-product-experiments-light)'] as FileSystemIconColor,
},
],
treeItemsProducts: [
@@ -48,6 +48,8 @@ export const manifest: ProductManifest = {
category: 'Features',
type: 'experiment',
href: urls.experiments(),
iconType: 'experiment',
iconColor: ['var(--color-product-experiments-light)'] as FileSystemIconColor,
},
],
}

View File

@@ -1,8 +1,6 @@
import { IconToggle } from '@posthog/icons'
import { urls } from 'scenes/urls'
import { ProductManifest } from '../../frontend/src/types'
import { FileSystemIconColor, ProductManifest } from '../../frontend/src/types'
export const manifest: ProductManifest = {
name: 'Feature Flags',
@@ -14,7 +12,7 @@ export const manifest: ProductManifest = {
fileSystemTypes: {
feature_flag: {
name: 'Feature flag',
icon: <IconToggle />,
iconType: 'feature_flag',
href: (ref: string) => urls.featureFlag(ref),
iconColor: ['var(--color-product-feature-flags-light)'],
filterKey: 'feature_flag',
@@ -25,6 +23,8 @@ export const manifest: ProductManifest = {
path: `Feature flag`,
type: 'feature_flag',
href: urls.featureFlag('new'),
iconType: 'feature_flag',
iconColor: ['var(--color-product-feature-flags-light)'] as FileSystemIconColor,
},
],
treeItemsProducts: [

View File

@@ -1,9 +1,8 @@
import { IconExternal } from '@posthog/icons'
import { FEATURE_FLAGS } from 'lib/constants'
import { urls } from 'scenes/urls'
import { ProductManifest } from '~/types'
import { FileSystemIconType } from '~/queries/schema/schema-general'
import { FileSystemIconColor, ProductManifest } from '~/types'
export const manifest: ProductManifest = {
name: 'Links',
@@ -36,7 +35,7 @@ export const manifest: ProductManifest = {
fileSystemTypes: {
link: {
name: 'Link',
icon: <IconExternal />,
iconType: 'link' as FileSystemIconType,
href: (ref: string) => urls.link(ref),
iconColor: ['var(--color-product-links-light)'],
filterKey: 'link',
@@ -48,6 +47,8 @@ export const manifest: ProductManifest = {
path: `Link`,
type: 'link',
href: urls.link('new'),
iconType: 'link' as FileSystemIconType,
iconColor: ['var(--color-product-links-light)'] as FileSystemIconColor,
flag: FEATURE_FLAGS.LINKS,
},
],

View File

@@ -341,8 +341,7 @@ export function LLMAnalyticsScene(): JSX.Element {
name="LLM Analytics"
description="Analyze and understand your LLM usage and performance."
resourceType={{
type: 'ai',
typePlural: 'LLM Analytics',
type: 'llm_analytics',
}}
/>
<SceneDivider />

View File

@@ -2,7 +2,9 @@ import { combineUrl } from 'kea-router'
import { urls } from 'scenes/urls'
import { ProductManifest } from '../../frontend/src/types'
import { FileSystemIconType } from '~/queries/schema/schema-general'
import { FileSystemIconColor, ProductManifest } from '../../frontend/src/types'
export const manifest: ProductManifest = {
name: 'LLM Analytics',
@@ -112,7 +114,8 @@ export const manifest: ProductManifest = {
{
path: 'LLM analytics',
category: 'Analytics',
iconType: 'ai',
iconType: 'llm_analytics' as FileSystemIconType,
iconColor: ['var(--color-product-llm-analytics-light)'] as FileSystemIconColor,
href: urls.llmAnalyticsDashboard(),
},
],

View File

@@ -1,7 +1,9 @@
import { FEATURE_FLAGS } from 'lib/constants'
import { urls } from 'scenes/urls'
import { ProductManifest } from '../../frontend/src/types'
import { FileSystemIconType } from '~/queries/schema/schema-general'
import { FileSystemIconColor, ProductManifest } from '../../frontend/src/types'
export const manifest: ProductManifest = {
name: 'Logs',
@@ -25,7 +27,8 @@ export const manifest: ProductManifest = {
{
path: 'Logs',
category: 'Tools',
iconType: 'live',
iconType: 'logs' as FileSystemIconType,
iconColor: ['var(--color-product-logs-light)'] as FileSystemIconColor,
href: urls.logs(),
flag: FEATURE_FLAGS.LOGS,
tags: ['alpha'],

View File

@@ -1,9 +1,7 @@
import { IconCursor } from '@posthog/icons'
import { FEATURE_FLAGS, PRODUCT_VISUAL_ORDER } from 'lib/constants'
import { urls } from 'scenes/urls'
import { ProductManifest } from '../../frontend/src/types'
import { FileSystemIconColor, ProductManifest } from '../../frontend/src/types'
import type { MessagingSceneTab } from './frontend/MessagingScene'
export const manifest: ProductManifest = {
@@ -53,8 +51,8 @@ export const manifest: ProductManifest = {
fileSystemTypes: {
messaging: {
name: 'Campaign',
icon: <IconCursor />,
iconColor: ['var(--color-product-messaging-light)'],
iconType: 'messaging',
iconColor: ['var(--color-product-messaging-light)'] as FileSystemIconColor,
href: (ref: string) => urls.messagingCampaign(ref),
filterKey: 'messaging',
},
@@ -68,6 +66,8 @@ export const manifest: ProductManifest = {
category: 'Tools',
tags: ['alpha'],
flag: FEATURE_FLAGS.MESSAGING,
iconType: 'messaging',
iconColor: ['var(--color-product-messaging-light)'] as FileSystemIconColor,
},
],
}

View File

@@ -1,5 +1,3 @@
import { IconNotebook } from '@posthog/icons'
import { urls } from 'scenes/urls'
import { ProductManifest } from '../../frontend/src/types'
@@ -14,7 +12,7 @@ export const manifest: ProductManifest = {
fileSystemTypes: {
notebook: {
name: 'Notebook',
icon: <IconNotebook />,
iconType: 'notebook',
href: (ref: string) => urls.notebook(ref),
filterKey: 'notebook',
},
@@ -24,6 +22,7 @@ export const manifest: ProductManifest = {
path: `Notebook`,
type: 'notebook',
href: urls.notebook('new'),
iconType: 'notebook',
},
],
}

View File

@@ -1,7 +1,5 @@
import { combineUrl } from 'kea-router'
import { IconGraph } from '@posthog/icons'
import { AlertType } from 'lib/components/Alerts/types'
import { INSIGHT_VISUAL_ORDER } from 'lib/constants'
import { urls } from 'scenes/urls'
@@ -9,7 +7,13 @@ import { urls } from 'scenes/urls'
import { DashboardFilter, HogQLFilters, HogQLVariable, Node, NodeKind } from '~/queries/schema/schema-general'
import { isDataTableNode, isDataVisualizationNode, isHogQLQuery } from '~/queries/utils'
import { DashboardType, InsightShortId, InsightType, ProductManifest } from '../../frontend/src/types'
import {
DashboardType,
FileSystemIconColor,
InsightShortId,
InsightType,
ProductManifest,
} from '../../frontend/src/types'
export const manifest: ProductManifest = {
name: 'Product Analytics',
@@ -77,7 +81,7 @@ export const manifest: ProductManifest = {
fileSystemTypes: {
insight: {
name: 'Insight',
icon: <IconGraph />,
iconType: 'product_analytics',
href: (ref: string) => urls.insightView(ref as InsightShortId),
iconColor: ['var(--color-product-product-analytics-light)'],
filterKey: 'insight',
@@ -88,42 +92,48 @@ export const manifest: ProductManifest = {
path: `Insight/Trends`,
type: 'insight',
href: urls.insightNew({ type: InsightType.TRENDS }),
iconType: 'insightTrends',
iconType: 'insight_trend',
iconColor: ['var(--color-insight-trends-light)'] as FileSystemIconColor,
visualOrder: INSIGHT_VISUAL_ORDER.trends,
},
{
path: `Insight/Funnel`,
type: 'insight',
href: urls.insightNew({ type: InsightType.FUNNELS }),
iconType: 'insightFunnel',
iconType: 'insight_funnel',
iconColor: ['var(--color-insight-funnel-light)'] as FileSystemIconColor,
visualOrder: INSIGHT_VISUAL_ORDER.funnel,
},
{
path: `Insight/Retention`,
type: 'insight',
href: urls.insightNew({ type: InsightType.RETENTION }),
iconType: 'insightRetention',
iconType: 'insight_retention',
iconColor: ['var(--color-insight-retention-light)'] as FileSystemIconColor,
visualOrder: INSIGHT_VISUAL_ORDER.retention,
},
{
path: `Insight/User paths`,
type: 'insight',
href: urls.insightNew({ type: InsightType.PATHS }),
iconType: 'insightUserPaths',
iconType: 'insight_user_path',
iconColor: ['var(--color-insight-user-paths-light)', 'var(--color-user-paths-dark)'] as FileSystemIconColor,
visualOrder: INSIGHT_VISUAL_ORDER.paths,
},
{
path: `Insight/Stickiness`,
type: 'insight',
href: urls.insightNew({ type: InsightType.STICKINESS }),
iconType: 'insightStickiness',
iconType: 'insight_stickiness',
iconColor: ['var(--color-insight-stickiness-light)'] as FileSystemIconColor,
visualOrder: INSIGHT_VISUAL_ORDER.stickiness,
},
{
path: `Insight/Lifecycle`,
type: 'insight',
href: urls.insightNew({ type: InsightType.LIFECYCLE }),
iconType: 'insightLifecycle',
iconType: 'insight_lifecycle',
iconColor: ['var(--color-insight-lifecycle-light)'] as FileSystemIconColor,
visualOrder: INSIGHT_VISUAL_ORDER.lifecycle,
},
],
@@ -133,6 +143,8 @@ export const manifest: ProductManifest = {
category: 'Analytics',
type: 'insight',
href: urls.insights(),
iconType: 'product_analytics',
iconColor: ['var(--color-product-product-analytics-light)'] as FileSystemIconColor,
},
],
}

View File

@@ -1,10 +1,8 @@
import { combineUrl } from 'kea-router'
import { IconRewindPlay } from '@posthog/icons'
import { urls } from 'scenes/urls'
import { ProductManifest, RecordingUniversalFilters, ReplayTabs } from '../../frontend/src/types'
import { FileSystemIconColor, ProductManifest, RecordingUniversalFilters, ReplayTabs } from '../../frontend/src/types'
export const manifest: ProductManifest = {
name: 'Replay',
@@ -28,7 +26,7 @@ export const manifest: ProductManifest = {
fileSystemTypes: {
session_recording_playlist: {
name: 'Replay playlist',
icon: <IconRewindPlay />,
iconType: 'session_replay',
href: (ref: string) => urls.replayPlaylist(ref),
iconColor: ['var(--color-product-session-replay-light)', 'var(--color-product-session-replay-dark)'],
filterKey: 'session_recording_playlist',
@@ -39,6 +37,11 @@ export const manifest: ProductManifest = {
path: `Replay playlist`,
type: 'session_recording_playlist',
href: urls.replayPlaylist('new'),
iconType: 'session_replay',
iconColor: [
'var(--color-product-session-replay-light)',
'var(--color-product-session-replay-dark)',
] as FileSystemIconColor,
},
],
treeItemsProducts: [
@@ -47,6 +50,8 @@ export const manifest: ProductManifest = {
category: 'Behavior',
href: urls.replay(ReplayTabs.Home),
type: 'session_recording_playlist',
iconType: 'session_replay',
iconColor: ['var(--color-product-session-replay-light)', 'var(--color-product-session-replay-dark)'],
},
],
}

View File

@@ -51,8 +51,7 @@ export function RevenueAnalyticsScene(): JSX.Element {
name={PRODUCT_NAME}
description={PRODUCT_DESCRIPTION}
resourceType={{
type: PRODUCT_THING_NAME,
typePlural: PRODUCT_NAME,
type: 'revenue_analytics',
}}
/>
<SceneDivider />

View File

@@ -1,7 +1,7 @@
import { useValues } from 'kea'
import { useRef, useState } from 'react'
import { IconHandMoney, IconPlus } from '@posthog/icons'
import { IconPlus } from '@posthog/icons'
import { LemonTabs, Link } from '@posthog/lemon-ui'
import { BaseCurrency } from 'lib/components/BaseCurrency/BaseCurrency'
@@ -54,9 +54,7 @@ export function RevenueAnalyticsSettings(): JSX.Element {
name="Revenue"
description={introductionDescription}
resourceType={{
type: 'revenue',
typePlural: 'revenue events',
forceIcon: <IconHandMoney />,
type: 'revenue_analytics',
}}
/>
<SceneDivider />

View File

@@ -1,8 +1,7 @@
import { IconPiggyBank } from '@posthog/icons'
import { FEATURE_FLAGS } from 'lib/constants'
import { urls } from 'scenes/urls'
import { FileSystemIconType } from '~/queries/schema/schema-general'
import { ProductManifest } from '~/types'
export const manifest: ProductManifest = {
@@ -35,7 +34,7 @@ export const manifest: ProductManifest = {
fileSystemTypes: {
revenue: {
name: 'Revenue',
icon: <IconPiggyBank />,
iconType: 'revenue_analytics' as FileSystemIconType,
href: () => urls.revenueAnalytics(),
iconColor: ['var(--color-product-revenue-analytics-light)', 'var(--color-product-revenue-analytics-dark)'],
filterKey: 'revenue',
@@ -45,14 +44,16 @@ export const manifest: ProductManifest = {
{
path: 'Revenue settings',
category: 'Definitions',
iconType: 'handMoney',
iconType: 'revenue_analytics' as FileSystemIconType,
iconColor: ['var(--color-product-revenue-analytics-light)', 'var(--color-product-revenue-analytics-dark)'],
href: urls.revenueSettings(),
flag: FEATURE_FLAGS.REVENUE_ANALYTICS,
},
{
path: 'Marketing settings',
category: 'Definitions',
iconType: 'definitions',
iconType: 'revenue_analytics' as FileSystemIconType,
iconColor: ['var(--color-product-revenue-analytics-light)', 'var(--color-product-revenue-analytics-dark)'],
href: urls.marketingAnalytics(),
flag: FEATURE_FLAGS.WEB_ANALYTICS_MARKETING,
},

View File

@@ -1,9 +1,7 @@
import { IconMessage } from '@posthog/icons'
import { SurveysTabs } from 'scenes/surveys/surveysLogic'
import { urls } from 'scenes/urls'
import { ProductManifest } from '../../frontend/src/types'
import { FileSystemIconColor, ProductManifest } from '../../frontend/src/types'
export const manifest: ProductManifest = {
name: 'Surveys',
@@ -16,7 +14,7 @@ export const manifest: ProductManifest = {
fileSystemTypes: {
survey: {
name: 'Survey',
icon: <IconMessage />,
iconType: 'survey',
href: (ref: string) => urls.survey(ref),
iconColor: ['var(--color-product-surveys-light)'],
filterKey: 'survey',
@@ -27,6 +25,8 @@ export const manifest: ProductManifest = {
path: `Survey`,
type: 'survey',
href: urls.survey('new'),
iconType: 'survey',
iconColor: ['var(--color-product-surveys-light)'] as FileSystemIconColor,
},
],
treeItemsProducts: [
@@ -35,6 +35,8 @@ export const manifest: ProductManifest = {
category: 'Behavior',
type: 'survey',
href: urls.surveys(),
iconType: 'survey',
iconColor: ['var(--color-product-surveys-light)'] as FileSystemIconColor,
},
],
}

View File

@@ -60,7 +60,6 @@ export function TaskTracker(): JSX.Element {
description="Manage and track development tasks across all PostHog products"
resourceType={{
type: 'task',
typePlural: 'tasks',
}}
/>
<SceneDivider />

View File

@@ -1,9 +1,7 @@
import { IconBug } from '@posthog/icons'
import { FEATURE_FLAGS } from 'lib/constants'
import { urls } from 'scenes/urls'
import { ProductManifest } from '../../frontend/src/types'
import { FileSystemIconColor, ProductManifest } from '../../frontend/src/types'
export const manifest: ProductManifest = {
name: 'Tasks',
@@ -26,7 +24,7 @@ export const manifest: ProductManifest = {
fileSystemTypes: {
task: {
name: 'Task',
icon: <IconBug />,
iconType: 'task',
href: () => urls.taskTracker(),
iconColor: ['var(--product-tasks-light)', 'var(--product-tasks-dark)'],
filterKey: 'task',
@@ -41,6 +39,8 @@ export const manifest: ProductManifest = {
type: 'task',
href: urls.taskTracker(),
flag: FEATURE_FLAGS.TASKS,
iconType: 'task',
iconColor: ['var(--product-tasks-light)', 'var(--product-tasks-dark)'] as FileSystemIconColor,
},
],
}

View File

@@ -35,7 +35,6 @@ export function UserInterviews(): JSX.Element {
description="Make full use of user interviews by recording them with PostHog."
resourceType={{
type: 'user_interview',
typePlural: 'User interviews',
}}
/>
<SceneDivider />

View File

@@ -1,9 +1,7 @@
import { IconChat } from '@posthog/icons'
import { FEATURE_FLAGS } from 'lib/constants'
import { urls } from 'scenes/urls'
import { ProductManifest } from '../../frontend/src/types'
import { FileSystemIconColor, ProductManifest } from '../../frontend/src/types'
export const manifest: ProductManifest = {
name: 'User interviews',
@@ -32,7 +30,7 @@ export const manifest: ProductManifest = {
fileSystemTypes: {
user_interview: {
name: 'User interview',
icon: <IconChat />,
iconType: 'user_interview',
href: (ref: string) => urls.userInterview(ref),
iconColor: ['var(--color-product-user-interviews-light)'],
filterKey: 'user_interview',
@@ -47,6 +45,8 @@ export const manifest: ProductManifest = {
type: 'user_interview',
flag: FEATURE_FLAGS.USER_INTERVIEWS,
tags: ['alpha'],
iconType: 'user_interview',
iconColor: ['var(--color-product-user-interviews-light)'] as FileSystemIconColor,
},
],
}

View File

@@ -1,6 +1,6 @@
import { urls } from 'scenes/urls'
import { ProductManifest } from '../../frontend/src/types'
import { FileSystemIconColor, ProductManifest } from '../../frontend/src/types'
export const manifest: ProductManifest = {
name: 'Web Analytics',
@@ -15,7 +15,8 @@ export const manifest: ProductManifest = {
{
path: 'Web analytics',
category: 'Analytics',
iconType: 'pieChart',
iconType: 'web_analytics',
iconColor: ['var(--color-product-web-analytics-light)'] as FileSystemIconColor,
href: urls.webAnalytics(),
},
],

View File

@@ -6,6 +6,7 @@
"scenes/*": ["src/scenes/*"],
"@posthog/lemon-ui": ["@posthog/lemon-ui/src/index"],
"@posthog/lemon-ui/*": ["@posthog/lemon-ui/src/*"],
"@posthog/icons": ["node_modules/@posthog/icons"],
"storybook/*": ["../.storybook/*"],
"@posthog/ee/exports": ["../ee/exports", "@posthog/ee/exports"],
"~/*": ["src/*"],