fix(dashboards): stabilize grid layout and remove owners N+1 fallback

This commit is contained in:
2026-02-28 10:46:47 +03:00
parent 066747de59
commit 7e43830144
2 changed files with 104 additions and 75 deletions

View File

@@ -14,7 +14,7 @@ import json
import re
import zipfile
from pathlib import Path
from typing import Dict, List, Optional, Tuple, Union, cast
from typing import Any, Dict, List, Optional, Tuple, Union, cast
from requests import Response
from datetime import datetime
from .logger import logger as app_logger, belief_scope
@@ -87,7 +87,17 @@ class SupersetClient:
app_logger.info("[get_dashboards][Enter] Fetching dashboards.")
validated_query = self._validate_query_params(query or {})
if 'columns' not in validated_query:
validated_query['columns'] = ["slug", "id", "changed_on_utc", "dashboard_title", "published"]
validated_query['columns'] = [
"slug",
"id",
"changed_on_utc",
"dashboard_title",
"published",
"created_by",
"changed_by",
"changed_by_name",
"owners",
]
paginated_data = self._fetch_all_pages(
endpoint="/dashboard/",
@@ -105,53 +115,56 @@ class SupersetClient:
# @RETURN: List[Dict]
def get_dashboards_summary(self) -> List[Dict]:
with belief_scope("SupersetClient.get_dashboards_summary"):
query = {
"columns": [
"id",
"dashboard_title",
"changed_on_utc",
"published",
"created_by",
"created_by_name",
"changed_by",
"changed_by_name",
"owners",
]
}
# Rely on list endpoint default projection to stay compatible
# across Superset versions and preserve owners in one request.
query: Dict[str, Any] = {}
_, dashboards = self.get_dashboards(query=query)
# Map fields to DashboardMetadata schema
result = []
for dash in dashboards:
owners = self._extract_owner_labels(dash.get("owners"))
# No per-dashboard detail requests here: keep list endpoint O(1).
if not owners:
owners = self._extract_owner_labels(
[dash.get("created_by"), dash.get("changed_by")],
)
result.append({
"id": dash.get("id"),
"title": dash.get("dashboard_title"),
"last_modified": dash.get("changed_on_utc"),
"status": "published" if dash.get("published") else "draft",
"created_by": self._extract_user_display(
dash.get("created_by_name"),
None,
dash.get("created_by"),
),
"modified_by": self._extract_user_display(
dash.get("changed_by_name"),
dash.get("changed_by"),
),
"owners": self._extract_owner_labels(dash.get("owners")),
"owners": owners,
})
return result
# [/DEF:get_dashboards_summary:Function]
# [DEF:_extract_owner_labels:Function]
# @PURPOSE: Normalize dashboard owners payload to stable display labels.
# @PRE: owners payload can be None, list of dicts or list of strings.
# @PRE: owners payload can be scalar, object or list.
# @POST: Returns deduplicated non-empty owner labels preserving order.
# @RETURN: List[str]
def _extract_owner_labels(self, owners_payload: Optional[List[Union[Dict, str]]]) -> List[str]:
if not isinstance(owners_payload, list):
def _extract_owner_labels(self, owners_payload: Any) -> List[str]:
if owners_payload is None:
return []
owners_list: List[Any]
if isinstance(owners_payload, list):
owners_list = owners_payload
else:
owners_list = [owners_payload]
normalized: List[str] = []
for owner in owners_payload:
for owner in owners_list:
label: Optional[str] = None
if isinstance(owner, dict):
label = self._extract_user_display(None, owner)