feat(analytics): expose full dashboard result groups
Some checks failed
Backend CI/CD / test (push) Has been cancelled
Backend CI/CD / deploy (push) Has been cancelled

This commit is contained in:
2026-06-15 17:33:30 +03:30
parent a326d2e31d
commit 08cab3b815
2 changed files with 26 additions and 10 deletions

View File

@@ -9,6 +9,7 @@ class AnalyticsPointSchema(Schema):
class AnalyticsPointGroupSchema(Schema): class AnalyticsPointGroupSchema(Schema):
items: list[AnalyticsPointSchema]
top_items: list[AnalyticsPointSchema] top_items: list[AnalyticsPointSchema]
other_count: int = 0 other_count: int = 0
total_count: int = 0 total_count: int = 0
@@ -46,6 +47,7 @@ class AnalyticsPostPopularitySchema(Schema):
class AnalyticsPostPopularityGroupSchema(Schema): class AnalyticsPostPopularityGroupSchema(Schema):
items: list[AnalyticsPostPopularitySchema]
top_items: list[AnalyticsPostPopularitySchema] top_items: list[AnalyticsPostPopularitySchema]
other_count: int = 0 other_count: int = 0
total_count: int = 0 total_count: int = 0

View File

@@ -114,13 +114,14 @@ def _normalize_entry_year(value) -> str:
def _point_group_from_rows(rows: list[dict], *, limit: int = TOP_ITEMS_LIMIT): def _point_group_from_rows(rows: list[dict], *, limit: int = TOP_ITEMS_LIMIT):
sorted_rows = sorted(rows, key=lambda item: (-int(item["value"] or 0), str(item["label"]))) sorted_rows = sorted(rows, key=lambda item: (-int(item["value"] or 0), str(item["label"])))
top_rows = sorted_rows[:limit]
other_rows = sorted_rows[limit:] other_rows = sorted_rows[limit:]
items = [
{"label": _label(item["label"]), "value": int(item["value"] or 0)}
for item in sorted_rows
]
return { return {
"top_items": [ "items": items,
{"label": _label(item["label"]), "value": int(item["value"] or 0)} "top_items": items[:limit],
for item in top_rows
],
"other_count": len(other_rows), "other_count": len(other_rows),
"total_count": len(sorted_rows), "total_count": len(sorted_rows),
} }
@@ -147,13 +148,14 @@ def _point_group_queryset(queryset, label_field: str, *, limit: int = TOP_ITEMS_
.order_by("-value", label_field) .order_by("-value", label_field)
) )
total_count = len(rows) total_count = len(rows)
top_rows = rows[:limit]
other_rows = rows[limit:] other_rows = rows[limit:]
items = [
{"label": _label(item.get(label_field)), "value": int(item["value"] or 0)}
for item in rows
]
return { return {
"top_items": [ "items": items,
{"label": _label(item.get(label_field)), "value": int(item["value"] or 0)} "top_items": items[:limit],
for item in top_rows
],
"other_count": len(other_rows), "other_count": len(other_rows),
"total_count": total_count, "total_count": total_count,
} }
@@ -502,6 +504,17 @@ def admin_blog_analytics(request, date_from: str | None = None, date_to: str | N
} }
for post in post_popularity_all[:TOP_ITEMS_LIMIT] for post in post_popularity_all[:TOP_ITEMS_LIMIT]
] ]
post_popularity_items = [
{
"id": post.id,
"title": post.title,
"slug": post.slug,
"likes": post.likes_total,
"saves": post.saves_total,
"comments": post.comments_total,
}
for post in post_popularity_all
]
top_posts = [ top_posts = [
{ {
**post, **post,
@@ -537,6 +550,7 @@ def admin_blog_analytics(request, date_from: str | None = None, date_to: str | N
}, },
"activity_trend": list(activity_buckets.values()), "activity_trend": list(activity_buckets.values()),
"post_popularity": { "post_popularity": {
"items": post_popularity_items,
"top_items": post_popularity, "top_items": post_popularity,
"other_count": max(len(post_popularity_all) - TOP_ITEMS_LIMIT, 0), "other_count": max(len(post_popularity_all) - TOP_ITEMS_LIMIT, 0),
"total_count": len(post_popularity_all), "total_count": len(post_popularity_all),