Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 54 additions & 12 deletions src/DotNetApiDiff/Reporting/HtmlTemplates/main-layout.scriban
Original file line number Diff line number Diff line change
Expand Up @@ -56,22 +56,50 @@
<section class="summary">
<h2>📈 Summary</h2>
<div class="summary-cards">
{{if result.summary.added_count > 0}}
<div class="summary-card added clickable" onclick="navigateToSection('added-items')">
<div class="card-number">{{ result.summary.added_count }}</div>
<div class="card-label">Added</div>
</div>
{{else}}
<div class="summary-card added">
<div class="card-number">{{ result.summary.added_count }}</div>
<div class="card-label">Added</div>
</div>
{{end}}
{{if result.summary.removed_count > 0}}
<div class="summary-card removed clickable" onclick="navigateToSection('removed-items')">
<div class="card-number">{{ result.summary.removed_count }}</div>
<div class="card-label">Removed</div>
</div>
{{else}}
<div class="summary-card removed">
<div class="card-number">{{ result.summary.removed_count }}</div>
<div class="card-label">Removed</div>
</div>
{{end}}
{{if result.summary.modified_count > 0}}
<div class="summary-card modified clickable" onclick="navigateToSection('modified-items')">
<div class="card-number">{{ result.summary.modified_count }}</div>
<div class="card-label">Modified</div>
</div>
{{else}}
<div class="summary-card modified">
<div class="card-number">{{ result.summary.modified_count }}</div>
<div class="card-label">Modified</div>
</div>
{{end}}
{{if result.summary.breaking_changes_count > 0}}
<div class="summary-card breaking clickable" onclick="navigateToSection('breaking-changes')">
<div class="card-number">{{ result.summary.breaking_changes_count }}</div>
<div class="card-label">Breaking</div>
</div>
{{else}}
<div class="summary-card breaking">
<div class="card-number">{{ result.summary.breaking_changes_count }}</div>
<div class="card-label">Breaking</div>
</div>
{{end}}
</div>
</section>

Expand All @@ -91,13 +119,19 @@

<!-- Breaking changes section -->
{{if result.has_breaking_changes}}
<section class="breaking-changes">
<h2>⚠️ Breaking Changes</h2>
<div class="alert alert-danger">
<strong>Warning:</strong> The following changes may break compatibility with existing code.
<section class="breaking-changes" id="breaking-changes">
<div class="section-header">
<h2>⚠️ Breaking Changes</h2>
<button class="section-toggle collapsed" onclick="toggleSection('breaking-changes')">
<span class="toggle-icon">▶</span>
</button>
</div>
<!-- Breaking changes content directly inline for debugging -->
<div class="breaking-changes-table">
<div class="section-content collapsed" id="breaking-changes-content">
<div class="alert alert-danger">
<strong>Warning:</strong> The following changes may break compatibility with existing code.
</div>
<!-- Breaking changes content directly inline for debugging -->
<div class="breaking-changes-table">
<table>
<thead>
<tr>
Expand All @@ -119,17 +153,25 @@
</tbody>
</table>
</div>
</div>
</section>
{{end}}

<!-- Change sections -->
{{for section in change_sections}}
<section class="changes-section">
<h2>{{ section.icon }} {{ section.title }} ({{ section.count }})</h2>
{{if section.description}}
<p class="section-description">{{ section.description }}</p>
{{end}}
{{ render_change_group section }}
<section class="changes-section" id="{{ section.change_type }}-items">
<div class="section-header">
<h2>{{ section.icon }} {{ section.title }} ({{ section.count }})</h2>
<button class="section-toggle collapsed" onclick="toggleSection('{{ section.change_type }}-items')">
<span class="toggle-icon">▶</span>
</button>
</div>
<div class="section-content collapsed" id="{{ section.change_type }}-items-content">
{{if section.description}}
<p class="section-description">{{ section.description }}</p>
{{end}}
{{ render_change_group section }}
</div>
</section>
{{end}}
</div>
Expand Down
101 changes: 101 additions & 0 deletions src/DotNetApiDiff/Reporting/HtmlTemplates/scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,104 @@ function toggleConfig() {
text.textContent = 'Show Configuration Details';
}
}

// Session storage helpers
function setSectionState(sectionId, state) {
try {
sessionStorage.setItem('section-' + sectionId, state);
} catch (e) {
// Ignore storage errors
}
}

function getSectionState(sectionId) {
try {
return sessionStorage.getItem('section-' + sectionId);
} catch (e) {
return null;
}
}

