Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
nermalcat69 authored Dec 29, 2024
2 parents dbd07b6 + 6c58e55 commit d0db99b
Show file tree
Hide file tree
Showing 109 changed files with 2,764 additions and 603 deletions.
17 changes: 11 additions & 6 deletions ee/clickhouse/views/experiment_saved_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
from posthog.api.routing import TeamAndOrgViewSetMixin
from posthog.api.shared import UserBasicSerializer
from posthog.models.experiment import ExperimentSavedMetric, ExperimentToSavedMetric
from posthog.schema import FunnelsQuery, TrendsQuery
from posthog.schema import ExperimentFunnelsQuery, ExperimentTrendsQuery


class ExperimentToSavedMetricSerializer(serializers.ModelSerializer):
query = serializers.JSONField(source="saved_metric.query", read_only=True)
name = serializers.CharField(source="saved_metric.name", read_only=True)

class Meta:
model = ExperimentToSavedMetric
fields = [
Expand All @@ -18,6 +21,8 @@ class Meta:
"saved_metric",
"metadata",
"created_at",
"query",
"name",
]
read_only_fields = [
"id",
Expand Down Expand Up @@ -52,15 +57,15 @@ def validate_query(self, value):

metric_query = value

if metric_query.get("kind") not in ["TrendsQuery", "FunnelsQuery"]:
raise ValidationError("Metric query kind must be 'TrendsQuery' or 'FunnelsQuery'")
if metric_query.get("kind") not in ["ExperimentTrendsQuery", "ExperimentFunnelsQuery"]:
raise ValidationError("Metric query kind must be 'ExperimentTrendsQuery' or 'ExperimentFunnelsQuery'")

# pydantic models are used to validate the query
try:
if metric_query["kind"] == "TrendsQuery":
TrendsQuery(**metric_query)
if metric_query["kind"] == "ExperimentTrendsQuery":
ExperimentTrendsQuery(**metric_query)
else:
FunnelsQuery(**metric_query)
ExperimentFunnelsQuery(**metric_query)
except pydantic.ValidationError as e:
raise ValidationError(str(e.errors())) from e

Expand Down
4 changes: 1 addition & 3 deletions ee/clickhouse/views/experiments.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,7 @@ class ExperimentSerializer(serializers.ModelSerializer):
queryset=ExperimentHoldout.objects.all(), source="holdout", required=False, allow_null=True
)
saved_metrics = ExperimentToSavedMetricSerializer(many=True, source="experimenttosavedmetric_set", read_only=True)
saved_metrics_ids = serializers.ListField(
child=serializers.JSONField(), write_only=True, required=False, allow_null=True
)
saved_metrics_ids = serializers.ListField(child=serializers.JSONField(), required=False, allow_null=True)

class Meta:
model = Experiment
Expand Down
29 changes: 24 additions & 5 deletions ee/clickhouse/views/test/test_clickhouse_experiments.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,13 @@ def test_saved_metrics(self):
{
"name": "Test Experiment saved metric",
"description": "Test description",
"query": {"kind": "TrendsQuery", "series": [{"kind": "EventsNode", "event": "$pageview"}]},
"query": {
"kind": "ExperimentTrendsQuery",
"count_query": {
"kind": "TrendsQuery",
"series": [{"kind": "EventsNode", "event": "$pageview"}],
},
},
},
)

Expand All @@ -380,7 +386,10 @@ def test_saved_metrics(self):
self.assertEqual(response.json()["description"], "Test description")
self.assertEqual(
response.json()["query"],
{"kind": "TrendsQuery", "series": [{"kind": "EventsNode", "event": "$pageview"}]},
{
"kind": "ExperimentTrendsQuery",
"count_query": {"kind": "TrendsQuery", "series": [{"kind": "EventsNode", "event": "$pageview"}]},
},
)
self.assertEqual(response.json()["created_by"]["id"], self.user.pk)

