diff --git a/.eslintrc.js b/.eslintrc.js index 91fe2aed3b1e8..5f71d84aebdd8 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -42,13 +42,25 @@ module.exports = { }, ecmaVersion: 2018, sourceType: 'module', - project: 'tsconfig.json' + project: 'tsconfig.json', }, - plugins: ['prettier', 'react', 'cypress', '@typescript-eslint', 'no-only-tests', 'jest', 'compat', 'posthog'], + plugins: [ + 'prettier', + 'react', + 'cypress', + '@typescript-eslint', + 'no-only-tests', + 'jest', + 'compat', + 'posthog', + 'simple-import-sort', + ], rules: { 'no-console': ['error', { allow: ['warn', 'error'] }], 'no-debugger': 'error', 'no-only-tests/no-only-tests': 'error', + 'simple-import-sort/imports': 'error', + 'simple-import-sort/exports': 'error', 'react/prop-types': [0], 'react/react-in-jsx-scope': [0], 'react/no-unescaped-entities': [0], @@ -112,6 +124,11 @@ module.exports = { importNames: ['Tooltip'], message: 'Please use Tooltip from @posthog/lemon-ui instead.', }, + { + name: 'antd', + importNames: ['Alert'], + message: 'Please use LemonBanner from @posthog/lemon-ui instead.', + }, ], }, ], @@ -231,6 +248,10 @@ module.exports = { element: 'a', message: 'use instead', }, + { + element: 'Alert', + message: 'use instead', + }, ], }, ], @@ -254,14 +275,22 @@ module.exports = { rules: { // The below complains needlessly about expect(api.createInvite).toHaveBeenCalledWith(...) '@typescript-eslint/unbound-method': 'off', - } + }, }, { - // disable these rules for files generated by kea-typegen - files: ['*Type.ts', '*Type.tsx'], + files: ['*Type.ts', '*Type.tsx'], // Kea typegen output rules: { 'no-restricted-imports': 'off', - '@typescript-eslint/ban-types': ['off'], + '@typescript-eslint/ban-types': 'off', + 'simple-import-sort/imports': 'off', + 'simple-import-sort/exports': 'off', + }, + }, + { + files: ['frontend/src/scenes/notebooks/Nodes/*'], // Notebooks code weirdly relies on its order of sorting + rules: { + 'simple-import-sort/imports': 'off', + 'simple-import-sort/exports': 'off', }, }, { diff --git a/.stylelintrc.js b/.stylelintrc.js index 5df820f88d8fb..19bbc999f0f51 100644 --- a/.stylelintrc.js +++ b/.stylelintrc.js @@ -10,6 +10,7 @@ module.exports = { // CSS Color Module Level 3 says currentColor, Level 4 candidate says currentcolor // Sticking to Level 3 for now camelCaseSvgKeywords: true, + ignoreKeywords: ['BlinkMacSystemFont'], // BlinkMacSystemFont MUST have this particular casing }, ], // Sadly Safari only started supporting the range syntax of media queries in 2023, so let's switch to that diff --git a/cypress/e2e/featureFlags.cy.ts b/cypress/e2e/featureFlags.cy.ts index 9045a51a4f485..bf37822321ad1 100644 --- a/cypress/e2e/featureFlags.cy.ts +++ b/cypress/e2e/featureFlags.cy.ts @@ -48,6 +48,7 @@ describe('Feature Flags', () => { cy.get('[data-attr=save-feature-flag]').first().click() // after save there should be a delete button + cy.get('[data-attr="more-button"]').click() cy.get('button[data-attr="delete-feature-flag"]').should('have.text', 'Delete feature flag') // make sure the data is there as expected after a page reload! @@ -83,11 +84,13 @@ describe('Feature Flags', () => { cy.get('[data-attr=save-feature-flag]').first().click() // after save there should be a delete button + cy.get('[data-attr="more-button"]').click() cy.get('button[data-attr="delete-feature-flag"]').should('have.text', 'Delete feature flag') cy.clickNavMenu('featureflags') cy.get('[data-attr=feature-flag-table]').should('contain', name) cy.get(`[data-row-key=${name}]`).contains(name).click() + cy.get('[data-attr="more-button"]').click() cy.get('[data-attr=delete-feature-flag]').click() cy.get('.Toastify').contains('Undo').should('be.visible') }) diff --git a/cypress/e2e/insights.cy.ts b/cypress/e2e/insights.cy.ts index 5157d21429ba9..80b1c06c4398e 100644 --- a/cypress/e2e/insights.cy.ts +++ b/cypress/e2e/insights.cy.ts @@ -1,7 +1,8 @@ import { urls } from 'scenes/urls' -import { randomString } from '../support/random' + import { decideResponse } from '../fixtures/api/decide' -import { savedInsights, createInsight, insight } from '../productAnalytics' +import { createInsight, insight, savedInsights } from '../productAnalytics' +import { randomString } from '../support/random' // For tests related to trends please check trendsElements.js // insight tests were split up because Cypress was struggling with this many tests in one file🙈 diff --git a/ee/api/test/test_billing.py b/ee/api/test/test_billing.py index 88addd2d7f416..c37c3ee9d6482 100644 --- a/ee/api/test/test_billing.py +++ b/ee/api/test/test_billing.py @@ -2,9 +2,9 @@ from typing import Any, Dict, List from unittest.mock import MagicMock, patch from uuid import uuid4 +from zoneinfo import ZoneInfo import jwt -from zoneinfo import ZoneInfo from dateutil.relativedelta import relativedelta from django.utils.timezone import now from freezegun import freeze_time diff --git a/ee/api/test/test_organization.py b/ee/api/test/test_organization.py index 2f1b11bb95256..a77361dc579e8 100644 --- a/ee/api/test/test_organization.py +++ b/ee/api/test/test_organization.py @@ -1,6 +1,7 @@ import datetime as dt import random -from unittest.mock import ANY, patch +from unittest import mock +from unittest.mock import ANY, call, patch from freezegun.api import freeze_time from rest_framework import status @@ -104,11 +105,21 @@ def test_delete_last_organization(self, mock_capture): "Did not return a 404 on trying to delete a nonexistent org", ) - mock_capture.assert_called_once_with( - self.user.distinct_id, - "organization deleted", - organization_props, - groups={"instance": ANY, "organization": str(org_id)}, + mock_capture.assert_has_calls( + [ + call( + self.user.distinct_id, + "membership level changed", + properties={"new_level": 15, "previous_level": 1}, + groups=mock.ANY, + ), + call( + self.user.distinct_id, + "organization deleted", + organization_props, + groups={"instance": mock.ANY, "organization": str(org_id)}, + ), + ] ) def test_no_delete_organization_not_owning(self): diff --git a/ee/billing/billing_manager.py b/ee/billing/billing_manager.py index 5a8119c57df9b..324b158fe071d 100644 --- a/ee/billing/billing_manager.py +++ b/ee/billing/billing_manager.py @@ -6,6 +6,7 @@ import structlog from django.utils import timezone from rest_framework.exceptions import NotAuthenticated +from sentry_sdk import capture_exception from ee.billing.billing_types import BillingStatus from ee.billing.quota_limiting import set_org_usage_summary, sync_org_quota_limits @@ -13,7 +14,7 @@ from ee.settings import BILLING_SERVICE_URL from posthog.cloud_utils import get_cached_instance_license from posthog.models import Organization -from posthog.models.organization import OrganizationUsageInfo +from posthog.models.organization import OrganizationMembership, OrganizationUsageInfo logger = structlog.get_logger(__name__) @@ -114,6 +115,14 @@ def update_billing_distinct_ids(self, organization: Organization) -> None: distinct_ids = list(organization.members.values_list("distinct_id", flat=True)) self.update_billing(organization, {"distinct_ids": distinct_ids}) + def update_billing_customer_email(self, organization: Organization) -> None: + try: + owner_membership = OrganizationMembership.objects.get(organization=organization, level=15) + user = owner_membership.user + self.update_billing(organization, {"org_customer_email": user.email}) + except Exception as e: + capture_exception(e) + def deactivate_products(self, organization: Organization, products: str) -> None: res = requests.get( f"{BILLING_SERVICE_URL}/api/billing/deactivate?products={products}", diff --git a/ee/billing/test/test_billing_manager.py b/ee/billing/test/test_billing_manager.py index e0c09e0d071fb..1dbbcb464f068 100644 --- a/ee/billing/test/test_billing_manager.py +++ b/ee/billing/test/test_billing_manager.py @@ -33,3 +33,26 @@ def test_update_billing_distinct_ids(self, billing_patch_request_mock: MagicMock BillingManager(license).update_billing_distinct_ids(organization) assert billing_patch_request_mock.call_count == 1 assert len(billing_patch_request_mock.call_args[1]["json"]["distinct_ids"]) == 2 + + @patch( + "ee.billing.billing_manager.requests.patch", + return_value=MagicMock(status_code=200, json=MagicMock(return_value={"text": "ok"})), + ) + def test_update_billing_customer_email(self, billing_patch_request_mock: MagicMock): + organization = self.organization + license = super(LicenseManager, cast(LicenseManager, License.objects)).create( + key="key123::key123", + plan="enterprise", + valid_until=timezone.datetime(2038, 1, 19, 3, 14, 7), + ) + User.objects.create_and_join( + organization=organization, + email="y@x.com", + password=None, + level=OrganizationMembership.Level.OWNER, + ) + organization.refresh_from_db() + assert len(organization.members.values_list("distinct_id", flat=True)) == 2 # one exists in the test base + BillingManager(license).update_billing_customer_email(organization) + assert billing_patch_request_mock.call_count == 1 + assert billing_patch_request_mock.call_args[1]["json"]["org_customer_email"] == "y@x.com" diff --git a/ee/clickhouse/models/test/__snapshots__/test_property.ambr b/ee/clickhouse/models/test/__snapshots__/test_property.ambr index cc8e77f83a0dc..d27396834cf99 100644 --- a/ee/clickhouse/models/test/__snapshots__/test_property.ambr +++ b/ee/clickhouse/models/test/__snapshots__/test_property.ambr @@ -57,7 +57,7 @@ --- # name: test_parse_groups_persons_edge_case_with_single_filter ( - 'AND ( has(%(vglobalperson_0)s, replaceRegexpAll(JSONExtractRaw(person_props, %(kglobalperson_0)s), \'^"|"$\', \'\')))', + 'AND ( has(%(vglobalperson_0)s, "pmat_email"))', { 'kglobalperson_0': 'email', 'vglobalperson_0': [ diff --git a/ee/clickhouse/views/test/__snapshots__/test_clickhouse_experiment_secondary_results.ambr b/ee/clickhouse/views/test/__snapshots__/test_clickhouse_experiment_secondary_results.ambr index 11cfe7070f2f4..3474ae77b858f 100644 --- a/ee/clickhouse/views/test/__snapshots__/test_clickhouse_experiment_secondary_results.ambr +++ b/ee/clickhouse/views/test/__snapshots__/test_clickhouse_experiment_secondary_results.ambr @@ -1,6 +1,6 @@ # name: ClickhouseTestExperimentSecondaryResults.test_basic_secondary_metric_results ' - /* user_id:133 celery:posthog.celery.sync_insight_caching_state */ + /* user_id:131 celery:posthog.celery.sync_insight_caching_state */ SELECT team_id, date_diff('second', max(timestamp), now()) AS age FROM events diff --git a/frontend/__snapshots__/components-command-bar--actions.png b/frontend/__snapshots__/components-command-bar--actions.png index 302fb86f50402..a1c3b448c6a2e 100644 Binary files a/frontend/__snapshots__/components-command-bar--actions.png and b/frontend/__snapshots__/components-command-bar--actions.png differ diff --git a/frontend/__snapshots__/components-command-bar--search.png b/frontend/__snapshots__/components-command-bar--search.png index 54dff6f4974bf..d155d92fac149 100644 Binary files a/frontend/__snapshots__/components-command-bar--search.png and b/frontend/__snapshots__/components-command-bar--search.png differ diff --git a/frontend/__snapshots__/components-command-bar--shortcuts.png b/frontend/__snapshots__/components-command-bar--shortcuts.png new file mode 100644 index 0000000000000..32f4e7ff34955 Binary files /dev/null and b/frontend/__snapshots__/components-command-bar--shortcuts.png differ diff --git a/frontend/__snapshots__/components-networkrequesttiming--basic.png b/frontend/__snapshots__/components-networkrequesttiming--basic.png index 8247b433f71c8..effc91c21a0a6 100644 Binary files a/frontend/__snapshots__/components-networkrequesttiming--basic.png and b/frontend/__snapshots__/components-networkrequesttiming--basic.png differ diff --git a/frontend/__snapshots__/layout-navigation--app-page-with-side-bar-shown.png b/frontend/__snapshots__/layout-navigation--app-page-with-side-bar-shown.png index b49b6fc4bd341..b2ae49cd91f5b 100644 Binary files a/frontend/__snapshots__/layout-navigation--app-page-with-side-bar-shown.png and b/frontend/__snapshots__/layout-navigation--app-page-with-side-bar-shown.png differ diff --git a/frontend/__snapshots__/lemon-ui-lemon-banner--closable.png b/frontend/__snapshots__/lemon-ui-lemon-banner--closable.png index a05dd78b3e3e7..a7a8ac55c5061 100644 Binary files a/frontend/__snapshots__/lemon-ui-lemon-banner--closable.png and b/frontend/__snapshots__/lemon-ui-lemon-banner--closable.png differ diff --git a/frontend/__snapshots__/lemon-ui-lemon-banner--dismissable.png b/frontend/__snapshots__/lemon-ui-lemon-banner--dismissable.png index be2ef2e5a884b..540a8a3ef2c39 100644 Binary files a/frontend/__snapshots__/lemon-ui-lemon-banner--dismissable.png and b/frontend/__snapshots__/lemon-ui-lemon-banner--dismissable.png differ diff --git a/frontend/__snapshots__/lemon-ui-lemon-banner--error.png b/frontend/__snapshots__/lemon-ui-lemon-banner--error.png index 7db8c557495b9..9389cfa4ea1b2 100644 Binary files a/frontend/__snapshots__/lemon-ui-lemon-banner--error.png and b/frontend/__snapshots__/lemon-ui-lemon-banner--error.png differ diff --git a/frontend/__snapshots__/lemon-ui-lemon-banner--info.png b/frontend/__snapshots__/lemon-ui-lemon-banner--info.png index 7c6e78d57caf2..6848c05f89a32 100644 Binary files a/frontend/__snapshots__/lemon-ui-lemon-banner--info.png and b/frontend/__snapshots__/lemon-ui-lemon-banner--info.png differ diff --git a/frontend/__snapshots__/lemon-ui-lemon-banner--success.png b/frontend/__snapshots__/lemon-ui-lemon-banner--success.png index 2053ce5ccc6de..f3b58cb98363a 100644 Binary files a/frontend/__snapshots__/lemon-ui-lemon-banner--success.png and b/frontend/__snapshots__/lemon-ui-lemon-banner--success.png differ diff --git a/frontend/__snapshots__/lemon-ui-lemon-banner--warning.png b/frontend/__snapshots__/lemon-ui-lemon-banner--warning.png index bf8c975d7385b..3c41933fb5078 100644 Binary files a/frontend/__snapshots__/lemon-ui-lemon-banner--warning.png and b/frontend/__snapshots__/lemon-ui-lemon-banner--warning.png differ diff --git a/frontend/__snapshots__/lemon-ui-lemon-button--as-links.png b/frontend/__snapshots__/lemon-ui-lemon-button--as-links.png index 24ae6fe59d181..292f9ce7d0a99 100644 Binary files a/frontend/__snapshots__/lemon-ui-lemon-button--as-links.png and b/frontend/__snapshots__/lemon-ui-lemon-button--as-links.png differ diff --git a/frontend/__snapshots__/posthog-3000-keyboard-shortcut--default.png b/frontend/__snapshots__/posthog-3000-keyboard-shortcut--default.png index 1f8990c3a32c8..995c1bc753ad1 100644 Binary files a/frontend/__snapshots__/posthog-3000-keyboard-shortcut--default.png and b/frontend/__snapshots__/posthog-3000-keyboard-shortcut--default.png differ diff --git a/frontend/__snapshots__/posthog-3000-keyboard-shortcut--muted.png b/frontend/__snapshots__/posthog-3000-keyboard-shortcut--muted.png index 091bda66799ec..995c1bc753ad1 100644 Binary files a/frontend/__snapshots__/posthog-3000-keyboard-shortcut--muted.png and b/frontend/__snapshots__/posthog-3000-keyboard-shortcut--muted.png differ diff --git a/frontend/__snapshots__/posthog-3000-navigation--navigation-3000.png b/frontend/__snapshots__/posthog-3000-navigation--navigation-3000.png index db71a2726588c..bf6d08b1cb083 100644 Binary files a/frontend/__snapshots__/posthog-3000-navigation--navigation-3000.png and b/frontend/__snapshots__/posthog-3000-navigation--navigation-3000.png differ diff --git a/frontend/__snapshots__/posthog-3000-navigation--navigation-base.png b/frontend/__snapshots__/posthog-3000-navigation--navigation-base.png index 3c1f2a921338a..87cd957353f8c 100644 Binary files a/frontend/__snapshots__/posthog-3000-navigation--navigation-base.png and b/frontend/__snapshots__/posthog-3000-navigation--navigation-base.png differ diff --git a/frontend/__snapshots__/scenes-app-batchexports--create-export.png b/frontend/__snapshots__/scenes-app-batchexports--create-export.png index 5812443d7cc01..51889a6cdcc34 100644 Binary files a/frontend/__snapshots__/scenes-app-batchexports--create-export.png and b/frontend/__snapshots__/scenes-app-batchexports--create-export.png differ diff --git a/frontend/__snapshots__/scenes-app-experiments--complete-funnel-experiment.png b/frontend/__snapshots__/scenes-app-experiments--complete-funnel-experiment.png index 189dc9741ea0f..0c9084824591a 100644 Binary files a/frontend/__snapshots__/scenes-app-experiments--complete-funnel-experiment.png and b/frontend/__snapshots__/scenes-app-experiments--complete-funnel-experiment.png differ diff --git a/frontend/__snapshots__/scenes-app-experiments--running-trend-experiment.png b/frontend/__snapshots__/scenes-app-experiments--running-trend-experiment.png index 60c850a72b2db..766de1662f8ae 100644 Binary files a/frontend/__snapshots__/scenes-app-experiments--running-trend-experiment.png and b/frontend/__snapshots__/scenes-app-experiments--running-trend-experiment.png differ diff --git a/frontend/__snapshots__/scenes-app-feature-flags--edit-feature-flag.png b/frontend/__snapshots__/scenes-app-feature-flags--edit-feature-flag.png index 0d7d6dd72c02b..9fe8b83975eb5 100644 Binary files a/frontend/__snapshots__/scenes-app-feature-flags--edit-feature-flag.png and b/frontend/__snapshots__/scenes-app-feature-flags--edit-feature-flag.png differ diff --git a/frontend/__snapshots__/scenes-app-insights--funnel-left-to-right-breakdown-edit.png b/frontend/__snapshots__/scenes-app-insights--funnel-left-to-right-breakdown-edit.png index 7ef2484ddde67..8be9ffc926019 100644 Binary files a/frontend/__snapshots__/scenes-app-insights--funnel-left-to-right-breakdown-edit.png and b/frontend/__snapshots__/scenes-app-insights--funnel-left-to-right-breakdown-edit.png differ diff --git a/frontend/__snapshots__/scenes-app-notebooks--notebook-not-found.png b/frontend/__snapshots__/scenes-app-notebooks--notebook-not-found.png index 0df1f64e9ec3c..6286e7ae27078 100644 Binary files a/frontend/__snapshots__/scenes-app-notebooks--notebook-not-found.png and b/frontend/__snapshots__/scenes-app-notebooks--notebook-not-found.png differ diff --git a/frontend/__snapshots__/scenes-app-notebooks--notebooks-list.png b/frontend/__snapshots__/scenes-app-notebooks--notebooks-list.png index c9f29c566c2c6..04209a125f40b 100644 Binary files a/frontend/__snapshots__/scenes-app-notebooks--notebooks-list.png and b/frontend/__snapshots__/scenes-app-notebooks--notebooks-list.png differ diff --git a/frontend/__snapshots__/scenes-app-pipeline--pipeline-app-logs.png b/frontend/__snapshots__/scenes-app-pipeline--pipeline-app-logs.png index f7ea3ec3cff02..fc3f054686e53 100644 Binary files a/frontend/__snapshots__/scenes-app-pipeline--pipeline-app-logs.png and b/frontend/__snapshots__/scenes-app-pipeline--pipeline-app-logs.png differ diff --git a/frontend/__snapshots__/scenes-app-surveys--surveys-list.png b/frontend/__snapshots__/scenes-app-surveys--surveys-list.png index 012692ee2758d..80ccaa5e006fd 100644 Binary files a/frontend/__snapshots__/scenes-app-surveys--surveys-list.png and b/frontend/__snapshots__/scenes-app-surveys--surveys-list.png differ diff --git a/frontend/__snapshots__/scenes-other-login--sso-error.png b/frontend/__snapshots__/scenes-other-login--sso-error.png index 4bac52c291407..37309681cfb75 100644 Binary files a/frontend/__snapshots__/scenes-other-login--sso-error.png and b/frontend/__snapshots__/scenes-other-login--sso-error.png differ diff --git a/frontend/__snapshots__/scenes-other-settings--settings-organization.png b/frontend/__snapshots__/scenes-other-settings--settings-organization.png index 240b6b4c957e5..0e5752e576d8b 100644 Binary files a/frontend/__snapshots__/scenes-other-settings--settings-organization.png and b/frontend/__snapshots__/scenes-other-settings--settings-organization.png differ diff --git a/frontend/__snapshots__/scenes-other-settings--settings-project.png b/frontend/__snapshots__/scenes-other-settings--settings-project.png index 71514ddb64f12..227e1bac41f89 100644 Binary files a/frontend/__snapshots__/scenes-other-settings--settings-project.png and b/frontend/__snapshots__/scenes-other-settings--settings-project.png differ diff --git a/frontend/__snapshots__/scenes-other-settings--settings-user.png b/frontend/__snapshots__/scenes-other-settings--settings-user.png index 5574601d11794..7d18a6db46dd5 100644 Binary files a/frontend/__snapshots__/scenes-other-settings--settings-user.png and b/frontend/__snapshots__/scenes-other-settings--settings-user.png differ diff --git a/frontend/__snapshots__/scenes-other-toolbar-components--flags.png b/frontend/__snapshots__/scenes-other-toolbar-components--flags.png index 43dd944036a73..10086fc86f5c1 100644 Binary files a/frontend/__snapshots__/scenes-other-toolbar-components--flags.png and b/frontend/__snapshots__/scenes-other-toolbar-components--flags.png differ diff --git a/frontend/src/exporter/ExportedInsight/ExportedInsight.tsx b/frontend/src/exporter/ExportedInsight/ExportedInsight.tsx index c75e6306f9ef8..d34818193fd4a 100644 --- a/frontend/src/exporter/ExportedInsight/ExportedInsight.tsx +++ b/frontend/src/exporter/ExportedInsight/ExportedInsight.tsx @@ -1,18 +1,20 @@ -import { ChartDisplayType, InsightLogicProps, InsightModel } from '~/types' +import './ExportedInsight.scss' + +import clsx from 'clsx' import { BindLogic } from 'kea' -import { insightLogic } from 'scenes/insights/insightLogic' import { FilterBasedCardContent } from 'lib/components/Cards/InsightCard/InsightCard' -import './ExportedInsight.scss' -import { Logo } from '~/toolbar/assets/Logo' +import { QueriesUnsupportedHere } from 'lib/components/Cards/InsightCard/QueriesUnsupportedHere' +import { TopHeading } from 'lib/components/Cards/InsightCard/TopHeading' import { InsightLegend } from 'lib/components/InsightLegend/InsightLegend' -import { ExportOptions, ExportType } from '~/exporter/types' -import clsx from 'clsx' import { SINGLE_SERIES_DISPLAY_TYPES } from 'lib/constants' +import { insightLogic } from 'scenes/insights/insightLogic' import { isTrendsFilter } from 'scenes/insights/sharedUtils' -import { isDataTableNode } from '~/queries/utils' -import { QueriesUnsupportedHere } from 'lib/components/Cards/InsightCard/QueriesUnsupportedHere' + +import { ExportOptions, ExportType } from '~/exporter/types' import { Query } from '~/queries/Query/Query' -import { TopHeading } from 'lib/components/Cards/InsightCard/TopHeading' +import { isDataTableNode } from '~/queries/utils' +import { Logo } from '~/toolbar/assets/Logo' +import { ChartDisplayType, InsightLogicProps, InsightModel } from '~/types' export function ExportedInsight({ insight, diff --git a/frontend/src/exporter/Exporter.stories.tsx b/frontend/src/exporter/Exporter.stories.tsx index 4c5acbd7257aa..95693b3465ad0 100644 --- a/frontend/src/exporter/Exporter.stories.tsx +++ b/frontend/src/exporter/Exporter.stories.tsx @@ -1,9 +1,11 @@ -import { useEffect } from 'react' import { Meta, StoryFn, StoryObj } from '@storybook/react' -import { Exporter } from './Exporter' +import { useEffect } from 'react' + import { dashboard } from '~/exporter/__mocks__/Exporter.mocks' import { ExportType } from '~/exporter/types' +import { Exporter } from './Exporter' + type Story = StoryObj const meta: Meta = { title: 'Exporter/Exporter', diff --git a/frontend/src/exporter/Exporter.tsx b/frontend/src/exporter/Exporter.tsx index 1941637123e83..0ba873c570fe1 100644 --- a/frontend/src/exporter/Exporter.tsx +++ b/frontend/src/exporter/Exporter.tsx @@ -1,18 +1,21 @@ import '~/styles' import './Exporter.scss' -import { useEffect } from 'react' -import { ExportedData, ExportType } from '~/exporter/types' -import { DashboardPlacement } from '~/types' -import { ExportedInsight } from '~/exporter/ExportedInsight/ExportedInsight' -import { Logo } from '~/toolbar/assets/Logo' -import { Dashboard } from 'scenes/dashboard/Dashboard' -import { useResizeObserver } from 'lib/hooks/useResizeObserver' -import { Link } from 'lib/lemon-ui/Link' + import clsx from 'clsx' import { useValues } from 'kea' -import { teamLogic } from 'scenes/teamLogic' +import { useResizeObserver } from 'lib/hooks/useResizeObserver' +import { Link } from 'lib/lemon-ui/Link' +import { useEffect } from 'react' +import { Dashboard } from 'scenes/dashboard/Dashboard' import { SessionRecordingPlayer } from 'scenes/session-recordings/player/SessionRecordingPlayer' import { SessionRecordingPlayerMode } from 'scenes/session-recordings/player/sessionRecordingPlayerLogic' +import { teamLogic } from 'scenes/teamLogic' + +import { ExportedInsight } from '~/exporter/ExportedInsight/ExportedInsight' +import { ExportedData, ExportType } from '~/exporter/types' +import { Logo } from '~/toolbar/assets/Logo' +import { DashboardPlacement } from '~/types' + import { exporterViewLogic } from './exporterViewLogic' export function Exporter(props: ExportedData): JSX.Element { diff --git a/frontend/src/exporter/__mocks__/Exporter.mocks.tsx b/frontend/src/exporter/__mocks__/Exporter.mocks.tsx index fdf477f996322..6d2b7e87d1fad 100644 --- a/frontend/src/exporter/__mocks__/Exporter.mocks.tsx +++ b/frontend/src/exporter/__mocks__/Exporter.mocks.tsx @@ -1,3 +1,5 @@ +import { FunnelLayout, ShownAsValue } from 'lib/constants' + import { ChartDisplayType, DashboardTile, @@ -7,7 +9,6 @@ import { InsightShortId, InsightType, } from '~/types' -import { FunnelLayout, ShownAsValue } from 'lib/constants' export const dashboard: DashboardType = { id: 1, diff --git a/frontend/src/exporter/exporterViewLogic.ts b/frontend/src/exporter/exporterViewLogic.ts index e0c36900fc728..dcb6adf2e137c 100644 --- a/frontend/src/exporter/exporterViewLogic.ts +++ b/frontend/src/exporter/exporterViewLogic.ts @@ -1,7 +1,7 @@ import { kea, path, props, selectors } from 'kea' -import { ExportedData } from './types' import type { exporterViewLogicType } from './exporterViewLogicType' +import { ExportedData } from './types' // This is a simple logic that is mounted by the Exporter view and then can be found by any nested callers // This simplifies passing props everywhere. diff --git a/frontend/src/exporter/index.tsx b/frontend/src/exporter/index.tsx index df1660537cb44..995334d949021 100644 --- a/frontend/src/exporter/index.tsx +++ b/frontend/src/exporter/index.tsx @@ -1,10 +1,13 @@ import '~/styles' import './Exporter.scss' + import { createRoot } from 'react-dom/client' -import { loadPostHogJS } from '~/loadPostHogJS' -import { initKea } from '~/initKea' + import { Exporter } from '~/exporter/Exporter' import { ExportedData } from '~/exporter/types' +import { initKea } from '~/initKea' +import { loadPostHogJS } from '~/loadPostHogJS' + import { ErrorBoundary } from '../layout/ErrorBoundary' // Disable tracking for all exports and embeds. diff --git a/frontend/src/globals.d.ts b/frontend/src/globals.d.ts index 17bc65680725a..b03852c10a890 100644 --- a/frontend/src/globals.d.ts +++ b/frontend/src/globals.d.ts @@ -1,4 +1,5 @@ import posthog from 'posthog-js' + import { ExportedData } from '~/exporter/types' declare global { diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index 42746c188f0ea..272a61f785e3d 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -1,16 +1,14 @@ import '~/styles' -import { createRoot } from 'react-dom/client' import { getContext } from 'kea' - +import posthog from 'posthog-js' +import { PostHogProvider } from 'posthog-js/react' +import { createRoot } from 'react-dom/client' import { App } from 'scenes/App' -import { initKea } from './initKea' -import { loadPostHogJS } from './loadPostHogJS' +import { initKea } from './initKea' import { ErrorBoundary } from './layout/ErrorBoundary' - -import { PostHogProvider } from 'posthog-js/react' -import posthog from 'posthog-js' +import { loadPostHogJS } from './loadPostHogJS' loadPostHogJS() initKea() diff --git a/frontend/src/initKea.ts b/frontend/src/initKea.ts index 79d727740a4dc..bb5b0af3e5525 100644 --- a/frontend/src/initKea.ts +++ b/frontend/src/initKea.ts @@ -1,13 +1,13 @@ import { KeaPlugin, resetContext } from 'kea' +import { formsPlugin } from 'kea-forms' +import { loadersPlugin } from 'kea-loaders' import { localStoragePlugin } from 'kea-localstorage' import { routerPlugin } from 'kea-router' -import { loadersPlugin } from 'kea-loaders' -import { windowValuesPlugin } from 'kea-window-values' -import { identifierToHuman } from 'lib/utils' +import { subscriptionsPlugin } from 'kea-subscriptions' import { waitForPlugin } from 'kea-waitfor' +import { windowValuesPlugin } from 'kea-window-values' import { lemonToast } from 'lib/lemon-ui/lemonToast' -import { subscriptionsPlugin } from 'kea-subscriptions' -import { formsPlugin } from 'kea-forms' +import { identifierToHuman } from 'lib/utils' /* Actions for which we don't want to show error alerts, diff --git a/frontend/src/layout/ErrorBoundary/ErrorBoundary.tsx b/frontend/src/layout/ErrorBoundary/ErrorBoundary.tsx index 456b89a8ab65b..78dde9a6d6b3a 100644 --- a/frontend/src/layout/ErrorBoundary/ErrorBoundary.tsx +++ b/frontend/src/layout/ErrorBoundary/ErrorBoundary.tsx @@ -1,8 +1,9 @@ -import { getCurrentHub, ErrorBoundary as SentryErrorBoundary } from '@sentry/react' +import './ErrorBoundary.scss' + +import { ErrorBoundary as SentryErrorBoundary, getCurrentHub } from '@sentry/react' import { HelpButton } from 'lib/components/HelpButton/HelpButton' import { IconArrowDropDown } from 'lib/lemon-ui/icons' import { LemonButton } from 'lib/lemon-ui/LemonButton' -import './ErrorBoundary.scss' export function ErrorBoundary({ children }: { children: React.ReactElement }): JSX.Element { const isSentryInitialized = !!getCurrentHub().getClient() diff --git a/frontend/src/layout/ErrorNetwork.tsx b/frontend/src/layout/ErrorNetwork.tsx index 01473440a0801..a415d1fc8028d 100644 --- a/frontend/src/layout/ErrorNetwork.tsx +++ b/frontend/src/layout/ErrorNetwork.tsx @@ -1,5 +1,5 @@ -import { LemonButton } from 'lib/lemon-ui/LemonButton' import { IconRefresh } from 'lib/lemon-ui/icons' +import { LemonButton } from 'lib/lemon-ui/LemonButton' export function ErrorNetwork(): JSX.Element { return ( diff --git a/frontend/src/layout/ErrorProjectUnavailable.tsx b/frontend/src/layout/ErrorProjectUnavailable.tsx index a3660e42c37cc..29a178c490b05 100644 --- a/frontend/src/layout/ErrorProjectUnavailable.tsx +++ b/frontend/src/layout/ErrorProjectUnavailable.tsx @@ -1,5 +1,6 @@ -import { PageHeader } from 'lib/components/PageHeader' import { useValues } from 'kea' +import { PageHeader } from 'lib/components/PageHeader' + import { organizationLogic } from '../scenes/organizationLogic' export function ErrorProjectUnavailable(): JSX.Element { diff --git a/frontend/src/layout/FeaturePreviews/FeaturePreviewsModal.stories.tsx b/frontend/src/layout/FeaturePreviews/FeaturePreviewsModal.stories.tsx index 45025c5d8132c..8853e4812c90a 100644 --- a/frontend/src/layout/FeaturePreviews/FeaturePreviewsModal.stories.tsx +++ b/frontend/src/layout/FeaturePreviews/FeaturePreviewsModal.stories.tsx @@ -1,9 +1,11 @@ import { Meta, StoryFn, StoryObj } from '@storybook/react' -import { FeaturePreviewsModal as FeaturePreviewsModalComponent } from './FeaturePreviewsModal' -import { setFeatureFlags, useStorybookMocks } from '~/mocks/browser' +import { FeatureFlagKey } from 'lib/constants' import { EarlyAccessFeature } from 'posthog-js' + +import { setFeatureFlags, useStorybookMocks } from '~/mocks/browser' + import { CONSTRAINED_PREVIEWS } from './featurePreviewsLogic' -import { FeatureFlagKey } from 'lib/constants' +import { FeaturePreviewsModal as FeaturePreviewsModalComponent } from './FeaturePreviewsModal' interface StoryProps { earlyAccessFeatures: EarlyAccessFeature[] diff --git a/frontend/src/layout/FeaturePreviews/FeaturePreviewsModal.tsx b/frontend/src/layout/FeaturePreviews/FeaturePreviewsModal.tsx index 2d64c4c5d32e0..5899f59b82d47 100644 --- a/frontend/src/layout/FeaturePreviews/FeaturePreviewsModal.tsx +++ b/frontend/src/layout/FeaturePreviews/FeaturePreviewsModal.tsx @@ -1,9 +1,10 @@ import { LemonButton, LemonDivider, LemonModal, LemonSwitch, LemonTextArea, Link } from '@posthog/lemon-ui' -import { useActions, useValues, useAsyncActions } from 'kea' +import clsx from 'clsx' +import { useActions, useAsyncActions, useValues } from 'kea' import { SpinnerOverlay } from 'lib/lemon-ui/Spinner' import { useLayoutEffect, useState } from 'react' + import { EnrichedEarlyAccessFeature, featurePreviewsLogic } from './featurePreviewsLogic' -import clsx from 'clsx' export function FeaturePreviewsModal({ inline, diff --git a/frontend/src/layout/FeaturePreviews/featurePreviewsLogic.tsx b/frontend/src/layout/FeaturePreviews/featurePreviewsLogic.tsx index 40c2e201be346..1dc54a618c214 100644 --- a/frontend/src/layout/FeaturePreviews/featurePreviewsLogic.tsx +++ b/frontend/src/layout/FeaturePreviews/featurePreviewsLogic.tsx @@ -1,12 +1,13 @@ -import { actions, kea, reducers, path, selectors, connect, listeners } from 'kea' -import { EarlyAccessFeature, posthog } from 'posthog-js' +import { actions, connect, kea, listeners, path, reducers, selectors } from 'kea' import { loaders } from 'kea-loaders' -import { featureFlagLogic } from 'lib/logic/featureFlagLogic' +import { actionToUrl, router, urlToAction } from 'kea-router' import { supportLogic } from 'lib/components/Support/supportLogic' -import { userLogic } from 'scenes/userLogic' import { FEATURE_FLAGS, FeatureFlagKey } from 'lib/constants' +import { featureFlagLogic } from 'lib/logic/featureFlagLogic' +import { EarlyAccessFeature, posthog } from 'posthog-js' +import { userLogic } from 'scenes/userLogic' + import type { featurePreviewsLogicType } from './featurePreviewsLogicType' -import { actionToUrl, router, urlToAction } from 'kea-router' /** Features that can only be toggled if you fall under the `${flagKey}-preview` flag */ export const CONSTRAINED_PREVIEWS: Set = new Set([FEATURE_FLAGS.POSTHOG_3000]) diff --git a/frontend/src/layout/FeaturePreviews/index.ts b/frontend/src/layout/FeaturePreviews/index.ts index 08a91428b164b..6101040e9e9f2 100644 --- a/frontend/src/layout/FeaturePreviews/index.ts +++ b/frontend/src/layout/FeaturePreviews/index.ts @@ -1,2 +1,2 @@ -export { FeaturePreviewsModal } from './FeaturePreviewsModal' export { featurePreviewsLogic } from './featurePreviewsLogic' +export { FeaturePreviewsModal } from './FeaturePreviewsModal' diff --git a/frontend/src/layout/GlobalModals.tsx b/frontend/src/layout/GlobalModals.tsx index b2ae0efd30f0f..e2041d0f72dc8 100644 --- a/frontend/src/layout/GlobalModals.tsx +++ b/frontend/src/layout/GlobalModals.tsx @@ -1,19 +1,19 @@ -import { kea, path, actions, reducers, useActions, useValues } from 'kea' -import { CreateOrganizationModal } from 'scenes/organization/CreateOrganizationModal' -import { CreateProjectModal } from 'scenes/project/CreateProjectModal' - -import type { globalModalsLogicType } from './GlobalModalsType' -import { FeaturePreviewsModal } from './FeaturePreviews' -import { UpgradeModal } from 'scenes/UpgradeModal' import { LemonModal } from '@posthog/lemon-ui' -import { Setup2FA } from 'scenes/authentication/Setup2FA' -import { userLogic } from 'scenes/userLogic' -import { membersLogic } from 'scenes/organization/membersLogic' +import { actions, kea, path, reducers, useActions, useValues } from 'kea' import { FlaggedFeature } from 'lib/components/FlaggedFeature' +import { HedgehogBuddyWithLogic } from 'lib/components/HedgehogBuddy/HedgehogBuddy' import { Prompt } from 'lib/logic/newPrompt/Prompt' +import { Setup2FA } from 'scenes/authentication/Setup2FA' +import { CreateOrganizationModal } from 'scenes/organization/CreateOrganizationModal' +import { membersLogic } from 'scenes/organization/membersLogic' +import { CreateProjectModal } from 'scenes/project/CreateProjectModal' import { inviteLogic } from 'scenes/settings/organization/inviteLogic' import { InviteModal } from 'scenes/settings/organization/InviteModal' -import { HedgehogBuddyWithLogic } from 'lib/components/HedgehogBuddy/HedgehogBuddy' +import { UpgradeModal } from 'scenes/UpgradeModal' +import { userLogic } from 'scenes/userLogic' + +import { FeaturePreviewsModal } from './FeaturePreviews' +import type { globalModalsLogicType } from './GlobalModalsType' export const globalModalsLogic = kea([ path(['layout', 'navigation', 'globalModalsLogic']), diff --git a/frontend/src/layout/navigation-3000/Navigation.stories.tsx b/frontend/src/layout/navigation-3000/Navigation.stories.tsx index 73d7298878007..bc31a2d8079d3 100644 --- a/frontend/src/layout/navigation-3000/Navigation.stories.tsx +++ b/frontend/src/layout/navigation-3000/Navigation.stories.tsx @@ -1,11 +1,12 @@ import { Meta } from '@storybook/react' -import { mswDecorator, setFeatureFlags } from '~/mocks/browser' -import { useEffect } from 'react' import { router } from 'kea-router' -import { urls } from 'scenes/urls' +import { FEATURE_FLAGS } from 'lib/constants' +import { useEffect } from 'react' import { App } from 'scenes/App' +import { urls } from 'scenes/urls' + +import { mswDecorator, setFeatureFlags } from '~/mocks/browser' import { EMPTY_PAGINATED_RESPONSE } from '~/mocks/handlers' -import { FEATURE_FLAGS } from 'lib/constants' const meta: Meta = { title: 'PostHog 3000/Navigation', diff --git a/frontend/src/layout/navigation-3000/Navigation.tsx b/frontend/src/layout/navigation-3000/Navigation.tsx index 3dab2a0c34052..dff2a25ec7ca4 100644 --- a/frontend/src/layout/navigation-3000/Navigation.tsx +++ b/frontend/src/layout/navigation-3000/Navigation.tsx @@ -1,18 +1,20 @@ -import { CommandPalette } from 'lib/components/CommandPalette/CommandPalette' +import './Navigation.scss' + +import clsx from 'clsx' import { useMountedLogic, useValues } from 'kea' +import { CommandPalette } from 'lib/components/CommandPalette/CommandPalette' +import { FlaggedFeature } from 'lib/components/FlaggedFeature' +import { FEATURE_FLAGS } from 'lib/constants' import { ReactNode, useEffect } from 'react' +import { SceneConfig } from 'scenes/sceneTypes' + import { Breadcrumbs } from './components/Breadcrumbs' +import { MinimalNavigation } from './components/MinimalNavigation' import { Navbar } from './components/Navbar' import { Sidebar } from './components/Sidebar' -import './Navigation.scss' -import { themeLogic } from './themeLogic' import { navigation3000Logic } from './navigationLogic' -import clsx from 'clsx' -import { SceneConfig } from 'scenes/sceneTypes' -import { FlaggedFeature } from 'lib/components/FlaggedFeature' -import { FEATURE_FLAGS } from 'lib/constants' import { SidePanel } from './sidepanel/SidePanel' -import { MinimalNavigation } from './components/MinimalNavigation' +import { themeLogic } from './themeLogic' export function Navigation({ children, diff --git a/frontend/src/layout/navigation-3000/components/Breadcrumbs.scss b/frontend/src/layout/navigation-3000/components/Breadcrumbs.scss index c143a10085e9a..0cf4e5a260384 100644 --- a/frontend/src/layout/navigation-3000/components/Breadcrumbs.scss +++ b/frontend/src/layout/navigation-3000/components/Breadcrumbs.scss @@ -54,6 +54,7 @@ overflow: hidden; height: calc(1.2em * (1 - var(--breadcrumbs-compaction-rate))); box-sizing: content-box; + font-family: var(--font-sans) !important; > * { position: absolute; diff --git a/frontend/src/layout/navigation-3000/components/Breadcrumbs.tsx b/frontend/src/layout/navigation-3000/components/Breadcrumbs.tsx index cbbcc6403ae48..881c7139c6b9a 100644 --- a/frontend/src/layout/navigation-3000/components/Breadcrumbs.tsx +++ b/frontend/src/layout/navigation-3000/components/Breadcrumbs.tsx @@ -1,14 +1,16 @@ -import React, { useLayoutEffect, useState } from 'react' +import './Breadcrumbs.scss' + +import { LemonSkeleton } from '@posthog/lemon-ui' +import clsx from 'clsx' import { useActions, useValues } from 'kea' +import { EditableField } from 'lib/components/EditableField/EditableField' import { IconArrowDropDown } from 'lib/lemon-ui/icons' import { Link } from 'lib/lemon-ui/Link' -import './Breadcrumbs.scss' -import { FinalizedBreadcrumb } from '~/types' -import clsx from 'clsx' import { Popover } from 'lib/lemon-ui/Popover/Popover' +import React, { useLayoutEffect, useState } from 'react' + import { breadcrumbsLogic } from '~/layout/navigation/Breadcrumbs/breadcrumbsLogic' -import { LemonSkeleton } from '@posthog/lemon-ui' -import { EditableField } from 'lib/components/EditableField/EditableField' +import { FinalizedBreadcrumb } from '~/types' const COMPACTION_DISTANCE = 44 diff --git a/frontend/src/layout/navigation-3000/components/KeyboardShortcut.scss b/frontend/src/layout/navigation-3000/components/KeyboardShortcut.scss index 29d1076ffe7aa..1620ab43cb0ab 100644 --- a/frontend/src/layout/navigation-3000/components/KeyboardShortcut.scss +++ b/frontend/src/layout/navigation-3000/components/KeyboardShortcut.scss @@ -3,28 +3,25 @@ } .KeyboardShortcut__key { - display: inline-flex; align-items: center; - justify-content: center; - height: 1.25rem; - min-width: 1.25rem; - padding: 0 0.1875rem; + background: var(--accent-3000); border-radius: 0.125rem; border-width: 1px; - background: var(--accent-3000); color: var(--default); + display: inline-flex; + height: 1.25rem; + justify-content: center; + min-width: 1.25rem; + padding: 0 0.1875rem; text-transform: capitalize; .posthog-3000 & { - text-transform: uppercase; - border-radius: 0.25rem; border-bottom-width: 2px; + border-color: var(--secondary-3000-button-border-hover); + border-radius: 0.25rem; font-size: 0.625rem; padding: 0.125rem 0.25rem; - } - - .posthog-3000[theme='dark'] & { - border-color: var(--muted-3000); + text-transform: uppercase; } .KeyboardShortcut--muted > & { diff --git a/frontend/src/layout/navigation-3000/components/KeyboardShortcut.tsx b/frontend/src/layout/navigation-3000/components/KeyboardShortcut.tsx index a636defcd78dd..d6d5b42d7a91d 100644 --- a/frontend/src/layout/navigation-3000/components/KeyboardShortcut.tsx +++ b/frontend/src/layout/navigation-3000/components/KeyboardShortcut.tsx @@ -1,7 +1,9 @@ -import { isMac } from 'lib/utils' -import { HotKeyOrModifier } from '~/types' import './KeyboardShortcut.scss' + import clsx from 'clsx' +import { isMac } from 'lib/utils' + +import { HotKeyOrModifier } from '~/types' const IS_MAC = isMac() const KEY_TO_SYMBOL: Partial> = { @@ -34,11 +36,11 @@ export function KeyboardShortcut({ muted, ...keys }: KeyboardShortcutProps): JSX ) as HotKeyOrModifier[] return ( - + {sortedKeys.map((key) => ( - - {KEY_TO_SYMBOL[key] || key} - + {KEY_TO_SYMBOL[key] || key} ))} ) diff --git a/frontend/src/layout/navigation-3000/components/MinimalNavigation.tsx b/frontend/src/layout/navigation-3000/components/MinimalNavigation.tsx index 2bd7486738b47..1161a4dadc1c8 100644 --- a/frontend/src/layout/navigation-3000/components/MinimalNavigation.tsx +++ b/frontend/src/layout/navigation-3000/components/MinimalNavigation.tsx @@ -1,13 +1,14 @@ +import { IconLogomark } from '@posthog/icons' import { LemonButton, Lettermark, Popover, ProfilePicture } from '@posthog/lemon-ui' -import { ProjectSwitcherOverlay } from '~/layout/navigation/ProjectSwitcher' -import { SitePopoverOverlay } from '~/layout/navigation/TopBar/SitePopover' -import { useValues, useActions } from 'kea' +import { useActions, useValues } from 'kea' +import { organizationLogic } from 'scenes/organizationLogic' import { teamLogic } from 'scenes/teamLogic' -import { navigationLogic } from '~/layout/navigation/navigationLogic' -import { userLogic } from 'scenes/userLogic' -import { IconLogomark } from '@posthog/icons' import { urls } from 'scenes/urls' -import { organizationLogic } from 'scenes/organizationLogic' +import { userLogic } from 'scenes/userLogic' + +import { navigationLogic } from '~/layout/navigation/navigationLogic' +import { ProjectSwitcherOverlay } from '~/layout/navigation/ProjectSwitcher' +import { SitePopoverOverlay } from '~/layout/navigation/TopBar/SitePopover' export function MinimalNavigation(): JSX.Element { const { user } = useValues(userLogic) diff --git a/frontend/src/layout/navigation-3000/components/Navbar.tsx b/frontend/src/layout/navigation-3000/components/Navbar.tsx index ac9898f6063a9..33f73e869b6fa 100644 --- a/frontend/src/layout/navigation-3000/components/Navbar.tsx +++ b/frontend/src/layout/navigation-3000/components/Navbar.tsx @@ -1,19 +1,39 @@ +import { IconAsterisk, IconDay, IconGear, IconNight, IconSearch } from '@posthog/icons' import { LemonBadge } from '@posthog/lemon-ui' import { useActions, useValues } from 'kea' -import { IconGear, IconDay, IconNight, IconAsterisk } from '@posthog/icons' +import { commandBarLogic } from 'lib/components/CommandBar/commandBarLogic' +import { Resizer } from 'lib/components/Resizer/Resizer' +import { useFeatureFlag } from 'lib/hooks/useFeatureFlag' import { Popover } from 'lib/lemon-ui/Popover' import { ProfilePicture } from 'lib/lemon-ui/ProfilePicture' +import { featureFlagLogic } from 'lib/logic/featureFlagLogic' +import { useRef } from 'react' import { Scene } from 'scenes/sceneTypes' +import { urls } from 'scenes/urls' import { userLogic } from 'scenes/userLogic' + import { navigationLogic } from '~/layout/navigation/navigationLogic' import { SitePopoverOverlay } from '~/layout/navigation/TopBar/SitePopover' +import { KeyboardShortcut } from '~/layout/navigation-3000/components/KeyboardShortcut' + import { navigation3000Logic } from '../navigationLogic' import { themeLogic } from '../themeLogic' import { NavbarButton } from './NavbarButton' -import { urls } from 'scenes/urls' -import { featureFlagLogic } from 'lib/logic/featureFlagLogic' -import { Resizer } from 'lib/components/Resizer/Resizer' -import { useRef } from 'react' + +export function ThemeIcon(): JSX.Element { + const { isDarkModeOn, isThemeSyncedWithSystem } = useValues(themeLogic) + + const activeThemeIcon = isDarkModeOn ? : + + return isThemeSyncedWithSystem ? ( +
+ {activeThemeIcon} + } /> +
+ ) : ( + activeThemeIcon + ) +} export function Navbar(): JSX.Element { const { user } = useValues(userLogic) @@ -21,14 +41,13 @@ export function Navbar(): JSX.Element { const { closeSitePopover, toggleSitePopover } = useActions(navigationLogic) const { isSidebarShown, activeNavbarItemId, navbarItems } = useValues(navigation3000Logic) const { showSidebar, hideSidebar, toggleNavCollapsed } = useActions(navigation3000Logic) - const { isDarkModeOn, darkModeSavedPreference, darkModeSystemPreference, isThemeSyncedWithSystem } = - useValues(themeLogic) + const { darkModeSavedPreference, darkModeSystemPreference } = useValues(themeLogic) const { toggleTheme } = useActions(themeLogic) const { featureFlags } = useValues(featureFlagLogic) - - const activeThemeIcon = isDarkModeOn ? : + const { toggleSearchBar } = useActions(commandBarLogic) const containerRef = useRef(null) + const isUsingNewNav = useFeatureFlag('POSTHOG_3000_NAV') return (