docs(electron): added info modal

This commit is contained in:
2025-08-10 07:14:31 -04:00
parent 54b4378fff
commit 1a81d104a5
5 changed files with 2211 additions and 72 deletions

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 78 KiB

View File

@@ -18,6 +18,10 @@
</nav>
<div class="sidebar-footer">
<p>v1.0.0</p>
<button id="info-btn" class="info-button" title="About 4DSTAR">
<span class="info-icon"></span>
Info
</button>
</div>
</aside>
@@ -160,6 +164,70 @@
</div>
</div>
<!-- Info Modal -->
<div id="info-modal" class="modal-container hidden">
<div class="modal-content info-modal-content">
<div class="modal-header">
<h3>About 4DSTAR</h3>
<button class="modal-close" onclick="hideInfoModal()">&times;</button>
</div>
<div class="info-modal-body">
<div class="info-tab-nav">
<button class="info-tab-link active" data-tab="about-info-tab">About</button>
<button class="info-tab-link" data-tab="license-info-tab">License</button>
<button class="info-tab-link" data-tab="funding-info-tab">Funding</button>
<button class="info-tab-link" data-tab="help-info-tab">Help</button>
</div>
<div class="info-tab-content">
<div id="about-info-tab" class="info-tab-pane active">
<h4>4DSTAR Bundle Manager</h4>
<p><strong>Author:</strong> Emily M. Boudreaux</p>
<p><strong>Version:</strong> 1.0.0</p>
<p><strong>Description:</strong> A modern bundle management tool for 4DSTAR stellar evolution models, providing an intuitive interface for creating, signing, validating, and filling binary bundles.</p>
<div class="info-links">
<a href="#" id="github-link" class="info-link">
<span class="link-icon">🔗</span>
View on GitHub
</a>
</div>
</div>
<div id="license-info-tab" class="info-tab-pane">
<h4>License Information</h4>
<p><strong>License:</strong> GNU General Public License v3.0</p>
<div class="license-content">
<p>This software is licensed under GPL v3. License text will be added here.</p>
<textarea readonly class="license-text" placeholder="GPL v3 license text will be pasted here..."></textarea>
</div>
</div>
<div id="funding-info-tab" class="info-tab-pane">
<h4>Funding & Support</h4>
<div class="funding-content">
<p>Funding information placeholder - content will be added here.</p>
</div>
</div>
<div id="help-info-tab" class="info-tab-pane">
<h4>Help & Documentation</h4>
<div class="help-content">
<h5>Getting Started</h5>
<ul>
<li><strong>Open Bundle:</strong> Click "Open Bundle" to load an existing .fbundle file</li>
<li><strong>Create Bundle:</strong> Click "Create Bundle" to build a new bundle from plugins</li>
<li><strong>Sign Bundle:</strong> Use the Sign button to digitally sign your bundle with a PEM key</li>
<li><strong>Fill Bundle:</strong> Use the Fill tab to compile and add binaries for different platforms</li>
</ul>
<h5>Bundle Operations</h5>
<ul>
<li><strong>Validate:</strong> Check bundle integrity and compatibility</li>
<li><strong>Edit Metadata:</strong> Click pencil icons to edit version, author, and comments</li>
<li><strong>Clear:</strong> Remove all compiled binaries from the bundle</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Fill Modal (Legacy - can be removed later) -->
<div id="fill-modal" class="modal-container hidden">
<div class="modal-content">

View File