Expand Down Expand Up @@ -418,7 +427,11 @@ def test_saved_metrics(self):
saved_metric = Experiment.objects.get(pk=exp_id).saved_metrics.first()
self.assertEqual(saved_metric.id, saved_metric_id)
self.assertEqual(
saved_metric.query, {"kind": "TrendsQuery", "series": [{"kind": "EventsNode", "event": "$pageview"}]}
saved_metric.query,
{
"kind": "ExperimentTrendsQuery",
"count_query": {"kind": "TrendsQuery", "series": [{"kind": "EventsNode", "event": "$pageview"}]},
},
)

# Now try updating experiment with new saved metric
Expand All @@ -427,7 +440,10 @@ def test_saved_metrics(self):
{
"name": "Test Experiment saved metric 2",
"description": "Test description 2",
"query": {"kind": "TrendsQuery", "series": [{"kind": "EventsNode", "event": "$pageleave"}]},
"query": {
"kind": "ExperimentTrendsQuery",
"count_query": {"kind": "TrendsQuery", "series": [{"kind": "EventsNode", "event": "$pageleave"}]},
},
},
)

Expand Down Expand Up @@ -513,7 +529,10 @@ def test_validate_saved_metrics_payload(self):
{
"name": "Test Experiment saved metric",
"description": "Test description",
"query": {"kind": "TrendsQuery", "series": [{"kind": "EventsNode", "event": "$pageview"}]},
"query": {
"kind": "ExperimentTrendsQuery",
"count_query": {"kind": "TrendsQuery", "series": [{"kind": "EventsNode", "event": "$pageview"}]},
},
},
)

Expand Down
63 changes: 48 additions & 15 deletions ee/clickhouse/views/test/test_experiment_saved_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ def test_validation_of_query_metric(self):
)

self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(response.json()["detail"], "Metric query kind must be 'TrendsQuery' or 'FunnelsQuery'")
self.assertEqual(
response.json()["detail"], "Metric query kind must be 'ExperimentTrendsQuery' or 'ExperimentFunnelsQuery'"
)

response = self.client.post(
f"/api/projects/{self.team.id}/experiment_saved_metrics/",
Expand All @@ -47,40 +49,46 @@ def test_validation_of_query_metric(self):
)

self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(response.json()["detail"], "Metric query kind must be 'TrendsQuery' or 'FunnelsQuery'")
self.assertEqual(
response.json()["detail"], "Metric query kind must be 'ExperimentTrendsQuery' or 'ExperimentFunnelsQuery'"
)

response = self.client.post(
f"/api/projects/{self.team.id}/experiment_saved_metrics/",
data={
"name": "Test Experiment saved metric",
"description": "Test description",
"query": {"kind": "ExperimentTrendsQuery"},
"query": {"kind": "TrendsQuery"},
},
format="json",
)

self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(response.json()["detail"], "Metric query kind must be 'TrendsQuery' or 'FunnelsQuery'")
self.assertEqual(
response.json()["detail"], "Metric query kind must be 'ExperimentTrendsQuery' or 'ExperimentFunnelsQuery'"
)

response = self.client.post(
f"/api/projects/{self.team.id}/experiment_saved_metrics/",
data={
"name": "Test Experiment saved metric",
"description": "Test description",
"query": {"kind": "TrendsQuery"},
"query": {"kind": "ExperimentTrendsQuery"},
},
format="json",
)

self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertTrue("'loc': ('series',), 'msg': 'Field required'" in response.json()["detail"])
self.assertTrue("'loc': ('count_query',), 'msg': 'Field required'" in response.json()["detail"])

