Skip to content

Commit

Permalink
feat(hogql): Format actors modal date labels (#21069)
Browse files Browse the repository at this point in the history
  • Loading branch information
webjunkie authored Mar 24, 2024
1 parent f2c2563 commit 37f3ff3
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 41 deletions.
10 changes: 10 additions & 0 deletions frontend/src/queries/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -949,6 +949,10 @@
},
"type": "object"
},
"DatetimeDay": {
"format": "date-time",
"type": "string"
},
"Day": {
"type": "integer"
},
Expand Down Expand Up @@ -2788,6 +2792,9 @@
{
"type": "string"
},
{
"$ref": "#/definitions/DatetimeDay"
},
{
"$ref": "#/definitions/Day"
}
Expand Down Expand Up @@ -3839,6 +3846,9 @@
{
"type": "string"
},
{
"$ref": "#/definitions/DatetimeDay"
},
{
"$ref": "#/definitions/Day"
}
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/queries/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1179,9 +1179,13 @@ export interface FunnelCorrelationQuery {
response?: FunnelCorrelationResponse
}

/** @format date-time */
export type DatetimeDay = string

export type BreakdownValueInt = integer
export interface InsightActorsQueryOptionsResponse {
day?: { label: string; value: string | Day }[]
// eslint-disable-next-line @typescript-eslint/no-duplicate-type-constituents
day?: { label: string; value: string | DatetimeDay | Day }[]
status?: { label: string; value: string }[]
interval?: {
label: string
Expand Down
18 changes: 18 additions & 0 deletions posthog/api/test/dashboards/__snapshots__/test_dashboard.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -2762,6 +2762,24 @@
5 /* ... */) /*controller='project_dashboards-list',route='api/projects/%28%3FP%3Cparent_lookup_team_id%3E%5B%5E/.%5D%2B%29/dashboards/%3F%24'*/
'''
# ---
# name: TestDashboard.test_listing_dashboards_is_not_nplus1.57
'''
SELECT "posthog_sharingconfiguration"."id",
"posthog_sharingconfiguration"."team_id",
"posthog_sharingconfiguration"."dashboard_id",
"posthog_sharingconfiguration"."insight_id",
"posthog_sharingconfiguration"."recording_id",
"posthog_sharingconfiguration"."created_at",
"posthog_sharingconfiguration"."enabled",
"posthog_sharingconfiguration"."access_token"
FROM "posthog_sharingconfiguration"
WHERE "posthog_sharingconfiguration"."dashboard_id" IN (1,
2,
3,
4,
5 /* ... */) /*controller='project_dashboards-list',route='api/projects/%28%3FP%3Cparent_lookup_team_id%3E%5B%5E/.%5D%2B%29/dashboards/%3F%24'*/
'''
# ---
# name: TestDashboard.test_listing_dashboards_is_not_nplus1.6
'''
SELECT "posthog_team"."id",
Expand Down
2 changes: 1 addition & 1 deletion posthog/hogql_queries/insights/lifecycle_query_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def to_actors_query(

def to_actors_query_options(self) -> InsightActorsQueryOptionsResponse:
return InsightActorsQueryOptionsResponse(
day=[{"label": day, "value": day} for day in self.query_date_range.all_values()],
day=[{"label": format_label_date(value), "value": value} for value in self.query_date_range.all_values()],
status=[
{
"label": "Dormant",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import zoneinfo
from dataclasses import dataclass
from datetime import datetime
from typing import Dict, List, Optional
from unittest.mock import MagicMock, patch
from django.test import override_settings
Expand Down Expand Up @@ -1478,18 +1480,18 @@ def test_to_actors_query_options(self):
response = runner.to_actors_query_options()

assert response.day == [
DayItem(label="2020-01-09", value="2020-01-09"),
DayItem(label="2020-01-10", value="2020-01-10"),
DayItem(label="2020-01-11", value="2020-01-11"),
DayItem(label="2020-01-12", value="2020-01-12"),
DayItem(label="2020-01-13", value="2020-01-13"),
DayItem(label="2020-01-14", value="2020-01-14"),
DayItem(label="2020-01-15", value="2020-01-15"),
DayItem(label="2020-01-16", value="2020-01-16"),
DayItem(label="2020-01-17", value="2020-01-17"),
DayItem(label="2020-01-18", value="2020-01-18"),
DayItem(label="2020-01-19", value="2020-01-19"),
DayItem(label="2020-01-20", value="2020-01-20"),
DayItem(label="9-Jan-2020", value=datetime(2020, 1, 9, 0, 0, tzinfo=zoneinfo.ZoneInfo(key="UTC"))),
DayItem(label="10-Jan-2020", value=datetime(2020, 1, 10, 0, 0, tzinfo=zoneinfo.ZoneInfo(key="UTC"))),
DayItem(label="11-Jan-2020", value=datetime(2020, 1, 11, 0, 0, tzinfo=zoneinfo.ZoneInfo(key="UTC"))),
DayItem(label="12-Jan-2020", value=datetime(2020, 1, 12, 0, 0, tzinfo=zoneinfo.ZoneInfo(key="UTC"))),
DayItem(label="13-Jan-2020", value=datetime(2020, 1, 13, 0, 0, tzinfo=zoneinfo.ZoneInfo(key="UTC"))),
DayItem(label="14-Jan-2020", value=datetime(2020, 1, 14, 0, 0, tzinfo=zoneinfo.ZoneInfo(key="UTC"))),
DayItem(label="15-Jan-2020", value=datetime(2020, 1, 15, 0, 0, tzinfo=zoneinfo.ZoneInfo(key="UTC"))),
DayItem(label="16-Jan-2020", value=datetime(2020, 1, 16, 0, 0, tzinfo=zoneinfo.ZoneInfo(key="UTC"))),
DayItem(label="17-Jan-2020", value=datetime(2020, 1, 17, 0, 0, tzinfo=zoneinfo.ZoneInfo(key="UTC"))),
DayItem(label="18-Jan-2020", value=datetime(2020, 1, 18, 0, 0, tzinfo=zoneinfo.ZoneInfo(key="UTC"))),
DayItem(label="19-Jan-2020", value=datetime(2020, 1, 19, 0, 0, tzinfo=zoneinfo.ZoneInfo(key="UTC"))),
DayItem(label="20-Jan-2020", value=datetime(2020, 1, 20, 0, 0, tzinfo=zoneinfo.ZoneInfo(key="UTC"))),
]

assert response.breakdown is None
Expand All @@ -1513,18 +1515,18 @@ def test_to_actors_query_options_compare(self):
response = runner.to_actors_query_options()

assert response.day == [
DayItem(label="2020-01-09", value="2020-01-09"),
DayItem(label="2020-01-10", value="2020-01-10"),
DayItem(label="2020-01-11", value="2020-01-11"),
DayItem(label="2020-01-12", value="2020-01-12"),
DayItem(label="2020-01-13", value="2020-01-13"),
DayItem(label="2020-01-14", value="2020-01-14"),
DayItem(label="2020-01-15", value="2020-01-15"),
DayItem(label="2020-01-16", value="2020-01-16"),
DayItem(label="2020-01-17", value="2020-01-17"),
DayItem(label="2020-01-18", value="2020-01-18"),
DayItem(label="2020-01-19", value="2020-01-19"),
DayItem(label="2020-01-20", value="2020-01-20"),
DayItem(label="9-Jan-2020", value=datetime(2020, 1, 9, 0, 0, tzinfo=zoneinfo.ZoneInfo(key="UTC"))),
DayItem(label="10-Jan-2020", value=datetime(2020, 1, 10, 0, 0, tzinfo=zoneinfo.ZoneInfo(key="UTC"))),
DayItem(label="11-Jan-2020", value=datetime(2020, 1, 11, 0, 0, tzinfo=zoneinfo.ZoneInfo(key="UTC"))),
DayItem(label="12-Jan-2020", value=datetime(2020, 1, 12, 0, 0, tzinfo=zoneinfo.ZoneInfo(key="UTC"))),
DayItem(label="13-Jan-2020", value=datetime(2020, 1, 13, 0, 0, tzinfo=zoneinfo.ZoneInfo(key="UTC"))),
DayItem(label="14-Jan-2020", value=datetime(2020, 1, 14, 0, 0, tzinfo=zoneinfo.ZoneInfo(key="UTC"))),
DayItem(label="15-Jan-2020", value=datetime(2020, 1, 15, 0, 0, tzinfo=zoneinfo.ZoneInfo(key="UTC"))),
DayItem(label="16-Jan-2020", value=datetime(2020, 1, 16, 0, 0, tzinfo=zoneinfo.ZoneInfo(key="UTC"))),
DayItem(label="17-Jan-2020", value=datetime(2020, 1, 17, 0, 0, tzinfo=zoneinfo.ZoneInfo(key="UTC"))),
DayItem(label="18-Jan-2020", value=datetime(2020, 1, 18, 0, 0, tzinfo=zoneinfo.ZoneInfo(key="UTC"))),
DayItem(label="19-Jan-2020", value=datetime(2020, 1, 19, 0, 0, tzinfo=zoneinfo.ZoneInfo(key="UTC"))),
DayItem(label="20-Jan-2020", value=datetime(2020, 1, 20, 0, 0, tzinfo=zoneinfo.ZoneInfo(key="UTC"))),
]

assert response.breakdown is None
Expand Down
8 changes: 7 additions & 1 deletion posthog/hogql_queries/insights/trends/trends_query_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,13 @@ def to_actors_query_options(self) -> InsightActorsQueryOptionsResponse:
res_compare: List[CompareItem] | None = None

# Days
res_days: List[DayItem] = [DayItem(label=day, value=day) for day in self.query_date_range.all_values()]
res_days: list[DayItem] = [
DayItem(
label=format_label_date(value, self.query_date_range.interval_name),
value=value,
)
for value in self.query_date_range.all_values()
]

# Series
for index, series in enumerate(self.query.series):
Expand Down
15 changes: 7 additions & 8 deletions posthog/hogql_queries/utils/query_date_range.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import re
from datetime import datetime, timedelta
from functools import cached_property
from typing import Literal, Optional, Dict, List
from typing import Literal, Optional, Dict
from zoneinfo import ZoneInfo

from dateutil.parser import parse
Expand Down Expand Up @@ -140,16 +140,15 @@ def interval_relativedelta(self) -> relativedelta:
hours=1 if self.interval_name == "hour" else 0,
)

def all_values(self) -> List[str]:
def all_values(self) -> list[datetime]:
start = self.align_with_interval(self.date_from())
end: datetime = self.date_to()
values: List[str] = []
delta = self.interval_relativedelta()

values: list[datetime] = []
while start <= end:
if self.interval_name == "hour":
values.append(start.strftime("%Y-%m-%d %H:%M:%S"))
else:
values.append(start.strftime("%Y-%m-%d"))
start += self.interval_relativedelta()
values.append(start)
start += delta
return values

def date_to_as_hogql(self) -> ast.Expr:
Expand Down
25 changes: 20 additions & 5 deletions posthog/hogql_queries/utils/test/test_query_date_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,32 +61,47 @@ def test_all_values(self):
QueryDateRange(
team=self.team, date_range=DateRange(date_from="-20h"), interval=IntervalType.day, now=now
).all_values(),
["2021-08-24", "2021-08-25"],
[parser.isoparse("2021-08-24T00:00:00Z"), parser.isoparse("2021-08-25T00:00:00Z")],
)
self.assertEqual(
QueryDateRange(
team=self.team, date_range=DateRange(date_from="-20d"), interval=IntervalType.week, now=now
).all_values(),
["2021-08-01", "2021-08-08", "2021-08-15", "2021-08-22"],
[
parser.isoparse("2021-08-01T00:00:00Z"),
parser.isoparse("2021-08-08T00:00:00Z"),
parser.isoparse("2021-08-15T00:00:00Z"),
parser.isoparse("2021-08-22T00:00:00Z"),
],
)
self.team.week_start_day = WeekStartDay.MONDAY
self.assertEqual(
QueryDateRange(
team=self.team, date_range=DateRange(date_from="-20d"), interval=IntervalType.week, now=now
).all_values(),
["2021-08-02", "2021-08-09", "2021-08-16", "2021-08-23"],
[
parser.isoparse("2021-08-02T00:00:00Z"),
parser.isoparse("2021-08-09T00:00:00Z"),
parser.isoparse("2021-08-16T00:00:00Z"),
parser.isoparse("2021-08-23T00:00:00Z"),
],
)
self.assertEqual(
QueryDateRange(
team=self.team, date_range=DateRange(date_from="-50d"), interval=IntervalType.month, now=now
).all_values(),
["2021-07-01", "2021-08-01"],
[parser.isoparse("2021-07-01T00:00:00Z"), parser.isoparse("2021-08-01T00:00:00Z")],
)
self.assertEqual(
QueryDateRange(
team=self.team, date_range=DateRange(date_from="-3h"), interval=IntervalType.hour, now=now
).all_values(),
["2021-08-24 21:00:00", "2021-08-24 22:00:00", "2021-08-24 23:00:00", "2021-08-25 00:00:00"],
[
parser.isoparse("2021-08-24T21:00:00Z"),
parser.isoparse("2021-08-24T22:00:00Z"),
parser.isoparse("2021-08-24T23:00:00Z"),
parser.isoparse("2021-08-25T00:00:00Z"),
],
)


Expand Down
6 changes: 5 additions & 1 deletion posthog/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@ class DateRange(BaseModel):
date_to: Optional[str] = None


class DatetimeDay(RootModel[AwareDatetime]):
root: AwareDatetime


class Day(RootModel[int]):
root: int

Expand Down Expand Up @@ -458,7 +462,7 @@ class DayItem(BaseModel):
extra="forbid",
)
label: str
value: Union[str, int]
value: Union[str, AwareDatetime, int]


class IntervalItem(BaseModel):
Expand Down

0 comments on commit 37f3ff3

Please sign in to comment.