diff --git a/api/chalicelib/core/events.py b/api/chalicelib/core/events.py index dd6ca960a..dcb4d88d6 100644 --- a/api/chalicelib/core/events.py +++ b/api/chalicelib/core/events.py @@ -1,8 +1,9 @@ +from functools import cache from typing import Optional import schemas -from chalicelib.core.autocomplete import autocomplete from chalicelib.core import issues +from chalicelib.core.autocomplete import autocomplete from chalicelib.core.sessions import sessions_metas from chalicelib.utils import pg_client, helper from chalicelib.utils.TimeUTC import TimeUTC @@ -137,52 +138,57 @@ class EventType: column=None) # column=None because errors are searched by name or message -SUPPORTED_TYPES = { - EventType.CLICK.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.CLICK), - query=autocomplete.__generic_query(typename=EventType.CLICK.ui_type)), - EventType.INPUT.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.INPUT), - query=autocomplete.__generic_query(typename=EventType.INPUT.ui_type)), - EventType.LOCATION.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.LOCATION), - query=autocomplete.__generic_query( - typename=EventType.LOCATION.ui_type)), - EventType.CUSTOM.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.CUSTOM), - query=autocomplete.__generic_query(typename=EventType.CUSTOM.ui_type)), - EventType.REQUEST.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.REQUEST), - query=autocomplete.__generic_query( - typename=EventType.REQUEST.ui_type)), - EventType.GRAPHQL.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.GRAPHQL), - query=autocomplete.__generic_query( - typename=EventType.GRAPHQL.ui_type)), - EventType.STATEACTION.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.STATEACTION), +@cache +def supported_types(): + return { + EventType.CLICK.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.CLICK), + query=autocomplete.__generic_query(typename=EventType.CLICK.ui_type)), + EventType.INPUT.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.INPUT), + query=autocomplete.__generic_query(typename=EventType.INPUT.ui_type)), + EventType.LOCATION.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.LOCATION), + query=autocomplete.__generic_query( + typename=EventType.LOCATION.ui_type)), + EventType.CUSTOM.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.CUSTOM), + query=autocomplete.__generic_query( + typename=EventType.CUSTOM.ui_type)), + EventType.REQUEST.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.REQUEST), query=autocomplete.__generic_query( - typename=EventType.STATEACTION.ui_type)), - EventType.TAG.ui_type: SupportedFilter(get=_search_tags, query=None), - EventType.ERROR.ui_type: SupportedFilter(get=autocomplete.__search_errors, - query=None), - EventType.METADATA.ui_type: SupportedFilter(get=autocomplete.__search_metadata, - query=None), - # MOBILE - EventType.CLICK_MOBILE.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.CLICK_MOBILE), - query=autocomplete.__generic_query( - typename=EventType.CLICK_MOBILE.ui_type)), - EventType.SWIPE_MOBILE.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.SWIPE_MOBILE), - query=autocomplete.__generic_query( - typename=EventType.SWIPE_MOBILE.ui_type)), - EventType.INPUT_MOBILE.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.INPUT_MOBILE), - query=autocomplete.__generic_query( - typename=EventType.INPUT_MOBILE.ui_type)), - EventType.VIEW_MOBILE.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.VIEW_MOBILE), + typename=EventType.REQUEST.ui_type)), + EventType.GRAPHQL.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.GRAPHQL), query=autocomplete.__generic_query( - typename=EventType.VIEW_MOBILE.ui_type)), - EventType.CUSTOM_MOBILE.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.CUSTOM_MOBILE), - query=autocomplete.__generic_query( - typename=EventType.CUSTOM_MOBILE.ui_type)), - EventType.REQUEST_MOBILE.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.REQUEST_MOBILE), - query=autocomplete.__generic_query( - typename=EventType.REQUEST_MOBILE.ui_type)), - EventType.CRASH_MOBILE.ui_type: SupportedFilter(get=autocomplete.__search_errors_mobile, + typename=EventType.GRAPHQL.ui_type)), + EventType.STATEACTION.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.STATEACTION), + query=autocomplete.__generic_query( + typename=EventType.STATEACTION.ui_type)), + EventType.TAG.ui_type: SupportedFilter(get=_search_tags, query=None), + EventType.ERROR.ui_type: SupportedFilter(get=autocomplete.__search_errors, + query=None), + EventType.METADATA.ui_type: SupportedFilter(get=autocomplete.__search_metadata, query=None), -} + # MOBILE + EventType.CLICK_MOBILE.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.CLICK_MOBILE), + query=autocomplete.__generic_query( + typename=EventType.CLICK_MOBILE.ui_type)), + EventType.SWIPE_MOBILE.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.SWIPE_MOBILE), + query=autocomplete.__generic_query( + typename=EventType.SWIPE_MOBILE.ui_type)), + EventType.INPUT_MOBILE.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.INPUT_MOBILE), + query=autocomplete.__generic_query( + typename=EventType.INPUT_MOBILE.ui_type)), + EventType.VIEW_MOBILE.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.VIEW_MOBILE), + query=autocomplete.__generic_query( + typename=EventType.VIEW_MOBILE.ui_type)), + EventType.CUSTOM_MOBILE.ui_type: SupportedFilter( + get=autocomplete.__generic_autocomplete(EventType.CUSTOM_MOBILE), + query=autocomplete.__generic_query( + typename=EventType.CUSTOM_MOBILE.ui_type)), + EventType.REQUEST_MOBILE.ui_type: SupportedFilter( + get=autocomplete.__generic_autocomplete(EventType.REQUEST_MOBILE), + query=autocomplete.__generic_query( + typename=EventType.REQUEST_MOBILE.ui_type)), + EventType.CRASH_MOBILE.ui_type: SupportedFilter(get=autocomplete.__search_errors_mobile, + query=None), + } def get_errors_by_session_id(session_id, project_id): @@ -202,17 +208,17 @@ def search(text, event_type, project_id, source, key): if not event_type: return {"data": autocomplete.__get_autocomplete_table(text, project_id)} - if event_type in SUPPORTED_TYPES.keys(): - rows = SUPPORTED_TYPES[event_type].get(project_id=project_id, value=text, key=key, source=source) - elif event_type + "_MOBILE" in SUPPORTED_TYPES.keys(): - rows = SUPPORTED_TYPES[event_type + "_MOBILE"].get(project_id=project_id, value=text, key=key, source=source) - elif event_type in sessions_metas.SUPPORTED_TYPES.keys(): + if event_type in supported_types().keys(): + rows = supported_types()[event_type].get(project_id=project_id, value=text, key=key, source=source) + elif event_type + "_MOBILE" in supported_types().keys(): + rows = supported_types()[event_type + "_MOBILE"].get(project_id=project_id, value=text, key=key, source=source) + elif event_type in sessions_metas.supported_types().keys(): return sessions_metas.search(text, event_type, project_id) elif event_type.endswith("_IOS") \ - and event_type[:-len("_IOS")] in sessions_metas.SUPPORTED_TYPES.keys(): + and event_type[:-len("_IOS")] in sessions_metas.supported_types().keys(): return sessions_metas.search(text, event_type, project_id) elif event_type.endswith("_MOBILE") \ - and event_type[:-len("_MOBILE")] in sessions_metas.SUPPORTED_TYPES.keys(): + and event_type[:-len("_MOBILE")] in sessions_metas.supported_types().keys(): return sessions_metas.search(text, event_type, project_id) else: return {"errors": ["unsupported event"]} diff --git a/api/chalicelib/core/metrics/custom_metrics.py b/api/chalicelib/core/metrics/custom_metrics.py index 84c7aab3c..8c02d2be3 100644 --- a/api/chalicelib/core/metrics/custom_metrics.py +++ b/api/chalicelib/core/metrics/custom_metrics.py @@ -378,21 +378,6 @@ def search_metrics(project_id, user_id, data: schemas.MetricSearchSchema, includ ) with pg_client.PostgresClient() as cur: - count_query = cur.mogrify( - f"""SELECT COUNT(*) - FROM metrics - LEFT JOIN LATERAL ( - SELECT email AS owner_email, name AS owner_name - FROM users - WHERE deleted_at ISNULL - AND users.user_id = metrics.user_id - ) AS owner ON (TRUE) - WHERE {" AND ".join(constraints)};""", - params - ) - cur.execute(count_query) - total = cur.fetchone()["count"] - sub_join = "" if include_series: sub_join = """LEFT JOIN LATERAL ( @@ -402,7 +387,8 @@ def search_metrics(project_id, user_id, data: schemas.MetricSearchSchema, includ AND metric_series.deleted_at ISNULL ) AS metric_series ON (TRUE)""" - sort_column = data.sort.field if data.sort.field is not None else "created_at" + sort_column = data.sort.field if data.sort.field is not None and len(data.sort.field) > 0 \ + else "created_at" # change ascend to asc and descend to desc sort_order = data.sort.order.value if hasattr(data.sort.order, "value") else data.sort.order if sort_order == "ascend": @@ -411,7 +397,7 @@ def search_metrics(project_id, user_id, data: schemas.MetricSearchSchema, includ sort_order = "desc" query = cur.mogrify( - f"""SELECT metric_id, project_id, user_id, name, is_public, created_at, edited_at, + f"""SELECT count(1) OVER () AS total,metric_id, project_id, user_id, name, is_public, created_at, edited_at, metric_type, metric_of, metric_format, metric_value, view_type, is_pinned, dashboards, owner_email, owner_name, default_config AS config, thumbnail FROM metrics @@ -441,15 +427,21 @@ def search_metrics(project_id, user_id, data: schemas.MetricSearchSchema, includ ) cur.execute(query) rows = cur.fetchall() - if include_series: - for r in rows: - for s in r.get("series", []): - s["filter"] = helper.old_search_payload_to_flat(s["filter"]) + if len(rows) > 0: + total = rows[0]["total"] + if include_series: + for r in rows: + r.pop("total") + for s in r.get("series", []): + s["filter"] = helper.old_search_payload_to_flat(s["filter"]) + else: + for r in rows: + r.pop("total") + r["created_at"] = TimeUTC.datetime_to_timestamp(r["created_at"]) + r["edited_at"] = TimeUTC.datetime_to_timestamp(r["edited_at"]) + rows = helper.list_to_camel_case(rows) else: - for r in rows: - r["created_at"] = TimeUTC.datetime_to_timestamp(r["created_at"]) - r["edited_at"] = TimeUTC.datetime_to_timestamp(r["edited_at"]) - rows = helper.list_to_camel_case(rows) + total = 0 return {"total": total, "list": rows} diff --git a/api/chalicelib/core/sessions/sessions_metas.py b/api/chalicelib/core/sessions/sessions_metas.py index 1b538ec9c..f39b19ebd 100644 --- a/api/chalicelib/core/sessions/sessions_metas.py +++ b/api/chalicelib/core/sessions/sessions_metas.py @@ -1,76 +1,81 @@ +from functools import cache + import schemas from chalicelib.core.autocomplete import autocomplete from chalicelib.utils.event_filter_definition import SupportedFilter -SUPPORTED_TYPES = { - schemas.FilterType.USER_OS: SupportedFilter( - get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_OS), - query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_OS)), - schemas.FilterType.USER_BROWSER: SupportedFilter( - get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_BROWSER), - query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_BROWSER)), - schemas.FilterType.USER_DEVICE: SupportedFilter( - get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_DEVICE), - query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_DEVICE)), - schemas.FilterType.USER_COUNTRY: SupportedFilter( - get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_COUNTRY), - query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_COUNTRY)), - schemas.FilterType.USER_CITY: SupportedFilter( - get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_CITY), - query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_CITY)), - schemas.FilterType.USER_STATE: SupportedFilter( - get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_STATE), - query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_STATE)), - schemas.FilterType.USER_ID: SupportedFilter( - get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_ID), - query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_ID)), - schemas.FilterType.USER_ANONYMOUS_ID: SupportedFilter( - get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_ANONYMOUS_ID), - query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_ANONYMOUS_ID)), - schemas.FilterType.REV_ID: SupportedFilter( - get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.REV_ID), - query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.REV_ID)), - schemas.FilterType.REFERRER: SupportedFilter( - get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.REFERRER), - query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.REFERRER)), - schemas.FilterType.UTM_CAMPAIGN: SupportedFilter( - get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.UTM_CAMPAIGN), - query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.UTM_CAMPAIGN)), - schemas.FilterType.UTM_MEDIUM: SupportedFilter( - get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.UTM_MEDIUM), - query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.UTM_MEDIUM)), - schemas.FilterType.UTM_SOURCE: SupportedFilter( - get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.UTM_SOURCE), - query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.UTM_SOURCE)), - # Mobile - schemas.FilterType.USER_OS_MOBILE: SupportedFilter( - get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_OS_MOBILE), - query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_OS_MOBILE)), - schemas.FilterType.USER_DEVICE_MOBILE: SupportedFilter( - get=autocomplete.generic_autocomplete_metas( - typename=schemas.FilterType.USER_DEVICE_MOBILE), - query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_DEVICE_MOBILE)), - schemas.FilterType.USER_COUNTRY_MOBILE: SupportedFilter( - get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_COUNTRY_MOBILE), - query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_COUNTRY_MOBILE)), - schemas.FilterType.USER_ID_MOBILE: SupportedFilter( - get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_ID_MOBILE), - query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_ID_MOBILE)), - schemas.FilterType.USER_ANONYMOUS_ID_MOBILE: SupportedFilter( - get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_ANONYMOUS_ID_MOBILE), - query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_ANONYMOUS_ID_MOBILE)), - schemas.FilterType.REV_ID_MOBILE: SupportedFilter( - get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.REV_ID_MOBILE), - query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.REV_ID_MOBILE)), -} +@cache +def supported_types(): + return { + schemas.FilterType.USER_OS: SupportedFilter( + get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_OS), + query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_OS)), + schemas.FilterType.USER_BROWSER: SupportedFilter( + get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_BROWSER), + query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_BROWSER)), + schemas.FilterType.USER_DEVICE: SupportedFilter( + get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_DEVICE), + query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_DEVICE)), + schemas.FilterType.USER_COUNTRY: SupportedFilter( + get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_COUNTRY), + query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_COUNTRY)), + schemas.FilterType.USER_CITY: SupportedFilter( + get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_CITY), + query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_CITY)), + schemas.FilterType.USER_STATE: SupportedFilter( + get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_STATE), + query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_STATE)), + schemas.FilterType.USER_ID: SupportedFilter( + get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_ID), + query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_ID)), + schemas.FilterType.USER_ANONYMOUS_ID: SupportedFilter( + get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_ANONYMOUS_ID), + query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_ANONYMOUS_ID)), + schemas.FilterType.REV_ID: SupportedFilter( + get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.REV_ID), + query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.REV_ID)), + schemas.FilterType.REFERRER: SupportedFilter( + get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.REFERRER), + query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.REFERRER)), + schemas.FilterType.UTM_CAMPAIGN: SupportedFilter( + get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.UTM_CAMPAIGN), + query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.UTM_CAMPAIGN)), + schemas.FilterType.UTM_MEDIUM: SupportedFilter( + get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.UTM_MEDIUM), + query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.UTM_MEDIUM)), + schemas.FilterType.UTM_SOURCE: SupportedFilter( + get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.UTM_SOURCE), + query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.UTM_SOURCE)), + # Mobile + schemas.FilterType.USER_OS_MOBILE: SupportedFilter( + get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_OS_MOBILE), + query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_OS_MOBILE)), + schemas.FilterType.USER_DEVICE_MOBILE: SupportedFilter( + get=autocomplete.generic_autocomplete_metas( + typename=schemas.FilterType.USER_DEVICE_MOBILE), + query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_DEVICE_MOBILE)), + schemas.FilterType.USER_COUNTRY_MOBILE: SupportedFilter( + get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_COUNTRY_MOBILE), + query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_COUNTRY_MOBILE)), + schemas.FilterType.USER_ID_MOBILE: SupportedFilter( + get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_ID_MOBILE), + query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_ID_MOBILE)), + schemas.FilterType.USER_ANONYMOUS_ID_MOBILE: SupportedFilter( + get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_ANONYMOUS_ID_MOBILE), + query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.USER_ANONYMOUS_ID_MOBILE)), + schemas.FilterType.REV_ID_MOBILE: SupportedFilter( + get=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.REV_ID_MOBILE), + query=autocomplete.generic_autocomplete_metas(typename=schemas.FilterType.REV_ID_MOBILE)), + + } def search(text: str, meta_type: schemas.FilterType, project_id: int): rows = [] - if meta_type not in list(SUPPORTED_TYPES.keys()): + if meta_type not in list(supported_types().keys()): return {"errors": ["unsupported type"]} - rows += SUPPORTED_TYPES[meta_type].get(project_id=project_id, text=text) + rows += supported_types()[meta_type].get(project_id=project_id, text=text) # for IOS events autocomplete # if meta_type + "_IOS" in list(SUPPORTED_TYPES.keys()): # rows += SUPPORTED_TYPES[meta_type + "_IOS"].get(project_id=project_id, text=text) diff --git a/api/chalicelib/core/sessions/sessions_search.py b/api/chalicelib/core/sessions/sessions_search.py index ac87deec4..8584f43af 100644 --- a/api/chalicelib/core/sessions/sessions_search.py +++ b/api/chalicelib/core/sessions/sessions_search.py @@ -166,7 +166,8 @@ def search_sessions(data: schemas.SessionsSearchPayloadSchema, project: schemas. # reverse=data.order.upper() == "DESC") return { 'total': total, - 'sessions': helper.list_to_camel_case(sessions) + 'sessions': helper.list_to_camel_case(sessions), + 'src': 1 } diff --git a/api/routers/subs/metrics.py b/api/routers/subs/metrics.py index 558175069..d60280c49 100644 --- a/api/routers/subs/metrics.py +++ b/api/routers/subs/metrics.py @@ -10,31 +10,22 @@ public_app, app, app_apikey = get_routers() @app.post("/{projectId}/dashboards", tags=["dashboard"]) -def create_dashboards( - projectId: int, - data: schemas.CreateDashboardSchema = Body(...), - context: schemas.CurrentContext = Depends(OR_context), -): +def create_dashboards(projectId: int, data: schemas.CreateDashboardSchema = Body(...), + context: schemas.CurrentContext = Depends(OR_context)): return dashboards.create_dashboard( project_id=projectId, user_id=context.user_id, data=data ) @app.get("/{projectId}/dashboards", tags=["dashboard"]) -def get_dashboards( - projectId: int, context: schemas.CurrentContext = Depends(OR_context) -): +def get_dashboards(projectId: int, context: schemas.CurrentContext = Depends(OR_context)): return { "data": dashboards.get_dashboards(project_id=projectId, user_id=context.user_id) } @app.get("/{projectId}/dashboards/{dashboardId}", tags=["dashboard"]) -def get_dashboard( - projectId: int, - dashboardId: int, - context: schemas.CurrentContext = Depends(OR_context), -): +def get_dashboard(projectId: int, dashboardId: int, context: schemas.CurrentContext = Depends(OR_context)): data = dashboards.get_dashboard( project_id=projectId, user_id=context.user_id, dashboard_id=dashboardId ) @@ -44,12 +35,8 @@ def get_dashboard( @app.put("/{projectId}/dashboards/{dashboardId}", tags=["dashboard"]) -def update_dashboard( - projectId: int, - dashboardId: int, - data: schemas.EditDashboardSchema = Body(...), - context: schemas.CurrentContext = Depends(OR_context), -): +def update_dashboard(projectId: int, dashboardId: int, data: schemas.EditDashboardSchema = Body(...), + context: schemas.CurrentContext = Depends(OR_context)): return { "data": dashboards.update_dashboard( project_id=projectId, @@ -61,23 +48,15 @@ def update_dashboard( @app.delete("/{projectId}/dashboards/{dashboardId}", tags=["dashboard"]) -def delete_dashboard( - projectId: int, - dashboardId: int, - _=Body(None), - context: schemas.CurrentContext = Depends(OR_context), -): +def delete_dashboard(projectId: int, dashboardId: int, _=Body(None), + context: schemas.CurrentContext = Depends(OR_context)): return dashboards.delete_dashboard( project_id=projectId, user_id=context.user_id, dashboard_id=dashboardId ) @app.get("/{projectId}/dashboards/{dashboardId}/pin", tags=["dashboard"]) -def pin_dashboard( - projectId: int, - dashboardId: int, - context: schemas.CurrentContext = Depends(OR_context), -): +def pin_dashboard(projectId: int, dashboardId: int, context: schemas.CurrentContext = Depends(OR_context)): return { "data": dashboards.pin_dashboard( project_id=projectId, user_id=context.user_id, dashboard_id=dashboardId @@ -86,12 +65,8 @@ def pin_dashboard( @app.post("/{projectId}/dashboards/{dashboardId}/cards", tags=["cards"]) -def add_card_to_dashboard( - projectId: int, - dashboardId: int, - data: schemas.AddWidgetToDashboardPayloadSchema = Body(...), - context: schemas.CurrentContext = Depends(OR_context), -): +def add_card_to_dashboard(projectId: int, dashboardId: int, data: schemas.AddWidgetToDashboardPayloadSchema = Body(...), + context: schemas.CurrentContext = Depends(OR_context)): return { "data": dashboards.add_widget( project_id=projectId, @@ -104,12 +79,8 @@ def add_card_to_dashboard( @app.post("/{projectId}/dashboards/{dashboardId}/metrics", tags=["dashboard"]) # @app.put('/{projectId}/dashboards/{dashboardId}/metrics', tags=["dashboard"]) -def create_metric_and_add_to_dashboard( - projectId: int, - dashboardId: int, - data: schemas.CardSchema = Body(...), - context: schemas.CurrentContext = Depends(OR_context), -): +def create_metric_and_add_to_dashboard(projectId: int, dashboardId: int, data: schemas.CardSchema = Body(...), + context: schemas.CurrentContext = Depends(OR_context)): return { "data": dashboards.create_metric_add_widget( project=context.project, @@ -121,13 +92,9 @@ def create_metric_and_add_to_dashboard( @app.put("/{projectId}/dashboards/{dashboardId}/widgets/{widgetId}", tags=["dashboard"]) -def update_widget_in_dashboard( - projectId: int, - dashboardId: int, - widgetId: int, - data: schemas.UpdateWidgetPayloadSchema = Body(...), - context: schemas.CurrentContext = Depends(OR_context), -): +def update_widget_in_dashboard(projectId: int, dashboardId: int, widgetId: int, + data: schemas.UpdateWidgetPayloadSchema = Body(...), + context: schemas.CurrentContext = Depends(OR_context)): return dashboards.update_widget( project_id=projectId, user_id=context.user_id, @@ -137,16 +104,9 @@ def update_widget_in_dashboard( ) -@app.delete( - "/{projectId}/dashboards/{dashboardId}/widgets/{widgetId}", tags=["dashboard"] -) -def remove_widget_from_dashboard( - projectId: int, - dashboardId: int, - widgetId: int, - _=Body(None), - context: schemas.CurrentContext = Depends(OR_context), -): +@app.delete("/{projectId}/dashboards/{dashboardId}/widgets/{widgetId}", tags=["dashboard"]) +def remove_widget_from_dashboard(projectId: int, dashboardId: int, widgetId: int, _=Body(None), + context: schemas.CurrentContext = Depends(OR_context)): return dashboards.remove_widget( project_id=projectId, user_id=context.user_id, @@ -156,11 +116,8 @@ def remove_widget_from_dashboard( @app.post("/{projectId}/cards/try", tags=["cards"]) -def try_card( - projectId: int, - data: schemas.CardSchema = Body(...), - context: schemas.CurrentContext = Depends(OR_context), -): +def try_card(projectId: int, data: schemas.CardSchema = Body(...), + context: schemas.CurrentContext = Depends(OR_context)): return { "data": custom_metrics.get_chart( project=context.project, data=data, user_id=context.user_id @@ -169,11 +126,8 @@ def try_card( @app.post("/{projectId}/cards/try/sessions", tags=["cards"]) -def try_card_sessions( - projectId: int, - data: schemas.CardSessionsSchema = Body(...), - context: schemas.CurrentContext = Depends(OR_context), -): +def try_card_sessions(projectId: int, data: schemas.CardSessionsSchema = Body(...), + context: schemas.CurrentContext = Depends(OR_context)): data = custom_metrics.get_sessions( project=context.project, user_id=context.user_id, data=data ) @@ -181,11 +135,8 @@ def try_card_sessions( @app.post("/{projectId}/cards/try/issues", tags=["cards"]) -def try_card_issues( - projectId: int, - data: schemas.CardSchema = Body(...), - context: schemas.CurrentContext = Depends(OR_context), -): +def try_card_issues(projectId: int, data: schemas.CardSchema = Body(...), + context: schemas.CurrentContext = Depends(OR_context)): return { "data": custom_metrics.get_issues( project=context.project, user_id=context.user_id, data=data @@ -201,22 +152,16 @@ def get_cards(projectId: int, context: schemas.CurrentContext = Depends(OR_conte @app.post("/{projectId}/cards", tags=["cards"]) -def create_card( - projectId: int, - data: schemas.CardSchema = Body(...), - context: schemas.CurrentContext = Depends(OR_context), -): +def create_card(projectId: int, data: schemas.CardSchema = Body(...), + context: schemas.CurrentContext = Depends(OR_context)): return custom_metrics.create_card( project=context.project, user_id=context.user_id, data=data ) @app.post("/{projectId}/cards/search", tags=["cards"]) -def search_cards( - projectId: int, - data: schemas.MetricSearchSchema = Body(...), - context: schemas.CurrentContext = Depends(OR_context), -): +def search_cards(projectId: int, data: schemas.MetricSearchSchema = Body(...), + context: schemas.CurrentContext = Depends(OR_context)): return { "data": custom_metrics.search_metrics( project_id=projectId, user_id=context.user_id, data=data @@ -225,11 +170,7 @@ def search_cards( @app.get("/{projectId}/cards/{metric_id}", tags=["cards"]) -def get_card( - projectId: int, - metric_id: Union[int, str], - context: schemas.CurrentContext = Depends(OR_context), -): +def get_card(projectId: int, metric_id: Union[int, str], context: schemas.CurrentContext = Depends(OR_context)): if metric_id.isnumeric(): metric_id = int(metric_id) else: @@ -243,12 +184,8 @@ def get_card( @app.post("/{projectId}/cards/{metric_id}/sessions", tags=["cards"]) -def get_card_sessions( - projectId: int, - metric_id: int, - data: schemas.CardSessionsSchema = Body(...), - context: schemas.CurrentContext = Depends(OR_context), -): +def get_card_sessions(projectId: int, metric_id: int, data: schemas.CardSessionsSchema = Body(...), + context: schemas.CurrentContext = Depends(OR_context)): data = custom_metrics.get_sessions_by_card_id( project=context.project, user_id=context.user_id, metric_id=metric_id, data=data ) @@ -257,16 +194,10 @@ def get_card_sessions( return {"data": data} -@app.post( - "/{projectId}/cards/{metric_id}/issues/{issueId}/sessions", tags=["dashboard"] -) -def get_metric_funnel_issue_sessions( - projectId: int, - metric_id: int, - issueId: str, - data: schemas.CardSessionsSchema = Body(...), - context: schemas.CurrentContext = Depends(OR_context), -): +@app.post("/{projectId}/cards/{metric_id}/issues/{issueId}/sessions", tags=["dashboard"]) +def get_metric_funnel_issue_sessions(projectId: int, metric_id: int, issueId: str, + data: schemas.CardSessionsSchema = Body(...), + context: schemas.CurrentContext = Depends(OR_context)): data = custom_metrics.get_funnel_sessions_by_issue( project_id=projectId, user_id=context.user_id, @@ -280,12 +211,8 @@ def get_metric_funnel_issue_sessions( @app.post("/{projectId}/cards/{metric_id}/chart", tags=["card"]) -def get_card_chart( - projectId: int, - metric_id: int, - data: schemas.CardSessionsSchema = Body(...), - context: schemas.CurrentContext = Depends(OR_context), -): +def get_card_chart(projectId: int, metric_id: int, data: schemas.CardSessionsSchema = Body(...), + context: schemas.CurrentContext = Depends(OR_context)): data = custom_metrics.make_chart_from_card( project=context.project, user_id=context.user_id, metric_id=metric_id, data=data ) @@ -293,12 +220,8 @@ def get_card_chart( @app.post("/{projectId}/cards/{metric_id}", tags=["dashboard"]) -def update_card( - projectId: int, - metric_id: int, - data: schemas.CardSchema = Body(...), - context: schemas.CurrentContext = Depends(OR_context), -): +def update_card(projectId: int, metric_id: int, data: schemas.CardSchema = Body(...), + context: schemas.CurrentContext = Depends(OR_context)): data = custom_metrics.update_card( project_id=projectId, user_id=context.user_id, metric_id=metric_id, data=data ) @@ -308,12 +231,8 @@ def update_card( @app.post("/{projectId}/cards/{metric_id}/status", tags=["dashboard"]) -def update_card_state( - projectId: int, - metric_id: int, - data: schemas.UpdateCardStatusSchema = Body(...), - context: schemas.CurrentContext = Depends(OR_context), -): +def update_card_state(projectId: int, metric_id: int, data: schemas.UpdateCardStatusSchema = Body(...), + context: schemas.CurrentContext = Depends(OR_context)): return { "data": custom_metrics.change_state( project_id=projectId, @@ -325,12 +244,7 @@ def update_card_state( @app.delete("/{projectId}/cards/{metric_id}", tags=["dashboard"]) -def delete_card( - projectId: int, - metric_id: int, - _=Body(None), - context: schemas.CurrentContext = Depends(OR_context), -): +def delete_card(projectId: int, metric_id: int, _=Body(None), context: schemas.CurrentContext = Depends(OR_context)): return { "data": custom_metrics.delete_card( project_id=projectId, user_id=context.user_id, metric_id=metric_id diff --git a/ee/api/chalicelib/core/sessions/sessions_search_exp.py b/ee/api/chalicelib/core/sessions/sessions_search_exp.py index ecca97821..c1b25caba 100644 --- a/ee/api/chalicelib/core/sessions/sessions_search_exp.py +++ b/ee/api/chalicelib/core/sessions/sessions_search_exp.py @@ -201,7 +201,8 @@ def search_sessions(data: schemas.SessionsSearchPayloadSchema, project: schemas. return { 'total': total, - 'sessions': sessions_list + 'sessions': sessions_list, + 'src': 2 } diff --git a/ee/scripts/schema/db/init_dbs/postgresql/1.22.0/1.22.0.sql b/ee/scripts/schema/db/init_dbs/postgresql/1.22.0/1.22.0.sql index fbedb48a0..460cebf6d 100644 --- a/ee/scripts/schema/db/init_dbs/postgresql/1.22.0/1.22.0.sql +++ b/ee/scripts/schema/db/init_dbs/postgresql/1.22.0/1.22.0.sql @@ -41,6 +41,10 @@ WHERE metric_of IN ('domainsErrors4xx', 'domainsErrors5xx', 'countSessions', 'speedLocation', 'avgVisitedPages') OR metric_type IN ('webVitals', 'errors', 'performance', 'resources'); +UPDATE public.metrics +SET view_type='chart' +WHERE metric_type = 'funnel'; + COMMIT; \elif :is_next diff --git a/frontend/app/components/Dashboard/components/CardUserList/SessionsModal/SessionsModal.tsx b/frontend/app/components/Dashboard/components/CardUserList/SessionsModal/SessionsModal.tsx index 5cba5f2a2..ff5b2c9f8 100644 --- a/frontend/app/components/Dashboard/components/CardUserList/SessionsModal/SessionsModal.tsx +++ b/frontend/app/components/Dashboard/components/CardUserList/SessionsModal/SessionsModal.tsx @@ -102,7 +102,7 @@ function SessionsModal(props: Props) { ))} -
;
-
- case 'cog':
- return ;
+
+
+ case 'cog': return