response = self.client.post(
f"/api/projects/{self.team.id}/experiment_saved_metrics/",
data={
"name": "Test Experiment saved metric",
"description": "Test description",
"query": {"kind": "TrendsQuery", "series": [{"kind": "EventsNode", "event": "$pageview"}]},
"query": {
"kind": "ExperimentTrendsQuery",
"count_query": {"kind": "TrendsQuery", "series": [{"kind": "EventsNode", "event": "$pageview"}]},
},
},
format="json",
)
Expand All @@ -93,7 +101,13 @@ def test_create_update_experiment_saved_metrics(self) -> None:
data={
"name": "Test Experiment saved metric",
"description": "Test description",
"query": {"kind": "TrendsQuery", "series": [{"kind": "EventsNode", "event": "$pageview"}]},
"query": {
"kind": "ExperimentTrendsQuery",
"count_query": {
"kind": "TrendsQuery",
"series": [{"kind": "EventsNode", "event": "$pageview"}],
},
},
},
format="json",
)
Expand All @@ -104,7 +118,10 @@ def test_create_update_experiment_saved_metrics(self) -> None:
self.assertEqual(response.json()["description"], "Test description")
self.assertEqual(
response.json()["query"],
{"kind": "TrendsQuery", "series": [{"kind": "EventsNode", "event": "$pageview"}]},
{
"kind": "ExperimentTrendsQuery",
"count_query": {"kind": "TrendsQuery", "series": [{"kind": "EventsNode", "event": "$pageview"}]},
},
)
self.assertEqual(response.json()["created_by"]["id"], self.user.pk)

Expand Down Expand Up @@ -142,7 +159,11 @@ def test_create_update_experiment_saved_metrics(self) -> None:
saved_metric = Experiment.objects.get(pk=exp_id).saved_metrics.first()
self.assertEqual(saved_metric.id, saved_metric_id)
self.assertEqual(
saved_metric.query, {"kind": "TrendsQuery", "series": [{"kind": "EventsNode", "event": "$pageview"}]}
saved_metric.query,
{
"kind": "ExperimentTrendsQuery",
"count_query": {"kind": "TrendsQuery", "series": [{"kind": "EventsNode", "event": "$pageview"}]},
},
)

# Now try updating saved metric
Expand All @@ -151,15 +172,21 @@ def test_create_update_experiment_saved_metrics(self) -> None:
{
"name": "Test Experiment saved metric 2",
"description": "Test description 2",
"query": {"kind": "TrendsQuery", "series": [{"kind": "EventsNode", "event": "$pageleave"}]},
"query": {
"kind": "ExperimentTrendsQuery",
"count_query": {"kind": "TrendsQuery", "series": [{"kind": "EventsNode", "event": "$pageleave"}]},
},
},
)

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json()["name"], "Test Experiment saved metric 2")
self.assertEqual(
response.json()["query"],
{"kind": "TrendsQuery", "series": [{"kind": "EventsNode", "event": "$pageleave"}]},
{
"kind": "ExperimentTrendsQuery",
"count_query": {"kind": "TrendsQuery", "series": [{"kind": "EventsNode", "event": "$pageleave"}]},
},
)

# make sure experiment in question was updated as well
Expand All @@ -168,7 +195,10 @@ def test_create_update_experiment_saved_metrics(self) -> None:
self.assertEqual(saved_metric.id, saved_metric_id)
self.assertEqual(
saved_metric.query,
{"kind": "TrendsQuery", "series": [{"kind": "EventsNode", "event": "$pageleave"}]},
{
"kind": "ExperimentTrendsQuery",
"count_query": {"kind": "TrendsQuery", "series": [{"kind": "EventsNode", "event": "$pageleave"}]},
},
)
self.assertEqual(saved_metric.name, "Test Experiment saved metric 2")
self.assertEqual(saved_metric.description, "Test description 2")
Expand All @@ -186,7 +216,10 @@ def test_invalid_create(self):
f"/api/projects/{self.team.id}/experiment_saved_metrics/",
data={
"name": None, # invalid
"query": {"kind": "TrendsQuery", "series": [{"kind": "EventsNode", "event": "$pageview"}]},
"query": {
"kind": "ExperimentTrendsQuery",
"count_query": {"kind": "TrendsQuery", "series": [{"kind": "EventsNode", "event": "$pageview"}]},
},
},
format="json",
)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { ActivityScope, AvailableFeature } from '~/types'