@@ -1,9 +1,8 @@
const { app, BrowserWindow, ipcMain, dialog, nativeTheme } = require('electron');
const { app, BrowserWindow, ipcMain, dialog, shell, nativeTheme } = require('electron');
const path = require('path');
const fs = require('fs-extra');
const { spawn } = require('child_process');
const yaml = require('js-yaml');
const AdmZip = require('adm-zip');
const { spawn } = require('child_process');
// Handle creating/removing shortcuts on Windows when installing/uninstalling.
if (require('electron-squirrel-startup')) {

View File

@@ -207,33 +207,61 @@ function setupEventListeners() {
// Check if bundle is signed and show warning before bundle-modifying operations
function checkSignatureAndWarn(operation, operationName = 'operation') {
console.log('checkSignatureAndWarn called for:', operationName);
console.log('currentBundle:', currentBundle);
// Check if current bundle has a valid signature
const isSigned = currentBundle &&
currentBundle.report &&
currentBundle.report.signature &&
currentBundle.report.signature.status &&
['TRUSTED', 'UNTRUSTED'].includes(currentBundle.report.signature.status);
console.log('Bundle signature status:', currentBundle?.report?.signature?.status);
console.log('isSigned:', isSigned);
if (isSigned) {
// Bundle is signed, show warning modal
console.log('Bundle is signed, showing warning modal');
pendingOperation = operation;
signatureWarningModal.classList.remove('hidden');
return false; // Don't execute operation immediately
} else {
// Bundle is not signed, execute operation directly
console.log('Bundle is not signed, executing operation directly');
operation();
return true; // Operation executed
}
}
// Info Modal functionality
const infoBtn = document.getElementById('info-btn');
const infoModal = document.getElementById('info-modal');
const infoTabLinks = document.querySelectorAll('.info-tab-link');
const infoTabPanes = document.querySelectorAll('.info-tab-pane');
const githubLink = document.getElementById('github-link');
// Show info modal
infoBtn.addEventListener('click', () => {
infoModal.classList.remove('hidden');
});
// Hide info modal - make it globally accessible
window.hideInfoModal = function() {
infoModal.classList.add('hidden');
};
// Tab switching functionality
infoTabLinks.forEach(tabLink => {
tabLink.addEventListener('click', () => {
const targetTab = tabLink.getAttribute('data-tab');
// Remove active class from all tabs and panes
infoTabLinks.forEach(link => link.classList.remove('active'));
infoTabPanes.forEach(pane => pane.classList.remove('active'));
// Add active class to clicked tab and corresponding pane
tabLink.classList.add('active');
document.getElementById(targetTab).classList.add('active');
});
});
// GitHub link functionality
githubLink.addEventListener('click', (e) => {
e.preventDefault();
const { ipcRenderer } = require('electron');
ipcRenderer.invoke('open-external', 'https://github.com/tboudreaux/4DSTAR');
});
// Old modal code removed - now using tab-based interface
// Create modern table-based interface for fillable targets

View File

@@ -102,10 +102,39 @@ body {
}
.sidebar-footer {
padding: 20px;
text-align: center;
padding: 12px 16px 16px 16px;
font-size: 0.8rem;
color: var(--text-light);
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
/* Info Button in Sidebar */
.info-button {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
background: rgba(255, 255, 255, 0.1);
color: white;
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 6px;
padding: 8px 12px;
cursor: pointer;
font-size: 12px;
transition: all 0.2s ease;
width: fit-content;
}
.info-button:hover {
background: rgba(255, 255, 255, 0.2);
border-color: rgba(255, 255, 255, 0.3);
}
.info-icon {
font-size: 14px;
}
/* Content Area */
@@ -584,67 +613,16 @@ body {
max-width: 500px;
}
#signature-warning-modal h2 {
color: #f59e0b;
margin-bottom: 16px;
display: flex;
align-items: center;
gap: 8px;
.signature-warning-content {
text-align: center;
}
.warning-content {
margin-bottom: 24px;
}
.warning-content p {
margin-bottom: 12px;
line-height: 1.5;
}
.warning-content ul {
margin: 12px 0;
padding-left: 24px;
}
.warning-content li {
margin-bottom: 6px;
line-height: 1.4;
}
.modal-actions {
display: flex;
gap: 12px;
justify-content: flex-end;
}
.modal-actions button {
padding: 10px 20px;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
font-weight: 600;
transition: background-color 0.2s;
}
/* Signature Warning Banner in Save Modal */
.signature-warning-section {
margin-bottom: 20px;
}
.warning-banner {
display: flex;
align-items: flex-start;
gap: 12px;
padding: 16px;
.warning-message {
margin: 20px 0;
padding: 20px;
background-color: #fef3c7;
border: 1px solid #f59e0b;
border-radius: 8px;
margin-bottom: 16px;
}
.warning-icon {
font-size: 20px;
flex-shrink: 0;
margin-top: 2px;
}
@@ -757,3 +735,135 @@ body {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* Info Modal */
.info-modal-content {
max-width: 600px;
max-height: 80vh;
}
.info-modal-body {
padding: 0;
}
.info-tab-nav {
display: flex;
border-bottom: 1px solid var(--border-color);
background-color: #f8f9fa;
}
.info-tab-link {
flex: 1;
padding: 12px 16px;
border: none;
background: none;
cursor: pointer;
font-weight: 500;
color: #6b7280;
transition: all 0.2s ease;
border-bottom: 2px solid transparent;
}
.info-tab-link:hover {
background-color: #e5e7eb;
color: #374151;
}
.info-tab-link.active {
color: #3b82f6;
border-bottom-color: #3b82f6;
background-color: white;
}
.info-tab-content {
padding: 24px;
max-height: 400px;
overflow-y: auto;
}
.info-tab-pane {
display: none;
}
.info-tab-pane.active {
display: block;
}
.info-tab-pane h4 {
margin-top: 0;
margin-bottom: 16px;
color: #1f2937;
font-size: 1.25rem;
}
.info-tab-pane h5 {
margin-top: 20px;
margin-bottom: 12px;
color: #374151;
font-size: 1rem;
}
.info-tab-pane p {
margin-bottom: 12px;
line-height: 1.6;
}
.info-tab-pane ul {
margin: 12px 0;
padding-left: 20px;
}
.info-tab-pane li {
margin-bottom: 8px;
line-height: 1.5;
}
.info-links {
margin-top: 20px;
padding-top: 16px;
border-top: 1px solid var(--border-color);
}
.info-link {
display: inline-flex;
align-items: center;
gap: 8px;
color: #3b82f6;
text-decoration: none;
font-weight: 500;
padding: 8px 12px;
border-radius: 6px;
transition: background-color 0.2s;
}
.info-link:hover {
background-color: #eff6ff;
text-decoration: none;
}
.link-icon {
font-size: 16px;
}
.license-content {
margin-top: 16px;
}
.license-text {
width: 100%;
height: 200px;
margin-top: 12px;
padding: 12px;
border: 1px solid var(--border-color);
border-radius: 6px;
font-family: 'Courier New', monospace;
font-size: 12px;
line-height: 1.4;
resize: vertical;
background-color: #f8f9fa;
}
.funding-content,
.help-content {
line-height: 1.6;
}