Blast radius UI: Changed matched items lists into tabs
Bug: b/483560331
Change-Id: I62bd998df896729477b1a7f31e47d4d135d335af
diff --git a/src/blastradius/web/main.js b/src/blastradius/web/main.js
index 9b85992..a8d2356 100644
--- a/src/blastradius/web/main.js
+++ b/src/blastradius/web/main.js
@@ -6,6 +6,7 @@
let filteredRules = [];
let filteredFiles = [];
let currentView = 'rules'; // 'rules', 'files', 'unused', 'redundant'
+let currentSubView = 'class'; // 'class', 'method', 'field'
let currentSelectedRule = null;
let currentRulePagination = {
classes: 100,
@@ -402,6 +403,7 @@
document.querySelectorAll('.rule-item').forEach(el => el.classList.remove('active'));
element.classList.add('active');
currentSelectedRule = rule;
+ currentSubView = 'class';
currentRulePagination = {
classes: 100,
methods: 100,
@@ -442,6 +444,17 @@
<div class="keep-rule-source">${escapeHtml(rule.source)}</div>
<p><strong>Origin:</strong> ${escapeHtml(getOriginString(rule.origin))}</p>
</div>
+ <div class="sub-tabs">
+ <button class="sub-tab-button ${currentSubView === 'class' ? 'active' : ''}" onclick="switchSubView('class')">
+ Matched Classes <span class="badge">${rule.blastRadius.classBlastRadius?.length || 0}</span>
+ </button>
+ <button class="sub-tab-button ${currentSubView === 'method' ? 'active' : ''}" onclick="switchSubView('method')">
+ Matched Methods <span class="badge">${rule.blastRadius.methodBlastRadius?.length || 0}</span>
+ </button>
+ <button class="sub-tab-button ${currentSubView === 'field' ? 'active' : ''}" onclick="switchSubView('field')">
+ Matched Fields <span class="badge">${rule.blastRadius.fieldBlastRadius?.length || 0}</span>
+ </button>
+ </div>
`;
html += renderBlastRadiusItems(rule.blastRadius);
@@ -474,13 +487,19 @@
let html = "";
const renderSection = (title, items, type, formatter, badgeClass, limit) => {
- if (!items || items.length === 0) return "";
+ if (currentSubView !== type) return "";
+ if (!items || items.length === 0) {
+ return `
+ <div class="card">
+ <p style="color: #666; font-style: italic;">No items matched this category.</p>
+ </div>
+ `;
+ }
const visibleItems = items.slice(0, limit);
const hasMore = items.length > limit;
return `
<div class="card">
- <div class="section-title">${title} <span class="badge ${badgeClass}">${items.length}</span></div>
<ul class="item-list">
${visibleItems.map(id => {
const info = type === 'class' ? tables.classes.get(id) :
@@ -566,6 +585,13 @@
}
}
+function switchSubView(subView) {
+ currentSubView = subView;
+ if (currentSelectedRule) {
+ renderRuleDetail(currentSelectedRule);
+ }
+}
+
function renderStatsOverview() {
const template = document.getElementById('stats-overview-template');
mainContent.innerHTML = '';
diff --git a/src/blastradius/web/style.css b/src/blastradius/web/style.css
index 7fa15e1..940b0db 100644
--- a/src/blastradius/web/style.css
+++ b/src/blastradius/web/style.css
@@ -327,3 +327,30 @@
height: 100%;
color: #666;
}
+
+.sub-tabs {
+ display: flex;
+ border-bottom: 1px solid #ddd;
+ margin-bottom: 1rem;
+}
+
+.sub-tab-button {
+ background: none;
+ border: none;
+ padding: 0.75rem 1.5rem;
+ cursor: pointer;
+ font-size: 0.9rem;
+ font-weight: 500;
+ color: #666;
+ border-bottom: 2px solid transparent;
+}
+
+.sub-tab-button:hover {
+ color: #3f51b5;
+ background-color: #f0f0f0;
+}
+
+.sub-tab-button.active {
+ color: #3f51b5;
+ border-bottom: 2px solid #3f51b5;
+}