// New collapsible section functionality
function toggleSection(sectionId) {
const section = document.getElementById(sectionId);
const content = document.getElementById(sectionId + '-content');
const button = section.querySelector('.section-toggle');
const icon = button.querySelector('.toggle-icon');

if (content.classList.contains('collapsed')) {
// Expand section
content.classList.remove('collapsed');
button.classList.remove('collapsed');
icon.textContent = '▶'; // Keep using ▶ and let CSS handle rotation
setSectionState(sectionId, 'expanded');
} else {
// Collapse section
content.classList.add('collapsed');
button.classList.add('collapsed');
icon.textContent = '▶'; // Keep using ▶ and let CSS handle rotation
setSectionState(sectionId, 'collapsed');
}
}

// Navigate to section with smooth scrolling and auto-expand
function navigateToSection(sectionId) {
const section = document.getElementById(sectionId);
const content = document.getElementById(sectionId + '-content');

if (!section) return;

// Auto-expand if collapsed
if (content && content.classList.contains('collapsed')) {
toggleSection(sectionId);
}

// Smooth scroll to section
section.scrollIntoView({
behavior: 'smooth',
block: 'start'
});

// Brief highlight effect
section.style.transition = 'box-shadow 0.3s ease';
section.style.boxShadow = '0 0 20px rgba(0, 123, 255, 0.3)';
setTimeout(() => {
section.style.boxShadow = '';
}, 1500);
}

// Initialize sections to collapsed state by default
function initializeSections() {
const sections = ['breaking-changes', 'added-items', 'removed-items', 'modified-items'];

sections.forEach(sectionId => {
const section = document.getElementById(sectionId);
const content = document.getElementById(sectionId + '-content');
const button = section?.querySelector('.section-toggle');
const icon = button?.querySelector('.toggle-icon');

if (!section || !content || !button || !icon) return;

// Check session storage first
const savedState = getSectionState(sectionId);

if (savedState === 'expanded') {
// Expand based on saved state
content.classList.remove('collapsed');
button.classList.remove('collapsed');
icon.textContent = '▶';
} else {
// Default to collapsed (including null/new sessions)
content.classList.add('collapsed');
button.classList.add('collapsed');
icon.textContent = '▶';
// Save the default state if not already set
if (savedState === null) {
setSectionState(sectionId, 'collapsed');
}
}
});
}

// Initialize sections when the page loads
document.addEventListener('DOMContentLoaded', initializeSections);
93 changes: 93 additions & 0 deletions src/DotNetApiDiff/Reporting/HtmlTemplates/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,84 @@ section h2 {
font-size: 1.5rem;
}

/* Collapsible Section Styles */
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
background: #f8f9fa;
padding: 15px 20px;
margin: 0;
border-bottom: 1px solid #dee2e6;
}

.section-header h2 {
background: none;
padding: 0;
margin: 0;
border: none;
font-size: 1.5rem;
}

.section-toggle {
background: none;
border: none;
cursor: pointer;
padding: 8px;
border-radius: 4px;
color: #6c757d;
transition: all 0.2s ease;
display: flex;
align-items: center;
justify-content: center;
min-width: 32px;
min-height: 32px;
}

.section-toggle:hover {
background-color: #e9ecef;
color: #495057;
}

.section-toggle:focus {
outline: 2px solid #007bff;
outline-offset: 2px;
}

.toggle-icon {
font-size: 14px;
transition: transform 0.3s ease;
}

.section-toggle.collapsed .toggle-icon {
transform: rotate(0deg); /* No rotation - ▶ points right when collapsed */
}

.section-toggle:not(.collapsed) .toggle-icon {
transform: rotate(90deg); /* Rotate ▶ to point down when expanded */
}

.section-content {
transition: all 0.3s ease;
overflow: hidden;
}

.section-content.collapsed {
max-height: 0;
opacity: 0;
padding-top: 0;
padding-bottom: 0;
margin-top: 0;
margin-bottom: 0;
}

.section-content:not(.collapsed) {
max-height: none;
opacity: 1;
padding-top: 0;
padding-bottom: 0;
}

.metadata-content {
padding: 20px;
}
Expand Down Expand Up @@ -157,6 +235,21 @@ section h2 {
border-radius: 8px;
color: white;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.summary-card.clickable {
cursor: pointer;
}

.summary-card.clickable:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}

.summary-card.clickable:active {
transform: translateY(0);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.summary-card.added {
Expand Down
Loading