diff --git a/api/chalicelib/core/custom_metrics.py b/api/chalicelib/core/custom_metrics.py index ec6840217..464cafc26 100644 --- a/api/chalicelib/core/custom_metrics.py +++ b/api/chalicelib/core/custom_metrics.py @@ -118,7 +118,7 @@ schemas.CustomMetricSessionsPayloadSchema]) \ -> Union[schemas.CreateCardSchema, None]: if data.series is not None and len(data.series) > 0: metric["series"] = data.series - metric: schemas.CreateCardSchema = schemas.CreateCardSchema.parse_obj({**data.dict(), **metric}) + metric: schemas.CreateCardSchema = schemas.CreateCardSchema(**{**data.dict(), **metric}) if len(data.filters) > 0 or len(data.events) > 0: for s in metric.series: if len(data.filters) > 0: @@ -328,6 +328,8 @@ def update(metric_id, user_id, project_id, data: schemas.UpdateCardSchema): def search_all(project_id, user_id, data: schemas.SearchCardsSchema, include_series=False): + print('>>>>') + print(data) constraints = ["metrics.project_id = %(project_id)s", "metrics.deleted_at ISNULL"] params = {"project_id": project_id, "user_id": user_id, diff --git a/api/chalicelib/core/dashboards.py b/api/chalicelib/core/dashboards.py index d406fe550..fa04f0fad 100644 --- a/api/chalicelib/core/dashboards.py +++ b/api/chalicelib/core/dashboards.py @@ -6,43 +6,6 @@ from chalicelib.utils import helper from chalicelib.utils import pg_client from chalicelib.utils.TimeUTC import TimeUTC -# category name should be lower cased -CATEGORY_DESCRIPTION = { - 'web vitals': 'A set of metrics that assess app performance on criteria such as load time, load performance, and stability.', - 'custom': 'Previously created custom metrics by me and my team.', - 'errors': 'Keep a closer eye on errors and track their type, origin and domain.', - 'performance': 'Optimize your app’s performance by tracking slow domains, page response times, memory consumption, CPU usage and more.', - 'resources': 'Find out which resources are missing and those that may be slowing your web app.' -} - - -def get_templates(project_id, user_id): - with pg_client.PostgresClient() as cur: - pg_query = cur.mogrify(f"""SELECT category, jsonb_agg(metrics ORDER BY name) AS widgets - FROM (SELECT * , default_config AS config - FROM metrics LEFT JOIN LATERAL (SELECT COALESCE(jsonb_agg(metric_series.* ORDER BY index), '[]'::jsonb) AS series - FROM metric_series - WHERE metric_series.metric_id = metrics.metric_id - AND metric_series.deleted_at ISNULL - ) AS metric_series ON (TRUE) - WHERE deleted_at IS NULL - AND (project_id ISNULL OR (project_id = %(project_id)s AND (is_public OR user_id= %(userId)s))) - ) AS metrics - GROUP BY category - ORDER BY ARRAY_POSITION(ARRAY ['custom','overview','errors','performance','resources'], category);""", - {"project_id": project_id, "userId": user_id}) - cur.execute(pg_query) - rows = cur.fetchall() - for r in rows: - r["description"] = CATEGORY_DESCRIPTION.get(r["category"].lower(), "") - for w in r["widgets"]: - w["created_at"] = TimeUTC.datetime_to_timestamp(w["created_at"]) - w["edited_at"] = TimeUTC.datetime_to_timestamp(w["edited_at"]) - for s in w["series"]: - s["filter"] = helper.old_search_payload_to_flat(s["filter"]) - - return helper.list_to_camel_case(rows) - def create_dashboard(project_id, user_id, data: schemas.CreateDashboardSchema): with pg_client.PostgresClient() as cur: @@ -306,7 +269,7 @@ def make_chart_metrics(project_id, user_id, metric_id, data: schemas.CustomMetri include_dashboard=False) if raw_metric is None: return None - metric: schemas.CustomMetricAndTemplate = schemas.CustomMetricAndTemplate.parse_obj(raw_metric) + metric: schemas.CustomMetricAndTemplate = schemas.CustomMetricAndTemplate(**raw_metric) if metric.is_template and metric.predefined_key is None: return None if metric.is_template: @@ -320,7 +283,7 @@ def make_chart_widget(dashboard_id, project_id, user_id, widget_id, data: schema raw_metric = get_widget(widget_id=widget_id, project_id=project_id, user_id=user_id, dashboard_id=dashboard_id) if raw_metric is None: return None - metric = schemas.CustomMetricAndTemplate = schemas.CustomMetricAndTemplate.parse_obj(raw_metric) + metric = schemas.CustomMetricAndTemplate = schemas.CustomMetricAndTemplate(**raw_metric) if metric.is_template: return get_predefined_metric(key=metric.predefined_key, project_id=project_id, data=data.dict()) else: diff --git a/api/routers/subs/metrics.py b/api/routers/subs/metrics.py index b015f31b2..65404662b 100644 --- a/api/routers/subs/metrics.py +++ b/api/routers/subs/metrics.py @@ -92,11 +92,6 @@ def get_widget_chart(projectId: int, dashboardId: int, widgetId: int, return {"data": data} -@app.get('/{projectId}/metrics/templates', tags=["dashboard"]) -def get_templates(projectId: int, context: schemas.CurrentContext = Depends(OR_context)): - return {"data": dashboards.get_templates(project_id=projectId, user_id=context.user_id)} - - @app.post('/{projectId}/metrics/try', tags=["dashboard"]) @app.put('/{projectId}/metrics/try', tags=["dashboard"]) @app.post('/{projectId}/custom_metrics/try', tags=["customMetrics"]) @@ -126,6 +121,14 @@ def try_custom_metric_funnel_issues(projectId: int, data: schemas.CustomMetricSe return {"data": data} +@app.get('/{projectId}/cards', tags=["cards"]) +@app.get('/{projectId}/metrics', tags=["dashboard"]) +@app.get('/{projectId}/custom_metrics', tags=["customMetrics"]) +def get_cards(projectId: int, context: schemas.CurrentContext = Depends(OR_context)): + return {"data": custom_metrics.search_all(project_id=projectId, user_id=context.user_id, + data=schemas.SearchCardsSchema())} + + @app.post('/{projectId}/cards', tags=["cards"]) @app.post('/{projectId}/metrics', tags=["dashboard"]) @app.put('/{projectId}/metrics', tags=["dashboard"]) @@ -201,11 +204,11 @@ def get_custom_metric_errors_list(projectId: int, metric_id: int, return {"data": data} -@app.post('/{projectId}/cards/{metric_id}/chart', tags=["dashboard"]) +@app.post('/{projectId}/cards/{metric_id}/chart', tags=["card"]) @app.post('/{projectId}/metrics/{metric_id}/chart', tags=["dashboard"]) @app.post('/{projectId}/custom_metrics/{metric_id}/chart', tags=["customMetrics"]) -def get_custom_metric_chart(projectId: int, metric_id: int, data: schemas.CustomMetricChartPayloadSchema = Body(...), - context: schemas.CurrentContext = Depends(OR_context)): +def get_card_chart(projectId: int, metric_id: int, data: schemas.CustomMetricChartPayloadSchema = Body(...), + context: schemas.CurrentContext = Depends(OR_context)): data = dashboards.make_chart_metrics(project_id=projectId, user_id=context.user_id, metric_id=metric_id, data=data) if data is None: diff --git a/api/schemas.py b/api/schemas.py index 865573fc3..7ed8df648 100644 --- a/api/schemas.py +++ b/api/schemas.py @@ -947,6 +947,11 @@ class CreateCardSchema(CustomMetricChartPayloadSchema): f"viewType must be of type {MetricTimeseriesViewType} for metricType:{MetricType.timeseries}" assert isinstance(values.get("metric_of"), MetricOfTimeseries), \ f"metricOf must be of type {MetricOfTimeseries} for metricType:{MetricType.timeseries}" + elif values.get("metric_type") == MetricType.funnel: + # assert isinstance(values.get("view_type"), MetricTimeseriesViewType), \ + # f"viewType must be of type {MetricTimeseriesViewType} for metricType:{MetricType.timeseries}" + assert isinstance(values.get("metric_of"), MetricOfTimeseries), \ + f"metricOf must be of type {MetricOfTimeseries} for metricType:{MetricType.funnel}" else: if values.get("metric_type") == MetricType.errors: assert isinstance(values.get("metric_of"), MetricOfErrors), \ @@ -1083,6 +1088,11 @@ class CustomMetricAndTemplate(BaseModel): project_id: Optional[int] = Field(...) predefined_key: Optional[TemplatePredefinedKeys] = Field(...) + @root_validator(pre=True) + def transform(cls, values): + values["isTemplate"] = values["metricType"] not in [MetricType.timeseries, MetricType.table, MetricType.funnel] + return values + class Config: alias_generator = attribute_to_camel_case