Fix metric display: use displayName in list, render HTML in modal
List view:
- Show display_name ("M1 + VFM Operational") instead of name ("M1PlusVFMOperational")
- Strip HTML and truncate description for clean list excerpts
Modal detail:
- Render original HTML from catalog instead of stripped plain text
- Add .om-description CSS class for structured HTML (bold labels, lists, code)
- Pass description_html alongside plain text description for backwards compat
This commit is contained in:
parent
ad525a96aa
commit
9be22fdc82
5 changed files with 56 additions and 4 deletions
|
|
@ -319,6 +319,7 @@ def metric_to_display_dict(raw_metric: Dict[str, Any]) -> Dict[str, Any]:
|
|||
Parse raw OpenMetadata metric for metric list display in webapp.
|
||||
|
||||
Returns a lightweight dict for listing metrics (not full detail).
|
||||
Description is stripped of HTML and truncated for list view.
|
||||
|
||||
Args:
|
||||
raw_metric: Raw metric dict from OpenMetadata API
|
||||
|
|
@ -332,10 +333,15 @@ def metric_to_display_dict(raw_metric: Dict[str, Any]) -> Dict[str, Any]:
|
|||
description = raw_metric.get("description", "") or ""
|
||||
tags = raw_metric.get("tags", [])
|
||||
|
||||
# Strip HTML and truncate for list excerpt
|
||||
clean_desc = strip_html(description)
|
||||
if len(clean_desc) > 150:
|
||||
clean_desc = clean_desc[:147] + "..."
|
||||
|
||||
return {
|
||||
"name": name,
|
||||
"display_name": display_name,
|
||||
"description": description,
|
||||
"description": clean_desc,
|
||||
"grain": extract_grain(raw_metric),
|
||||
"category": extract_category(tags),
|
||||
"path": f"catalog:{fqn}",
|
||||
|
|
@ -376,6 +382,7 @@ def metric_to_detail_dict(raw_metric: Dict[str, Any], category_colors: Optional[
|
|||
},
|
||||
"overview": {
|
||||
"description": strip_html(description),
|
||||
"description_html": description,
|
||||
"key_insights": [],
|
||||
},
|
||||
"validation": None,
|
||||
|
|
|
|||
|
|
@ -829,7 +829,7 @@ def _build_om_metric_detail(raw_metric: dict) -> dict:
|
|||
"category": category,
|
||||
"category_color": category_colors.get(category, "#6B7280"),
|
||||
"metadata": {"type": metric_type, "unit": unit, "grain": grain, "time_column": ""},
|
||||
"overview": {"description": description.strip(), "key_insights": []},
|
||||
"overview": {"description": description.strip(), "description_html": description.strip(), "key_insights": []},
|
||||
"validation": None,
|
||||
"dimensions": dimensions,
|
||||
"notes": {"all": [], "key_insights": []},
|
||||
|
|
|
|||
|
|
@ -330,6 +330,46 @@
|
|||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* OpenMetadata HTML description (rendered from catalog) */
|
||||
.om-description {
|
||||
font-size: 15px;
|
||||
line-height: 1.7;
|
||||
color: #374151;
|
||||
}
|
||||
|
||||
.om-description p {
|
||||
margin: 0 0 12px 0;
|
||||
}
|
||||
|
||||
.om-description p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.om-description strong {
|
||||
color: #111827;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.om-description ul,
|
||||
.om-description ol {
|
||||
margin: 8px 0 12px 0;
|
||||
padding-left: 24px;
|
||||
}
|
||||
|
||||
.om-description li {
|
||||
margin-bottom: 4px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.om-description code {
|
||||
background: #F3F4F6;
|
||||
color: #0073D1;
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
font-family: 'Monaco', 'Menlo', monospace;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* Dimension Pills */
|
||||
.metric-dimensions {
|
||||
display: flex;
|
||||
|
|
|
|||
|
|
@ -148,12 +148,17 @@ function renderMetricModal(data) {
|
|||
function renderOverviewTab(data) {
|
||||
const keyInsights = data.notes.key_insights || data.notes.all.slice(0, 5);
|
||||
|
||||
// Prefer rendered HTML from catalog over stripped plain text
|
||||
const descriptionContent = data.overview.description_html
|
||||
? `<div class="om-description">${data.overview.description_html}</div>`
|
||||
: `<p>${escapeHtml(data.overview.description)}</p>`;
|
||||
|
||||
return `
|
||||
<div id="tabOverview" class="metric-tab-content">
|
||||
<div class="metric-section">
|
||||
<h3 class="metric-section-header">What it measures</h3>
|
||||
<div class="metric-section-content">
|
||||
<p>${data.overview.description}</p>
|
||||
${descriptionContent}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1415,7 +1415,7 @@
|
|||
{% for metric in category.metrics %}
|
||||
<div class="table-row" onclick="openMetricModal('{{ metric.path }}')">
|
||||
<div class="table-row-left">
|
||||
<div class="table-row-name">{{ metric.name }}</div>
|
||||
<div class="table-row-name">{{ metric.display_name }}</div>
|
||||
<div class="table-row-desc">{{ metric.description }}</div>
|
||||
</div>
|
||||
<div class="table-row-right">
|
||||
|
|
|
|||
Loading…
Reference in a new issue