diff --git a/frontend/src/scenes/session-recordings/apm/playerInspector/ItemPerformanceEvent.tsx b/frontend/src/scenes/session-recordings/apm/playerInspector/ItemPerformanceEvent.tsx index 9b1d2f1a1e64f..84097a1eb27b2 100644 --- a/frontend/src/scenes/session-recordings/apm/playerInspector/ItemPerformanceEvent.tsx +++ b/frontend/src/scenes/session-recordings/apm/playerInspector/ItemPerformanceEvent.tsx @@ -82,7 +82,7 @@ function renderTimeBenchmark(milliseconds: number): JSX.Element { } function emptyPayloadMessage( - payloadCaptureIsEnabled: undefined | boolean, + payloadCaptureIsEnabled: boolean | undefined | null, item: PerformanceEvent, label: 'Request' | 'Response' ): JSX.Element | string { diff --git a/frontend/src/scenes/settings/project/SessionRecordingSettings.tsx b/frontend/src/scenes/settings/project/SessionRecordingSettings.tsx index 2402c6592a834..297ac4feb0be4 100644 --- a/frontend/src/scenes/settings/project/SessionRecordingSettings.tsx +++ b/frontend/src/scenes/settings/project/SessionRecordingSettings.tsx @@ -47,10 +47,8 @@ function LogCaptureSettings(): JSX.Element { }} label="Capture console logs" bordered - checked={currentTeam?.session_recording_opt_in ? !!currentTeam?.capture_console_log_opt_in : false} - disabledReason={ - !currentTeam?.session_recording_opt_in ? 'session recording must be enabled' : undefined - } + checked={!!currentTeam?.capture_console_log_opt_in} + disabledReason={!currentTeam?.session_recording_opt_in ? 'Session replay must be enabled' : undefined} /> ) @@ -89,9 +87,7 @@ function CanvasCaptureSettings(): JSX.Element | null { checked={ currentTeam?.session_replay_config ? !!currentTeam?.session_replay_config?.record_canvas : false } - disabledReason={ - !currentTeam?.session_recording_opt_in ? 'session recording must be enabled' : undefined - } + disabledReason={!currentTeam?.session_recording_opt_in ? 'Session replay must be enabled' : undefined} /> ) @@ -134,10 +130,8 @@ export function NetworkCaptureSettings(): JSX.Element { }} label="Capture network performance" bordered - checked={currentTeam?.session_recording_opt_in ? !!currentTeam?.capture_performance_opt_in : false} - disabledReason={ - !currentTeam?.session_recording_opt_in ? 'session recording must be enabled' : undefined - } + checked={!!currentTeam?.capture_performance_opt_in} + disabledReason={!currentTeam?.session_recording_opt_in ? 'Session replay must be enabled' : undefined} />
@@ -676,8 +670,6 @@ export function ReplayGeneral(): JSX.Element { // when switching replay on or off, // we set defaults for some of the other settings session_recording_opt_in: checked, - capture_console_log_opt_in: checked, - capture_performance_opt_in: checked, }) }} label="Record user sessions" diff --git a/frontend/src/types.ts b/frontend/src/types.ts index d66b0beb1e788..4af16fab3a6ba 100644 --- a/frontend/src/types.ts +++ b/frontend/src/types.ts @@ -475,8 +475,9 @@ export interface TeamType extends TeamBasicType { slack_incoming_webhook: string autocapture_opt_out: boolean session_recording_opt_in: boolean - capture_console_log_opt_in: boolean - capture_performance_opt_in: boolean + // These fields in the database accept null values and were previously set to NULL by default + capture_console_log_opt_in: boolean | null + capture_performance_opt_in: boolean | null // a string representation of the decimal value between 0 and 1 session_recording_sample_rate: string session_recording_minimum_duration_milliseconds: number | null diff --git a/latest_migrations.manifest b/latest_migrations.manifest index 5f32a0ea3f522..e92cd61fc6623 100644 --- a/latest_migrations.manifest +++ b/latest_migrations.manifest @@ -5,7 +5,7 @@ contenttypes: 0002_remove_content_type_name ee: 0016_rolemembership_organization_member otp_static: 0002_throttling otp_totp: 0002_auto_20190420_0723 -posthog: 0461_alter_externaldatasource_source_type +posthog: 0462_change_replay_team_setting_defaults sessions: 0001_initial social_django: 0010_uid_db_index two_factor: 0007_auto_20201201_1019 diff --git a/posthog/api/test/test_decide.py b/posthog/api/test/test_decide.py index e1fac07364eaf..0395cbce3717d 100644 --- a/posthog/api/test/test_decide.py +++ b/posthog/api/test/test_decide.py @@ -160,7 +160,7 @@ def test_user_session_recording_opt_in(self, *args): assert response["sessionRecording"] == { "endpoint": "/s/", "recorderVersion": "v2", - "consoleLogRecordingEnabled": False, + "consoleLogRecordingEnabled": True, "sampleRate": None, "linkedFlag": None, "minimumDurationMilliseconds": None, @@ -189,12 +189,12 @@ def test_user_console_log_opt_in(self, *args): def test_user_performance_opt_in(self, *args): # :TRICKY: Test for regression around caching response = self._post_decide().json() - self.assertEqual(response["capturePerformance"], False) + self.assertEqual(response["capturePerformance"], {"network_timing": True, "web_vitals": False}) - self._update_team({"capture_performance_opt_in": True}) + self._update_team({"capture_performance_opt_in": False}) response = self._post_decide().json() - self.assertEqual(response["capturePerformance"], {"network_timing": True, "web_vitals": False}) + self.assertEqual(response["capturePerformance"], False) def test_session_recording_sample_rate(self, *args): # :TRICKY: Test for regression around caching @@ -376,14 +376,14 @@ def test_exception_autocapture_opt_in(self, *args): def test_web_vitals_autocapture_opt_in(self, *args): response = self._post_decide().json() - self.assertEqual(response["capturePerformance"], False) + self.assertEqual(response["capturePerformance"], {"web_vitals": False, "network_timing": True}) self._update_team({"autocapture_web_vitals_opt_in": True}) response = self._post_decide().json() self.assertEqual( response["capturePerformance"], - {"web_vitals": True, "network_timing": False}, + {"web_vitals": True, "network_timing": True}, ) def test_user_session_recording_opt_in_wildcard_domain(self, *args): @@ -402,7 +402,7 @@ def test_user_session_recording_opt_in_wildcard_domain(self, *args): assert response["sessionRecording"] == { "endpoint": "/s/", "recorderVersion": "v2", - "consoleLogRecordingEnabled": False, + "consoleLogRecordingEnabled": True, "sampleRate": None, "linkedFlag": None, "minimumDurationMilliseconds": None, @@ -429,7 +429,7 @@ def test_user_session_recording_evil_site(self, *args): assert response["sessionRecording"] == { "endpoint": "/s/", "recorderVersion": "v2", - "consoleLogRecordingEnabled": False, + "consoleLogRecordingEnabled": True, "sampleRate": None, "linkedFlag": None, "minimumDurationMilliseconds": None, @@ -463,7 +463,7 @@ def test_user_session_recording_allowed_when_no_permitted_domains_are_set(self, assert response["sessionRecording"] == { "endpoint": "/s/", "recorderVersion": "v2", - "consoleLogRecordingEnabled": False, + "consoleLogRecordingEnabled": True, "sampleRate": None, "linkedFlag": None, "minimumDurationMilliseconds": None, @@ -477,7 +477,7 @@ def test_user_session_recording_allowed_for_android(self, *args) -> None: assert response["sessionRecording"] == { "endpoint": "/s/", "recorderVersion": "v2", - "consoleLogRecordingEnabled": False, + "consoleLogRecordingEnabled": True, "sampleRate": None, "linkedFlag": None, "minimumDurationMilliseconds": None, @@ -491,7 +491,7 @@ def test_user_session_recording_allowed_for_ios(self, *args) -> None: assert response["sessionRecording"] == { "endpoint": "/s/", "recorderVersion": "v2", - "consoleLogRecordingEnabled": False, + "consoleLogRecordingEnabled": True, "sampleRate": None, "linkedFlag": None, "minimumDurationMilliseconds": None, @@ -510,7 +510,7 @@ def test_user_session_recording_allowed_when_permitted_domains_are_not_http_base assert response["sessionRecording"] == { "endpoint": "/s/", "recorderVersion": "v2", - "consoleLogRecordingEnabled": False, + "consoleLogRecordingEnabled": True, "sampleRate": None, "linkedFlag": None, "minimumDurationMilliseconds": None, diff --git a/posthog/migrations/0462_change_replay_team_setting_defaults.py b/posthog/migrations/0462_change_replay_team_setting_defaults.py new file mode 100644 index 0000000000000..d144176cf4994 --- /dev/null +++ b/posthog/migrations/0462_change_replay_team_setting_defaults.py @@ -0,0 +1,22 @@ +# Generated by Django 4.2.14 on 2024-08-28 08:55 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("posthog", "0461_alter_externaldatasource_source_type"), + ] + + operations = [ + migrations.AlterField( + model_name="team", + name="capture_console_log_opt_in", + field=models.BooleanField(blank=True, default=True, null=True), + ), + migrations.AlterField( + model_name="team", + name="capture_performance_opt_in", + field=models.BooleanField(blank=True, default=True, null=True), + ), + ] diff --git a/posthog/models/team/team.py b/posthog/models/team/team.py index bcb0b236c75d4..10e658022f386 100644 --- a/posthog/models/team/team.py +++ b/posthog/models/team/team.py @@ -231,8 +231,8 @@ class Meta: session_recording_linked_flag = models.JSONField(null=True, blank=True) session_recording_network_payload_capture_config = models.JSONField(null=True, blank=True) session_replay_config = models.JSONField(null=True, blank=True) - capture_console_log_opt_in = models.BooleanField(null=True, blank=True) - capture_performance_opt_in = models.BooleanField(null=True, blank=True) + capture_console_log_opt_in = models.BooleanField(null=True, blank=True, default=True) + capture_performance_opt_in = models.BooleanField(null=True, blank=True, default=True) surveys_opt_in = models.BooleanField(null=True, blank=True) heatmaps_opt_in = models.BooleanField(null=True, blank=True) session_recording_version = models.CharField(null=True, blank=True, max_length=24)