interface improvement (compact filter section)
This commit is contained in:
parent
8693cd87d4
commit
0e66c6e32f
@ -91,19 +91,27 @@ const sortedTags = Object.entries(tagFrequency)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Advanced Filters Section -->
|
||||
<!-- Advanced Filters Section - COLLAPSIBLE -->
|
||||
<div class="filter-section">
|
||||
<div class="filter-card-compact">
|
||||
<div class="filter-header-compact">
|
||||
<h3>⚙️ Erweiterte Filter</h3>
|
||||
<div class="filter-header-controls">
|
||||
<button class="filter-reset" id="reset-advanced" title="Erweiterte Filter zurücksetzen">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<polyline points="1 4 1 10 7 10"/>
|
||||
<path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="collapse-toggle" id="toggle-advanced" data-collapsed="true" title="Erweiterte Filter ein/ausblenden">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<polyline points="6 9 12 15 18 9"></polyline>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="collapsible-content hidden" id="advanced-filters-content">
|
||||
<div class="advanced-filters-compact">
|
||||
<div class="filter-grid-compact">
|
||||
<div class="filter-group">
|
||||
@ -171,27 +179,36 @@ const sortedTags = Object.entries(tagFrequency)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tag Filters Section -->
|
||||
<!-- Tag Filters Section - COLLAPSIBLE -->
|
||||
<div class="filter-section">
|
||||
<div class="filter-card-compact">
|
||||
<div class="filter-header-compact">
|
||||
<h3>🏷️ Tag-Filter</h3>
|
||||
<div class="tag-controls">
|
||||
<div class="filter-header-controls">
|
||||
<button class="filter-reset" id="reset-tags" title="Tags zurücksetzen">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<polyline points="1 4 1 10 7 10"/>
|
||||
<path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button id="tag-cloud-toggle" class="tag-toggle" data-expanded="false">
|
||||
Mehr zeigen
|
||||
<button class="collapse-toggle" id="toggle-tags" data-collapsed="true" title="Tag-Filter ein/ausblenden">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<polyline points="6 9 12 15 18 9"></polyline>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="collapsible-content hidden" id="tag-filters-content">
|
||||
<div class="tag-section">
|
||||
<div class="selected-tags" id="selected-tags"></div>
|
||||
<div class="tag-controls">
|
||||
<button id="tag-cloud-toggle" class="tag-toggle" data-expanded="false">
|
||||
Mehr zeigen
|
||||
</button>
|
||||
</div>
|
||||
<div class="tag-cloud" id="tag-cloud">
|
||||
{sortedTags.map((tag, index) => (
|
||||
<button
|
||||
@ -208,6 +225,7 @@ const sortedTags = Object.entries(tagFrequency)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- View Controls Section -->
|
||||
<div class="filter-section">
|
||||
@ -293,7 +311,12 @@ const sortedTags = Object.entries(tagFrequency)
|
||||
advanced: document.getElementById('reset-advanced'),
|
||||
tags: document.getElementById('reset-tags'),
|
||||
all: document.getElementById('reset-all-filters')
|
||||
}
|
||||
},
|
||||
// Collapsible elements
|
||||
toggleAdvanced: document.getElementById('toggle-advanced'),
|
||||
toggleTags: document.getElementById('toggle-tags'),
|
||||
advancedContent: document.getElementById('advanced-filters-content'),
|
||||
tagContent: document.getElementById('tag-filters-content')
|
||||
};
|
||||
|
||||
// Verify critical elements exist
|
||||
@ -307,6 +330,52 @@ const sortedTags = Object.entries(tagFrequency)
|
||||
let selectedPhase = '';
|
||||
let isTagCloudExpanded = false;
|
||||
|
||||
// Collapsible functionality
|
||||
function toggleCollapsible(toggleBtn, content, storageKey) {
|
||||
const isCollapsed = toggleBtn.getAttribute('data-collapsed') === 'true';
|
||||
const newState = !isCollapsed;
|
||||
|
||||
toggleBtn.setAttribute('data-collapsed', newState.toString());
|
||||
|
||||
if (newState) {
|
||||
// Collapse
|
||||
content.classList.add('hidden');
|
||||
toggleBtn.style.transform = 'rotate(0deg)';
|
||||
} else {
|
||||
// Expand
|
||||
content.classList.remove('hidden');
|
||||
toggleBtn.style.transform = 'rotate(180deg)';
|
||||
}
|
||||
|
||||
// Store state in sessionStorage
|
||||
sessionStorage.setItem(storageKey, newState.toString());
|
||||
}
|
||||
|
||||
// Initialize collapsible sections (collapsed by default)
|
||||
function initializeCollapsible() {
|
||||
// Advanced filters
|
||||
const advancedCollapsed = sessionStorage.getItem('advanced-collapsed') !== 'false';
|
||||
elements.toggleAdvanced.setAttribute('data-collapsed', advancedCollapsed.toString());
|
||||
if (advancedCollapsed) {
|
||||
elements.advancedContent.classList.add('hidden');
|
||||
elements.toggleAdvanced.style.transform = 'rotate(0deg)';
|
||||
} else {
|
||||
elements.advancedContent.classList.remove('hidden');
|
||||
elements.toggleAdvanced.style.transform = 'rotate(180deg)';
|
||||
}
|
||||
|
||||
// Tag filters
|
||||
const tagsCollapsed = sessionStorage.getItem('tags-collapsed') !== 'false';
|
||||
elements.toggleTags.setAttribute('data-collapsed', tagsCollapsed.toString());
|
||||
if (tagsCollapsed) {
|
||||
elements.tagContent.classList.add('hidden');
|
||||
elements.toggleTags.style.transform = 'rotate(0deg)';
|
||||
} else {
|
||||
elements.tagContent.classList.remove('hidden');
|
||||
elements.toggleTags.style.transform = 'rotate(180deg)';
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to check if tool is hosted
|
||||
function isToolHosted(tool) {
|
||||
return tool.projectUrl !== undefined &&
|
||||
@ -418,18 +487,23 @@ const sortedTags = Object.entries(tagFrequency)
|
||||
});
|
||||
}
|
||||
|
||||
// Add/remove tags
|
||||
// Add/remove tags - FIXED: Update ALL matching elements
|
||||
function addTag(tag) {
|
||||
selectedTags.add(tag);
|
||||
document.querySelector(`[data-tag="${tag}"]`).classList.add('active');
|
||||
// FIXED: Use querySelectorAll to update ALL matching tag elements
|
||||
document.querySelectorAll(`[data-tag="${tag}"]`).forEach(element => {
|
||||
element.classList.add('active');
|
||||
});
|
||||
updateSelectedTags();
|
||||
filterTools();
|
||||
}
|
||||
|
||||
function removeTag(tag) {
|
||||
selectedTags.delete(tag);
|
||||
const tagElement = document.querySelector(`[data-tag="${tag}"]`);
|
||||
if (tagElement) tagElement.classList.remove('active');
|
||||
// FIXED: Use querySelectorAll to update ALL matching tag elements
|
||||
document.querySelectorAll(`[data-tag="${tag}"]`).forEach(element => {
|
||||
element.classList.remove('active');
|
||||
});
|
||||
updateSelectedTags();
|
||||
filterTools();
|
||||
}
|
||||
@ -553,7 +627,10 @@ const sortedTags = Object.entries(tagFrequency)
|
||||
|
||||
function resetTags() {
|
||||
selectedTags.clear();
|
||||
elements.tagCloudItems.forEach(item => item.classList.remove('active'));
|
||||
// FIXED: Update ALL tag elements
|
||||
document.querySelectorAll('.tag-cloud-item').forEach(item => {
|
||||
item.classList.remove('active');
|
||||
});
|
||||
updateSelectedTags();
|
||||
filterTools();
|
||||
}
|
||||
@ -630,11 +707,21 @@ const sortedTags = Object.entries(tagFrequency)
|
||||
elements.resetButtons.tags.addEventListener('click', resetTags);
|
||||
elements.resetButtons.all.addEventListener('click', resetAllFilters);
|
||||
|
||||
// Collapsible toggle listeners
|
||||
elements.toggleAdvanced.addEventListener('click', () => {
|
||||
toggleCollapsible(elements.toggleAdvanced, elements.advancedContent, 'advanced-collapsed');
|
||||
});
|
||||
|
||||
elements.toggleTags.addEventListener('click', () => {
|
||||
toggleCollapsible(elements.toggleTags, elements.tagContent, 'tags-collapsed');
|
||||
});
|
||||
|
||||
// Expose functions globally for backwards compatibility
|
||||
window.clearTagFilters = resetTags;
|
||||
window.clearAllFilters = resetAllFilters;
|
||||
|
||||
// Initialize
|
||||
initializeCollapsible();
|
||||
initTagCloud();
|
||||
filterTagCloud();
|
||||
updateSelectedTags();
|
||||
|
@ -1263,6 +1263,12 @@ input[type="checkbox"] {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.filter-header-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
/* Search Components */
|
||||
.search-wrapper {
|
||||
position: relative;
|
||||
@ -1315,6 +1321,64 @@ input[type="checkbox"] {
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.collapse-toggle {
|
||||
background: none;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: 0.375rem;
|
||||
color: var(--color-text-secondary);
|
||||
cursor: pointer;
|
||||
padding: 0.375rem;
|
||||
transition: var(--transition-fast);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.collapse-toggle:hover {
|
||||
background-color: var(--color-bg-secondary);
|
||||
border-color: var(--color-primary);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.collapse-toggle svg {
|
||||
transition: transform var(--transition-medium);
|
||||
}
|
||||
|
||||
/* When expanded, rotate the chevron */
|
||||
.collapse-toggle[data-collapsed="false"] svg {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
/* Collapsible Content */
|
||||
.collapsible-content {
|
||||
overflow: hidden;
|
||||
transition: all var(--transition-medium);
|
||||
opacity: 1;
|
||||
max-height: 1000px;
|
||||
}
|
||||
|
||||
.collapsible-content.hidden {
|
||||
opacity: 0;
|
||||
max-height: 0;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* Smooth animation for expanding content */
|
||||
.collapsible-content:not(.hidden) {
|
||||
animation: expandContent 0.3s ease-out;
|
||||
}
|
||||
|
||||
/* Content spacing when expanded */
|
||||
.collapsible-content:not(.hidden) .advanced-filters-compact,
|
||||
.collapsible-content:not(.hidden) .tag-section {
|
||||
padding-top: 0.75rem;
|
||||
}
|
||||
|
||||
/* Filter Grids & Groups */
|
||||
.filter-grid-compact {
|
||||
display: grid;
|
||||
@ -1429,11 +1493,9 @@ input[type="checkbox"] {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
/* Tag System */
|
||||
.tag-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
.tag-section .tag-controls {
|
||||
order: -1;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.selected-tags {
|
||||
@ -1574,6 +1636,14 @@ input[type="checkbox"] {
|
||||
transition: var(--transition-fast);
|
||||
}
|
||||
|
||||
.filter-reset {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.filter-reset:hover {
|
||||
background-color: var(--color-bg-secondary);
|
||||
border-color: var(--color-warning);
|
||||
@ -1591,13 +1661,6 @@ input[type="checkbox"] {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* Tag Controls */
|
||||
.tag-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.tag-toggle {
|
||||
padding: 0.375rem 0.75rem;
|
||||
border: 1px solid var(--color-border);
|
||||
@ -2391,6 +2454,17 @@ footer {
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
@keyframes expandContent {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
@ -3385,6 +3459,23 @@ footer {
|
||||
.view-toggle {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.filter-header-controls {
|
||||
gap: 0.375rem;
|
||||
}
|
||||
|
||||
.collapse-toggle,
|
||||
.filter-reset {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
.collapse-toggle svg,
|
||||
.filter-reset svg {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width <= 640px) {
|
||||
@ -3519,6 +3610,21 @@ footer {
|
||||
.filter-card-compact {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.filter-header-compact {
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.filter-header-compact h3 {
|
||||
flex: 1 1 100%;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.filter-header-controls {
|
||||
flex: 1 1 100%;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user