feat(api): dashboard re-think 1/5
This commit is contained in:
parent
cc08060e30
commit
8e1f93630c
8 changed files with 119 additions and 51 deletions
|
|
@ -9,10 +9,9 @@ from starlette.responses import StreamingResponse
|
|||
from chalicelib.utils import helper
|
||||
from chalicelib.utils import pg_client
|
||||
from routers import core, core_dynamic
|
||||
from routers.app import v1_api
|
||||
from routers.crons import core_crons
|
||||
from routers.crons import core_dynamic_crons
|
||||
from routers.subs import dashboard, insights, metrics
|
||||
from routers.subs import dashboard, insights, metrics, v1_api
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
|
|
|||
|
|
@ -77,13 +77,17 @@ def add_widget(project_id, user_id, dashboard_id, data: schemas.AddWidgetToDashb
|
|||
row = cur.fetchone()
|
||||
return helper.dict_to_camel_case(row)
|
||||
|
||||
# def get_widgets(project_id):
|
||||
# with pg_client.PostgresClient() as cur:
|
||||
# pg_query = f"""SELECT *
|
||||
# FROM widgets
|
||||
# WHERE deleted_at ISNULL
|
||||
# AND project_id = %(projectId)s;"""
|
||||
# params = {"projectId": project_id}
|
||||
# cur.execute(cur.mogrify(pg_query, params))
|
||||
# rows = cur.fetchall()
|
||||
# return helper.list_to_camel_case(rows)
|
||||
def remove_widget(project_id, user_id, dashboard_id,widget_id):
|
||||
ref_key = "metric_id"
|
||||
if data.template_id is not None:
|
||||
ref_key = "template_id"
|
||||
with pg_client.PostgresClient() as cur:
|
||||
pg_query = f"""INSERT INTO dashboard_widgets(dashboard_id, {ref_key}, user_id, configuration, name)
|
||||
VALUES (%(dashboard_id)s, %({ref_key})s, %(userId)s, %(configuration)s::jsonb, %(name)s)
|
||||
RETURNING *;"""
|
||||
params = {"userId": user_id, "projectId": project_id, "dashboard_id": dashboard_id, **data.dict()}
|
||||
params["configuration"] = json.dumps(params.get("configuration", {}))
|
||||
cur.execute(cur.mogrify(pg_query, params))
|
||||
row = cur.fetchone()
|
||||
return helper.dict_to_camel_case(row)
|
||||
|
||||
|
|
|
|||
|
|
@ -6,12 +6,13 @@ CATEGORY_DESCRIPTION = {
|
|||
}
|
||||
|
||||
|
||||
def get_templates():
|
||||
def get_templates(project_id, user_id):
|
||||
with pg_client.PostgresClient() as cur:
|
||||
pg_query = f"""SELECT category, jsonb_agg(templates ORDER BY name) AS widgets
|
||||
FROM templates
|
||||
pg_query = cur.mogrify(f"""SELECT category, jsonb_agg(metrics ORDER BY name) AS widgets
|
||||
FROM metrics
|
||||
WHERE project_id ISNULL OR (project_id = %(project_id)s AND (is_public OR user_id= %(userId)s))
|
||||
GROUP BY category
|
||||
ORDER BY category;"""
|
||||
ORDER BY category;""", {"project_id": project_id, "userId": user_id})
|
||||
cur.execute(pg_query)
|
||||
rows = cur.fetchall()
|
||||
for r in rows:
|
||||
|
|
|
|||
|
|
@ -21,15 +21,23 @@ def get_dashboards(projectId: int, context: schemas.CurrentContext = Depends(OR_
|
|||
|
||||
|
||||
@app.get('/{projectId}/dashboards/{dashboardId}', tags=["dashboard", "metrics"])
|
||||
def get_dashboards(projectId: int, dashboardId: int, context: schemas.CurrentContext = Depends(OR_context)):
|
||||
def get_dashboard(projectId: int, dashboardId: int, context: schemas.CurrentContext = Depends(OR_context)):
|
||||
return {"data": dashboards2.get_dashboard(project_id=projectId, user_id=context.user_id, dashboard_id=dashboardId)}
|
||||
|
||||
|
||||
@app.post('/{projectId}/dashboards/{dashboardId}/metrics', tags=["dashboard", "metrics"])
|
||||
@app.put('/{projectId}/dashboards/{dashboardId}/metrics', tags=["dashboard", "metrics"])
|
||||
def add_widget_to_dashboards(projectId: int, dashboardId: int,
|
||||
data: schemas.AddWidgetToDashboardPayloadSchema = Body(...),
|
||||
context: schemas.CurrentContext = Depends(OR_context)):
|
||||
def add_widget_to_dashboard(projectId: int, dashboardId: int,
|
||||
data: schemas.AddWidgetToDashboardPayloadSchema = Body(...),
|
||||
context: schemas.CurrentContext = Depends(OR_context)):
|
||||
return {"data": dashboards2.add_widget(project_id=projectId, user_id=context.user_id, dashboard_id=dashboardId,
|
||||
data=data)}
|
||||
|
||||
|
||||
@app.delete('/{projectId}/dashboards/{dashboardId}/metrics/{metricId}', tags=["dashboard", "metrics"])
|
||||
def remove_widget_from_dashboard(projectId: int, dashboardId: int, metricId: int,
|
||||
data: schemas.AddWidgetToDashboardPayloadSchema = Body(...),
|
||||
context: schemas.CurrentContext = Depends(OR_context)):
|
||||
return {"data": dashboards2.add_widget(project_id=projectId, user_id=context.user_id, dashboard_id=dashboardId,
|
||||
data=data)}
|
||||
|
||||
|
|
@ -41,7 +49,7 @@ def add_widget_to_dashboards(projectId: int, dashboardId: int,
|
|||
|
||||
@app.get('/{projectId}/metrics/templates', tags=["dashboard", "metrics"])
|
||||
def get_templates(projectId: int, context: schemas.CurrentContext = Depends(OR_context)):
|
||||
return {"data": templates.get_templates()}
|
||||
return {"data": templates.get_templates(project_id=projectId, user_id=context.user_id)}
|
||||
|
||||
|
||||
@app.post('/{projectId}/metrics/try', tags=["dashboard"])
|
||||
|
|
|
|||
|
|
@ -6,38 +6,86 @@ SELECT 'v1.5.5'
|
|||
$$ LANGUAGE sql IMMUTABLE;
|
||||
|
||||
|
||||
CREATE TABLE dashboards
|
||||
-- CREATE TABLE dashboards
|
||||
-- (
|
||||
-- dashboard_id integer generated BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
-- project_id integer NOT NULL REFERENCES projects (project_id) ON DELETE CASCADE,
|
||||
-- user_id integer NOT NULL REFERENCES users (user_id) ON DELETE SET NULL,
|
||||
-- name text NOT NULL,
|
||||
-- is_public boolean NOT NULL DEFAULT TRUE,
|
||||
-- is_pinned boolean NOT NULL DEFAULT FALSE,
|
||||
-- created_at timestamp NOT NULL DEFAULT timezone('utc'::text, now()),
|
||||
-- deleted_at timestamp NULL DEFAULT NULL
|
||||
-- );
|
||||
|
||||
-- CREATE TABLE templates
|
||||
-- (
|
||||
-- template_id integer generated BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
-- template_key text,
|
||||
-- name text NOT NULL,
|
||||
-- category text NOT NULL,
|
||||
-- series jsonb NOT NULL,
|
||||
-- config jsonb NOT NULL,
|
||||
-- predefined boolean DEFAULT TRUE
|
||||
-- );
|
||||
|
||||
-- CREATE TABLE dashboard_widgets
|
||||
-- (
|
||||
-- widget_id integer generated BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
-- dashboard_id integer NOT NULL REFERENCES dashboards (dashboard_id) ON DELETE CASCADE,
|
||||
-- metric_id integer NOT NULL REFERENCES metrics (metric_id) ON DELETE CASCADE,
|
||||
-- -- template_id integer NOT NULL REFERENCES templates (template_id) ON DELETE CASCADE,
|
||||
-- user_id integer NOT NULL REFERENCES users (user_id) ON DELETE SET NULL,
|
||||
-- created_at timestamp NOT NULL DEFAULT timezone('utc'::text, now()),
|
||||
-- configuration jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
-- name text
|
||||
-- );
|
||||
|
||||
-- INSERT INTO public.templates (name, category, series, config, predefined, template_key)
|
||||
-- VALUES ('captured sessions', 'overview', '[]', '{}', true, 'count_sessions'),
|
||||
-- ('request load time', 'overview', '[]', '{}', true, 'avg_request_load_time'),
|
||||
-- ('page load time', 'overview', '[]', '{}', true, 'avg_page_load_time'),
|
||||
-- ('image load time', 'overview', '[]', '{}', true, 'avg_image_load_time');
|
||||
|
||||
ALTER TYPE metric_view_type ADD VALUE IF NOT EXISTS 'areaChart';
|
||||
|
||||
ALTER TABLE IF EXISTS metrics
|
||||
DROP CONSTRAINT IF EXISTS null_project_id_for_template_only;
|
||||
|
||||
ALTER TABLE IF EXISTS metrics
|
||||
ADD COLUMN IF NOT EXISTS category text NULL DEFAULT 'custom',
|
||||
ADD COLUMN IF NOT EXISTS is_predefined boolean NOT NULL DEFAULT FALSE,
|
||||
ADD COLUMN IF NOT EXISTS is_template boolean NOT NULL DEFAULT FALSE,
|
||||
ADD COLUMN IF NOT EXISTS key text NULL DEFAULT NULL,
|
||||
ADD COLUMN IF NOT EXISTS config jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
ALTER COLUMN project_id DROP NOT NULL,
|
||||
ADD CONSTRAINT null_project_id_for_template_only
|
||||
CHECK ( (metrics.category != 'custom') != (metrics.project_id IS NOT NULL) );
|
||||
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS dashboard_widgets
|
||||
(
|
||||
dashboard_id integer generated BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
project_id integer NOT NULL REFERENCES projects (project_id) ON DELETE CASCADE,
|
||||
widget_id integer generated BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
dashboard_id integer NOT NULL REFERENCES dashboards (dashboard_id) ON DELETE CASCADE,
|
||||
metric_id integer NOT NULL REFERENCES metrics (metric_id) ON DELETE CASCADE,
|
||||
user_id integer NOT NULL REFERENCES users (user_id) ON DELETE SET NULL,
|
||||
name text NOT NULL,
|
||||
is_public boolean NOT NULL DEFAULT TRUE,
|
||||
is_pinned boolean NOT NULL DEFAULT FALSE,
|
||||
created_at timestamp NOT NULL DEFAULT timezone('utc'::text, now()),
|
||||
deleted_at timestamp NULL DEFAULT NULL
|
||||
config jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
name text
|
||||
);
|
||||
|
||||
-- INSERT INTO public.templates (name, category, series, config, predefined, template_key)
|
||||
-- VALUES ('captured sessions', 'overview', '[]', '{}', true, 'count_sessions'),
|
||||
-- ('request load time', 'overview', '[]', '{}', true, 'avg_request_load_time'),
|
||||
-- ('page load time', 'overview', '[]', '{}', true, 'avg_page_load_time'),
|
||||
-- ('image load time', 'overview', '[]', '{}', true, 'avg_image_load_time');
|
||||
|
||||
CREATE TABLE widgets
|
||||
(
|
||||
widget_id integer generated BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
project_id integer NOT NULL REFERENCES projects (project_id) ON DELETE CASCADE,
|
||||
user_id integer NOT NULL REFERENCES users (user_id) ON DELETE SET NULL,
|
||||
name text NOT NULL,
|
||||
is_template boolean NOT NULL DEFAULT FALSE,
|
||||
predefined boolean NOT NULL DEFAULT FALSE,
|
||||
created_at timestamp NOT NULL DEFAULT timezone('utc'::text, now()),
|
||||
deleted_at timestamp NULL DEFAULT NULL
|
||||
);
|
||||
INSERT INTO metrics (name, category, config, is_predefined, is_template, is_public, key)
|
||||
VALUES ('captured sessions', 'overview', '{}', true, true, true, 'count_sessions'),
|
||||
('request load time', 'overview', '{}', true, true, true, 'avg_request_load_time'),
|
||||
('page load time', 'overview', '{}', true, true, true, 'avg_page_load_time'),
|
||||
('image load time', 'overview', '{}', true, true, true, 'avg_image_load_time');
|
||||
|
||||
CREATE TABLE dashboard_widgets
|
||||
(
|
||||
dashboard_id integer NOT NULL REFERENCES dashboards (dashboard_id) ON DELETE CASCADE,
|
||||
widget_id integer NOT NULL REFERENCES widgets (widget_id) ON DELETE CASCADE,
|
||||
user_id integer NOT NULL REFERENCES users (user_id) ON DELETE SET NULL,
|
||||
created_at timestamp NOT NULL DEFAULT timezone('utc'::text, now()),
|
||||
configuration jsonb NOT NULL DEFAULT '{}'::jsonb
|
||||
);
|
||||
|
||||
COMMIT;
|
||||
COMMIT
|
||||
|
|
@ -936,11 +936,11 @@ $$
|
|||
CREATE INDEX jobs_project_id_idx ON jobs (project_id);
|
||||
|
||||
CREATE TYPE metric_type AS ENUM ('timeseries','table');
|
||||
CREATE TYPE metric_view_type AS ENUM ('lineChart','progress','table','pieChart');
|
||||
CREATE TYPE metric_view_type AS ENUM ('lineChart','progress','table','pieChart','areaChart');
|
||||
CREATE TABLE metrics
|
||||
(
|
||||
metric_id integer generated BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
project_id integer NOT NULL REFERENCES projects (project_id) ON DELETE CASCADE,
|
||||
project_id integer NULL REFERENCES projects (project_id) ON DELETE CASCADE,
|
||||
user_id integer REFERENCES users (user_id) ON DELETE SET NULL,
|
||||
name text NOT NULL,
|
||||
is_public boolean NOT NULL DEFAULT FALSE,
|
||||
|
|
@ -951,8 +951,16 @@ $$
|
|||
view_type metric_view_type NOT NULL DEFAULT 'lineChart',
|
||||
metric_of text NOT NULL DEFAULT 'sessionCount',
|
||||
metric_value text[] NOT NULL DEFAULT '{}'::text[],
|
||||
metric_format text
|
||||
metric_format text,
|
||||
category text NULL DEFAULT 'custom',
|
||||
is_predefined boolean NOT NULL DEFAULT FALSE,
|
||||
is_template boolean NOT NULL DEFAULT FALSE,
|
||||
key text NULL DEFAULT NULL,
|
||||
config jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
CONSTRAINT null_project_id_for_template_only
|
||||
CHECK ( (metrics.category != 'custom') != (metrics.project_id IS NOT NULL) )
|
||||
);
|
||||
|
||||
CREATE INDEX metrics_user_id_is_public_idx ON public.metrics (user_id, is_public);
|
||||
CREATE TABLE metric_series
|
||||
(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue