Files
ETPlot/gallery/templates/gallery.html
T
Kylian Schmidt 19fc15abb4 feat: add Gallery TUI for interactive configuration and generation
- Implemented a terminal user interface (TUI) for configuring the gallery generator using Textual.
- Included functionality to manage sources with add/remove
- Integrated a log pane to display generation output from subprocess calls.
- Implemented save functionality to persist configuration changes.
2026-05-08 15:47:02 +02:00

364 lines
14 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ title }}</title>
<link rel="stylesheet" href="{{ assets_path }}/css/main.css">
<link rel="stylesheet" href="{{ assets_path }}/css/html-plots.css">
<!-- MathJax for LaTeX rendering -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']],
displayMath: [['$$', '$$'], ['\\[', '\\]']]
}
};
</script>
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
</head>
<body>
<!-- Main Content -->
<h1>{{ title }}</h1>
<!-- Search Bar -->
<div class="search-container">
<input type="text" class="search-box" id="searchBox" placeholder="Search plots..." />
<span class="search-icon">🔍</span>
<div class="search-results" id="searchResults"></div>
</div>
<!-- Breadcrumb Navigation -->
<div class="breadcrumb" id="breadcrumb"></div>
<!-- Navigation Buttons -->
<div class="navigation">
<button class="nav-btn" onclick="window.history.back()">
← Back
</button>
{% if relpath != "." %}
<a href="../index.html" class="nav-btn">
↑ Parent Directory
</a>
{% endif %}
</div>
<!-- Folder Tree -->
<div class="folder-tree" id="folderTree"></div>
<!-- Folder Metadata Section -->
{% if folder_metadata %}
<div class="metadata-section">
<button class="metadata-toggle-btn" onclick="toggleMetadataSection()">
<span class="metadata-icon">📋</span>
<span class="metadata-label">Folder Information</span>
<span class="metadata-arrow" id="metadataArrow"></span>
</button>
<div class="metadata-content" id="metadataContent" style="display: none;">
<div class="metadata-header">
<div class="metadata-file-info">
<span class="file-path-label">📁 Metadata file:</span>
<code class="file-path" id="metadata-file-path">{{ metadata_file_path }}</code>
<button class="copy-path-btn" onclick="copyMetadataPath()" title="Copy path to clipboard">
📋 Copy
</button>
<span class="tip-icon" title="Tip: Create this file in the source directory to add folder-level metadata that will be inherited by all plots in this folder and its subdirectories. Supports both YAML (.yaml/.yml) and JSON (.json) formats.">
💡
</span>
</div>
</div>
<div class="metadata-grid">
{% for key, value in folder_metadata.items() %}
<div class="metadata-item">
<span class="metadata-key">{{ key }}:</span>
<span class="metadata-value">
{% if value is string and (value.startswith('http://') or value.startswith('https://')) %}
<a href="{{ value }}" target="_blank" rel="noopener noreferrer">{{ value }}</a>
{% elif value is string and '$$' in value %}
<span class="latex-content">{{ value }}</span>
{% elif value is string and value|length > 100 %}
<span class="metadata-long-text">{{ value[:100] }}...</span>
<button class="metadata-expand" onclick="expandText(this)">Show more</button>
<span class="metadata-full-text" style="display: none;">{{ value }}</span>
{% elif value is iterable and value is not string and value is not mapping %}
<div class="metadata-yaml-list">
{% for item in value %}
<div class="yaml-list-item">- {{ item }}</div>
{% endfor %}
</div>
{% elif value is mapping %}
<div class="metadata-yaml-object">
{% for subkey, subvalue in value.items() %}
<div class="yaml-object-item">
<span class="yaml-key">{{ subkey }}:</span>
{% if subvalue is iterable and subvalue is not string and subvalue is not mapping %}
<div class="yaml-nested-list">
{% for nested_item in subvalue %}
<div class="yaml-nested-item">- {{ nested_item }}</div>
{% endfor %}
</div>
{% elif subvalue is mapping %}
<div class="yaml-nested-object">
{% for nested_key, nested_value in subvalue.items() %}
<div class="yaml-nested-item">{{ nested_key }}: {{ nested_value }}</div>
{% endfor %}
</div>
{% else %}
<span class="yaml-value"> {{ subvalue }}</span>
{% endif %}
</div>
{% endfor %}
</div>
{% else %}
{{ value }}
{% endif %}
</span>
</div>
{% endfor %}
</div>
</div>
</div>
{% endif %}
<!-- View Toggle Controls - Only show if there are plot items -->
{% if items %}
<div class="controls-container">
<div class="sort-controls">
<label class="sort-label">Sort by:</label>
<button class="sort-btn active" data-sort="name" title="Sort by Name">
📝 Name
</button>
<button class="sort-btn" data-sort="time" title="Sort by Creation Time">
🕒 Time
</button>
<button class="sort-order-btn" data-order="asc" title="Sort Order">
</button>
</div>
<div class="view-controls">
<button class="view-btn active" data-view="grid" title="Grid View">
<svg width="16" height="16" viewBox="0 0 16 16">
<rect x="1" y="1" width="6" height="6" fill="currentColor"/>
<rect x="9" y="1" width="6" height="6" fill="currentColor"/>
<rect x="1" y="9" width="6" height="6" fill="currentColor"/>
<rect x="9" y="9" width="6" height="6" fill="currentColor"/>
</svg>
</button>
<button class="view-btn" data-view="list-large" title="Large List View">
<svg width="16" height="16" viewBox="0 0 16 16">
<rect x="1" y="2" width="4" height="3" fill="currentColor"/>
<rect x="7" y="2" width="8" height="1" fill="currentColor"/>
<rect x="7" y="4" width="6" height="1" fill="currentColor"/>
<rect x="1" y="7" width="4" height="3" fill="currentColor"/>
<rect x="7" y="7" width="8" height="1" fill="currentColor"/>
<rect x="7" y="9" width="6" height="1" fill="currentColor"/>
<rect x="1" y="12" width="4" height="3" fill="currentColor"/>
<rect x="7" y="12" width="8" height="1" fill="currentColor"/>
<rect x="7" y="14" width="6" height="1" fill="currentColor"/>
</svg>
</button>
<button class="view-btn" data-view="list-compact" title="Compact List View">
<svg width="16" height="16" viewBox="0 0 16 16">
<rect x="1" y="3" width="14" height="1" fill="currentColor"/>
<rect x="1" y="6" width="14" height="1" fill="currentColor"/>
<rect x="1" y="9" width="14" height="1" fill="currentColor"/>
<rect x="1" y="12" width="14" height="1" fill="currentColor"/>
</svg>
</button>
</div>
</div>
{% endif %}
<!-- Plot Container -->
<div class="plot-container grid-view" id="plotContainer">
{% for item in items %}
<div class="plot-item grid-item {% if item.is_html %}html-plot{% endif %}"
data-name="{{ item.name }}"
data-time="{{ item.creation_time|default(0) }}">
{% if item.is_html %}
<a href="{{ item.html_href }}" class="plot-link" target="_blank">
<div class="html-thumbnail">
<div class="html-indicator">HTML</div>
<div class="html-preview">Click to open interactive plot</div>
</div>
</a>
{% else %}
<a href="{{ item.pdf_href }}" class="plot-link">
<img src="{{ item.png_href }}" alt="{{ item.name }}" class="plot-thumbnail">
</a>
{% endif %}
<div class="plot-info">
<div class="plot-name" title="{{ item.name }}">{{ item.name }}</div>
<div class="plot-date" title="Created: {{ item.creation_time|default(0)|int|datetime_from_timestamp|strftime('%Y-%m-%d %H:%M') if item.creation_time and item.creation_time|int > 0 else 'Unknown' }}">
{% if item.creation_time and item.creation_time|int > 0 %}
{{ item.creation_time|int|datetime_from_timestamp|strftime('%Y-%m-%d') }}
{% else %}
Unknown
{% endif %}
</div>
</div>
</div>
{% endfor %}
</div>
<!-- Recent Plots Sidebar -->
<div class="sidebar-overlay" id="sidebarOverlay" onclick="toggleSidebar()"></div>
<div class="sidebar" id="sidebar">
<div class="sidebar-header">
<h3 class="sidebar-title">Recent Plots</h3>
<button class="sidebar-close" onclick="toggleSidebar()">×</button>
</div>
<div class="sidebar-content" id="sidebarContent">
<div style="text-align: center; color: var(--breadcrumb-color); margin: 2rem 0;">
No recent plots yet
</div>
</div>
</div>
<!-- Floating Action Buttons -->
<div class="floating-buttons">
<button class="floating-btn sidebar-toggle" onclick="toggleSidebar()" id="sidebarToggle" title="Recent Plots (Ctrl+R)">
📋
</button>
<button class="floating-btn compare-toggle" onclick="app.toggleCompareMode()" id="compareToggle" title="Compare Plots (Ctrl+C)">
⚖️
</button>
<button class="floating-btn theme-toggle" onclick="toggleTheme()" id="themeToggle" title="Toggle Theme (Ctrl+T)">
☀️
</button>
</div>
<!-- Keyboard Shortcuts Help -->
<div class="shortcuts-help" id="shortcutsHelp">
<h4>Keyboard Shortcuts</h4>
<div class="shortcut-item">
<span>Search</span>
<span class="shortcut-key">Ctrl+K</span>
</div>
<div class="shortcut-item">
<span>Recent plots</span>
<span class="shortcut-key">Ctrl+R</span>
</div>
<div class="shortcut-item">
<span>Compare plots</span>
<span class="shortcut-key">Ctrl+C</span>
</div>
<div class="shortcut-item">
<span>Export plots</span>
<span class="shortcut-key">Ctrl+E</span>
</div>
<div class="shortcut-item">
<span>Exit selection mode</span>
<span class="shortcut-key">Esc</span>
</div>
<div class="shortcut-item">
<span>Toggle theme</span>
<span class="shortcut-key">Ctrl+T</span>
</div>
<div class="shortcut-item">
<span>Toggle view</span>
<span class="shortcut-key">Ctrl+V</span>
</div>
<div class="shortcut-item">
<span>Sort by name</span>
<span class="shortcut-key">Ctrl+N</span>
</div>
<div class="shortcut-item">
<span>Sort by time</span>
<span class="shortcut-key">Ctrl+M</span>
</div>
<div class="shortcut-item">
<span>Toggle sort order</span>
<span class="shortcut-key">Ctrl+O</span>
</div>
<div class="shortcut-item">
<span>Help</span>
<span class="shortcut-key">?</span>
</div>
</div>
<!-- Gallery Statistics -->
<div class="gallery-stats" id="galleryStats">
<div class="stats-item">
<span class="stats-label">📊 Files:</span>
<span class="stats-value" id="fileCount">0</span>
</div>
<div class="stats-item">
<span class="stats-label">📁 Folders:</span>
<span class="stats-value" id="folderCount">0</span>
</div>
<div class="stats-item">
<span class="stats-label">💾 Size:</span>
<span class="stats-value" id="totalSize">0 KB</span>
</div>
<div class="stats-item">
<span class="stats-label">🕒 Updated:</span>
<span class="stats-value" id="lastUpdated">Now</span>
</div>
</div>
<!-- Plot Comparison Overlay -->
<div class="comparison-overlay" id="comparisonOverlay">
<div class="comparison-container">
<div class="comparison-header">
<h2 class="comparison-title">Plot Comparison</h2>
<button class="comparison-close" onclick="app.closeComparison()" title="Close Comparison (Esc)">×</button>
</div>
<div class="comparison-content">
<div class="comparison-panel">
<div class="comparison-panel-header">
<span class="comparison-panel-title" id="leftPlotTitle">Plot A</span>
<button class="comparison-replace-btn" onclick="app.replacePlot('left')" id="leftReplaceBtn">Replace</button>
</div>
<div class="comparison-panel-content">
<div class="comparison-plot-container" id="leftPlotContainer">
<div class="comparison-placeholder" onclick="app.selectPlotForComparison('left')">
📊 Click to select first plot
</div>
</div>
</div>
</div>
<div class="comparison-panel">
<div class="comparison-panel-header">
<span class="comparison-panel-title" id="rightPlotTitle">Plot B</span>
<button class="comparison-replace-btn" onclick="app.replacePlot('right')" id="rightReplaceBtn">Replace</button>
</div>
<div class="comparison-panel-content">
<div class="comparison-plot-container" id="rightPlotContainer">
<div class="comparison-placeholder" onclick="app.selectPlotForComparison('right')">
📊 Click to select second plot
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Configuration for JavaScript -->
<script>
// Configuration object for the gallery app
window.galleryConfig = {
searchDebounceMs: {{ ui.search_debounce_ms|default(300) }},
maxRecentPlots: {{ ui.max_recent_plots|default(20) }},
stats: {% if stats %}{{ stats|tojson }}{% else %}null{% endif %}
};
</script>
<script id="gallery-data" type="application/json">{"subdirs": {{ subdirs|tojson }}, "item_count": {{ items|length }}}</script>
<!-- Metadata Popup Script -->
<script src="{{ assets_path }}/js/metadata-popup.js"></script>
<!-- Metadata Section Script -->
<script src="{{ assets_path }}/js/metadata-section.js"></script>
<!-- Folder Metadata Script -->
<script src="{{ assets_path }}/js/folder-metadata.js"></script>
<!-- Main JavaScript Application -->
<script type="module" src="{{ assets_path }}/js/main.js"></script>
</body>
</html>