import { SidePanelPaneHeader } from '../../components/SidePanelPaneHeader'
import { SidePanelActivityMetalytics } from './SidePanelActivityMetalytics'
import { SidePanelActivitySubscriptions } from './SidePanelActivitySubscriptions'

const SCROLL_TRIGGER_OFFSET = 100

Expand Down Expand Up @@ -152,6 +153,14 @@ export const SidePanelActivity = (): JSX.Element => {
},
]
: []),
...(featureFlags[FEATURE_FLAGS.CDP_ACTIVITY_LOG_NOTIFICATIONS]
? [
{
key: SidePanelActivityTab.Subscriptions,
label: 'Subscriptions',
},
]
: []),
]}
/>
</div>
Expand Down Expand Up @@ -280,6 +289,8 @@ export const SidePanelActivity = (): JSX.Element => {
</>
) : activeTab === SidePanelActivityTab.Metalytics ? (
<SidePanelActivityMetalytics />
) : activeTab === SidePanelActivityTab.Subscriptions ? (
<SidePanelActivitySubscriptions />
) : null}
</ScrollableShadows>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { LinkedHogFunctions } from 'scenes/pipeline/hogfunctions/list/LinkedHogFunctions'

export function SidePanelActivitySubscriptions(): JSX.Element {
return (
<div className="space-y-4 ">
<p>Get notified of your team's activity</p>

<LinkedHogFunctions
type="internal_destination"
subTemplateId="activity-log"
filters={{
events: [
{
id: `$activity_log_entry_created`,
type: 'events',
},
],
}}
/>
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export enum SidePanelActivityTab {
Unread = 'unread',
All = 'all',
Metalytics = 'metalytics',
Subscriptions = 'subscriptions',
}

export const sidePanelActivityLogic = kea<sidePanelActivityLogicType>([
Expand All @@ -65,6 +66,7 @@ export const sidePanelActivityLogic = kea<sidePanelActivityLogicType>([
reducers({
activeTab: [
SidePanelActivityTab.Unread as SidePanelActivityTab,
{ persist: true },
{
setActiveTab: (_, { tab }) => tab,
},
Expand Down
17 changes: 10 additions & 7 deletions frontend/src/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import {
GroupListParams,
HogFunctionIconResponse,
HogFunctionStatus,
HogFunctionSubTemplateIdType,
HogFunctionTemplateType,
HogFunctionType,
HogFunctionTypeType,
Expand Down Expand Up @@ -1824,13 +1825,15 @@ const api = {
): Promise<AppMetricsTotalsV2Response> {
return await new ApiRequest().hogFunction(id).withAction('metrics/totals').withQueryString(params).get()
},
async listTemplates(
type?: HogFunctionTypeType | HogFunctionTypeType[]
): Promise<PaginatedResponse<HogFunctionTemplateType>> {
return new ApiRequest()
.hogFunctionTemplates()
.withQueryString(Array.isArray(type) ? { types: type.join(',') } : { type: type ?? 'destination' })
.get()
async listTemplates(params: {
types: HogFunctionTypeType[]
sub_template_id?: HogFunctionSubTemplateIdType
}): Promise<PaginatedResponse<HogFunctionTemplateType>> {
const finalParams = {
...params,
types: params.types.join(','),
}
return new ApiRequest().hogFunctionTemplates().withQueryString(finalParams).get()
},
async getTemplate(id: HogFunctionTemplateType['id']): Promise<HogFunctionTemplateType> {
return await new ApiRequest().hogFunctionTemplate(id).get()
Expand Down
Loading

0 comments on commit d0db99b

Please sign in to comment.