Skip to content

Commit

Permalink
Merge pull request #28 from weni-ai/feature/live_filters
Browse files Browse the repository at this point in the history
Feature/live filters
  • Loading branch information
AlanJaeger authored Jul 22, 2024
2 parents f727046 + b2bfbaf commit 0a255a4
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 16 deletions.
33 changes: 30 additions & 3 deletions insights/dashboards/usecases/dashboard_creation.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ def create_widgets(self, dashboard_atendimento_humano):
config={
"limit": 12,
"operation": "timeseries_hour_group_count",
"live_filter": {
"created_on__gte": "today",
},
},
dashboard=dashboard_atendimento_humano,
position={"rows": [1, 1], "columns": [1, 12]},
Expand All @@ -48,7 +51,7 @@ def create_widgets(self, dashboard_atendimento_humano):
config={
"operation": "count",
"type_result": "executions",
"filter": {"is_active": True, "user_id__isnull": True},
"filter": {"is_active": True, "user_id__isnull": False},
},
dashboard=dashboard_atendimento_humano,
position={"rows": [2, 2], "columns": [1, 4]},
Expand All @@ -61,6 +64,12 @@ def create_widgets(self, dashboard_atendimento_humano):
"operation": "avg",
"type_result": "executions",
"op_field": "waiting_time",
"filter": {},
"live_filter": {
"created_on__gte": "today",
"user_id__isnull": False,
"is_active": False,
},
"data_type": "sec",
},
dashboard=dashboard_atendimento_humano,
Expand All @@ -74,6 +83,7 @@ def create_widgets(self, dashboard_atendimento_humano):
"operation": "count",
"type_result": "executions",
"filter": {"is_active": False},
"live_filter": {"ended_at__gte": "today"},
},
dashboard=dashboard_atendimento_humano,
position={"rows": [2, 2], "columns": [9, 12]},
Expand All @@ -86,6 +96,12 @@ def create_widgets(self, dashboard_atendimento_humano):
"operation": "avg",
"type_result": "executions",
"op_field": "message_response_time",
"filter": {},
"live_filter": {
"created_on__gte": "today",
"user_id__isnull": False,
"is_active": False,
},
"data_type": "sec",
},
dashboard=dashboard_atendimento_humano,
Expand All @@ -100,7 +116,7 @@ def create_widgets(self, dashboard_atendimento_humano):
"type_result": "executions",
"filter": {
"is_active": True,
"user_id__isnull": False,
"user_id__isnull": True,
},
},
dashboard=dashboard_atendimento_humano,
Expand All @@ -114,6 +130,12 @@ def create_widgets(self, dashboard_atendimento_humano):
"operation": "avg",
"type_result": "executions",
"op_field": "interaction_time",
"filter": {},
"live_filter": {
"created_on__gte": "today",
"user_id__isnull": False,
"is_active": False,
},
"data_type": "sec",
},
dashboard=dashboard_atendimento_humano,
Expand Down Expand Up @@ -242,6 +264,7 @@ def create_reports(
"filter": {
"is_active": True,
"attending": False,
"user_id__isnull": True,
},
"is_default": False,
}
Expand Down Expand Up @@ -285,7 +308,7 @@ def create_reports(
"hidden_name": False,
},
],
"filter": {"is_active": True, "attending": True},
"filter": {"is_active": True, "attending": True, "user_id__isnull": False},
"is_default": False,
}
closed = {
Expand Down Expand Up @@ -341,6 +364,7 @@ def create_reports(
},
],
"filter": {"is_active": False},
"live_filter": {"ended_at__gte": "today"},
"is_default": False,
}
table_group_report = {
Expand All @@ -361,6 +385,9 @@ def create_reports(
source="rooms",
config={
"operation": "timeseries_hour_group_count",
"live_filter": {
"created_on__gte": "today",
},
},
widget=pico_de_atendimento,
)
Expand Down
9 changes: 6 additions & 3 deletions insights/dashboards/viewsets.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from django.conf import settings
from django.db.models import Q
from rest_framework import mixins, status, viewsets
from rest_framework.decorators import action
from rest_framework.response import Response

from django.conf import settings
from django.db.models import Q

from insights.authentication.permissions import ProjectAuthPermission
from insights.dashboards.models import Dashboard
from insights.dashboards.utils import DefaultPagination
Expand Down Expand Up @@ -83,9 +82,11 @@ def get_widget_data(self, request, pk=None, widget_uuid=None):
widget = Widget.objects.get(uuid=widget_uuid, dashboard_id=pk)
filters = dict(request.data or request.query_params or {})
filters.pop("project", None)
is_live = filters.pop("is_live", False)
serialized_source = get_source_data_from_widget(
widget=widget,
is_report=False,
is_live=is_live,
filters=filters,
user_email=request.user.email,
)
Expand Down Expand Up @@ -121,11 +122,13 @@ def get_report_data(self, request, pk=None, widget_uuid=None):
widget = Widget.objects.get(uuid=widget_uuid, dashboard_id=pk)
filters = dict(request.data or request.query_params or {})
filters.pop("project", None)
is_live = filters.pop("is_live", False)
serialized_source = get_source_data_from_widget(
widget=widget,
is_report=True,
filters=filters,
user_email=request.user.email,
is_live=is_live,
)
return Response(serialized_source, status.HTTP_200_OK)

Expand Down
2 changes: 1 addition & 1 deletion insights/sources/rooms/query_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def timeseries_hour_group_count(
):
if not self.is_valid:
self.build_query()
query = f"WITH hourly_data AS (SELECT EXTRACT(HOUR FROM r.{time_field}) AS hour, COUNT(*) AS rooms_count FROM public.rooms_room as r {self.join_clause} WHERE {self.where_clause} GROUP BY hour) SELECT CONCAT(hours.label, 'h') AS label, COALESCE(hourly_data.rooms_count, 0) AS value FROM generate_series(0, 23) AS hours(label) LEFT JOIN hourly_data ON hours.label = hourly_data.hour ORDER BY value DESC FETCH FIRST {limit} ROWS ONLY;"
query = f"WITH hourly_data AS (SELECT EXTRACT(HOUR FROM r.{time_field} AT TIME ZONE '{timezone}') AS hour, COUNT(*) AS rooms_count FROM public.rooms_room as r {self.join_clause} WHERE {self.where_clause} GROUP BY hour) SELECT CONCAT(hours.label, 'h') AS label, COALESCE(hourly_data.rooms_count, 0) AS value FROM generate_series(0, 23) AS hours(label) LEFT JOIN hourly_data ON hours.label::int = hourly_data.hour ORDER BY value DESC FETCH FIRST {limit} ROWS ONLY;"
return query, self.params

def count(self, *args, **kwargs):
Expand Down
16 changes: 11 additions & 5 deletions insights/widgets/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,14 @@ def project(self):
def is_configurable(self):
return self.dashboard.name == "Resultados de fluxos"

def source_config(self, sub_widget: str = None):
def source_config(self, sub_widget: str = None, is_live=False):
config = self.config if sub_widget is None else self.config[sub_widget]
# default_filters, operation, op_field, limit
filters = config.get("filter", {})
if is_live:
filters.update(config.get("live_filter", {}))
return (
config.get("filter", {}),
filters,
config.get("operation", "list"),
config.get("op_field", None),
config.get("limit", None),
Expand All @@ -60,11 +63,14 @@ def project(self):
def __str__(self):
return self.name

def source_config(self, sub_widget: str = None):
def source_config(self, sub_widget: str = None, is_live=False):
config = self.config if sub_widget is None else self.config[sub_widget]
# default_filters, operation, op_field
# default_filters, operation, op_field, limit
filters = config.get("filter", {})
if is_live:
filters.update(config.get("live_filter", {}))
return (
config.get("filter", {}),
filters,
config.get("operation", "list"),
config.get("op_field", None),
config.get("limit", None),
Expand Down
34 changes: 30 additions & 4 deletions insights/widgets/usecases/get_source_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,39 @@
from insights.widgets.models import Widget


def set_live_day(default_filters):
start_of_day = datetime.combine(datetime.now().date(), datetime.min.time())

for key, value in default_filters.items():
if value == "today":
default_filters[key] = start_of_day


def apply_timezone_to_filters(default_filters, project_timezone_str):
project_timezone = pytz.timezone(project_timezone_str)
for key in default_filters.keys():
if key.endswith("__gte") or key.endswith("__lte"):
date_str = default_filters[key][0]
date_obj = datetime.strptime(date_str, "%Y-%m-%d")
value = default_filters[key]
if isinstance(value, list):
date_str = value[0]
date_obj = datetime.strptime(date_str, "%Y-%m-%d")
elif isinstance(value, datetime):
date_obj = value
else:
raise ValueError(
f"Unexpected value type for filter {key}: {type(value)}"
)

date_obj_with_tz = project_timezone.localize(date_obj)
default_filters[key] = date_obj_with_tz.isoformat()


def get_source_data_from_widget(
widget: Widget, is_report: bool = False, filters: dict = {}, user_email: str = ""
widget: Widget,
is_report: bool = False,
is_live=False,
filters: dict = {},
user_email: str = "",
):
try:
source = widget.source
Expand All @@ -32,11 +53,14 @@ def get_source_data_from_widget(
)

default_filters, operation, op_field, limit = widget.source_config(
sub_widget=filters.pop("slug", [None])[0]
sub_widget=filters.pop("slug", [None])[0], is_live=is_live
)

default_filters.update(filters)

if is_live:
set_live_day(default_filters)

project_timezone = widget.project.timezone
apply_timezone_to_filters(default_filters, project_timezone)

Expand All @@ -49,6 +73,8 @@ def get_source_data_from_widget(
query_kwargs["op_field"] = op_field
if limit:
query_kwargs["limit"] = limit
if project_timezone:
query_kwargs["timezone"] = project_timezone

default_filters["project"] = str(widget.project.uuid)
serialized_source = SourceQuery.execute(
Expand Down

0 comments on commit 0a255a4

Please sign in to comment.