feat: add left panal collapsible-expandable functionality

This commit is contained in:
Kevin Bruton 2025-09-29 18:03:36 +02:00
parent 105e93faf2
commit e0848e960c
3 changed files with 108 additions and 10 deletions

View File

@ -243,6 +243,22 @@ body {
border-left: 2px solid var(--border-color); border-left: 2px solid var(--border-color);
padding-left: 15px; padding-left: 15px;
margin-top: 8px; margin-top: 8px;
overflow: hidden;
transition: max-height 0.3s ease-in-out, opacity 0.2s ease-in-out;
}
/* Collapsed state - hide children by default */
.item-children.collapsed {
max-height: 0;
opacity: 0;
margin-top: 0;
margin-bottom: 0;
}
/* Expanded state */
.item-children.expanded {
max-height: 1000px; /* Large enough to accommodate content */
opacity: 1;
} }
.process-item { .process-item {
@ -260,6 +276,59 @@ body {
background-color: var(--border-color); background-color: var(--border-color);
} }
/* Item header container */
.item-header {
display: flex;
align-items: center;
gap: 4px;
}
/* Toggle button styles */
.toggle-btn {
background: none;
border: none;
color: var(--text-secondary);
cursor: pointer;
padding: 4px;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
transition: all 0.2s ease;
font-size: 10px;
line-height: 1;
}
.toggle-btn:hover {
background-color: var(--hover-color);
color: var(--text-primary);
transform: scale(1.1);
}
.toggle-btn:focus {
outline: 2px solid var(--accent-color);
outline-offset: 2px;
}
/* Toggle icon rotation */
.toggle-icon {
transition: transform 0.2s ease;
display: inline-block;
}
.toggle-btn.expanded .toggle-icon {
transform: rotate(90deg);
}
/* Spacer for items without children */
.toggle-spacer {
width: 20px;
height: 20px;
display: inline-block;
}
.clickable { .clickable {
cursor: pointer; cursor: pointer;
transition: all 0.2s ease; transition: all 0.2s ease;

View File

@ -1,17 +1,26 @@
{% macro render_item(item) %} {% macro render_item(item) %}
<li class="process-item status-{{ item.status }}"> <li class="process-item status-{{ item.status }}">
<span hx-get="/content/{{ item.id }}" hx-target="#right-panel" hx-swap="innerHTML" class="item-name clickable"> <div class="item-header">
<span class="status-icon"> {% if item.children %}
{% if item.status == 'completed' %}✅ <button class="toggle-btn" onclick="toggleNode(this)" aria-label="Toggle children">
{% elif item.status == 'in_progress' %}⏳ <span class="toggle-icon"></span>
{% elif item.status == 'error' %}❌ </button>
{% else %}⏸️ {% else %}
{% endif %} <span class="toggle-spacer"></span>
{% endif %}
<span hx-get="/content/{{ item.id }}" hx-target="#right-panel" hx-swap="innerHTML" class="item-name clickable">
<span class="status-icon">
{% if item.status == 'completed' %}✅
{% elif item.status == 'in_progress' %}⏳
{% elif item.status == 'error' %}❌
{% else %}⏸️
{% endif %}
</span>
{{ item.name }}
</span> </span>
{{ item.name }} </div>
</span>
{% if item.children %} {% if item.children %}
<ul class="item-children"> <ul class="item-children collapsed">
{% for child in item.children %} {% for child in item.children %}
{{ render_item(child) }} {{ render_item(child) }}
{% endfor %} {% endfor %}

View File

@ -183,6 +183,26 @@
document.getElementById('analysis_date').value = dateString; document.getElementById('analysis_date').value = dateString;
} }
// Toggle node functionality for collapsible tree
function toggleNode(button) {
const children = button.parentElement.parentElement.querySelector('.item-children');
if (children) {
const isExpanded = children.classList.contains('expanded');
if (isExpanded) {
// Collapse
children.classList.remove('expanded');
children.classList.add('collapsed');
button.classList.remove('expanded');
} else {
// Expand
children.classList.remove('collapsed');
children.classList.add('expanded');
button.classList.add('expanded');
}
}
}
// Initialize the page // Initialize the page
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
setCurrentDate(); setCurrentDate();