Fix VirtViewer detection on Windows + manual path override
VirtViewer's installer folder name includes the version number (e.g. "VirtViewer v11.0-256"), so the previous hardcoded path never matched a real install. Now scans Program Files for any VirtViewer* folder, and adds a Settings dialog (Windows only) to pick the remote-viewer.exe path manually as a fallback.
This commit is contained in:
@@ -292,3 +292,59 @@ body.vms-page {
|
||||
margin-top: 0.5rem;
|
||||
color: #3a4a60;
|
||||
}
|
||||
|
||||
/* ── Settings modal ───────────────────────────────────────── */
|
||||
.modal-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(5, 8, 16, 0.65);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.modal-card {
|
||||
width: 420px;
|
||||
max-width: 90vw;
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 14px;
|
||||
padding: 1.6rem 1.7rem;
|
||||
box-shadow: 0 24px 60px rgba(0,0,0,0.55);
|
||||
}
|
||||
|
||||
.modal-card h3 {
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.6rem;
|
||||
}
|
||||
|
||||
.modal-card .hint {
|
||||
font-size: 0.8rem;
|
||||
color: var(--muted);
|
||||
margin-bottom: 1.1rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.path-display {
|
||||
padding: 0.6rem 0.85rem;
|
||||
background: var(--bg-input);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 7px;
|
||||
font-size: 0.82rem;
|
||||
color: var(--text);
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.modal-actions {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
justify-content: flex-end;
|
||||
margin-top: 1.4rem;
|
||||
}
|
||||
|
||||
.modal-actions .modal-close {
|
||||
width: auto;
|
||||
padding: 0.42rem 1rem;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<div class="page-header">
|
||||
<h2>Virtuelle Maschinen</h2>
|
||||
<div class="header-actions">
|
||||
<button id="settingsBtn" class="btn-secondary hidden" title="Viewer-Pfad einstellen">⚙ Einstellungen</button>
|
||||
<button id="refreshBtn" class="btn-secondary" title="Liste aktualisieren">↻ Aktualisieren</button>
|
||||
<button id="logoutBtn" class="btn-secondary">Abmelden</button>
|
||||
</div>
|
||||
@@ -42,6 +43,26 @@
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Settings modal (Windows only — VirtViewer's install folder name changes per version) -->
|
||||
<div id="settingsOverlay" class="modal-overlay hidden">
|
||||
<div class="modal-card">
|
||||
<h3>Viewer-Pfad</h3>
|
||||
<p class="hint">
|
||||
Wird VirtViewer (remote-viewer.exe) nicht automatisch gefunden, kannst du hier
|
||||
den Pfad zur .exe manuell festlegen.
|
||||
</p>
|
||||
<div class="field">
|
||||
<label>Aktueller Pfad</label>
|
||||
<div id="viewerPathDisplay" class="path-display">automatisch erkannt</div>
|
||||
</div>
|
||||
<div class="modal-actions">
|
||||
<button id="browseViewerBtn" class="btn-secondary">Durchsuchen…</button>
|
||||
<button id="resetViewerBtn" class="btn-secondary">Zurücksetzen</button>
|
||||
<button id="closeSettingsBtn" class="btn-primary modal-close">Schließen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="vms.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -6,6 +6,9 @@ const emptyEl = document.getElementById('emptyState');
|
||||
const errorEl = document.getElementById('error');
|
||||
const noticeEl = document.getElementById('notice');
|
||||
const refreshBtn = document.getElementById('refreshBtn');
|
||||
const settingsBtn = document.getElementById('settingsBtn');
|
||||
const settingsOverlay = document.getElementById('settingsOverlay');
|
||||
const viewerPathDisplay = document.getElementById('viewerPathDisplay');
|
||||
|
||||
document.getElementById('logoutBtn').addEventListener('click', async () => {
|
||||
await api.proxmox.logout();
|
||||
@@ -13,6 +16,42 @@ document.getElementById('logoutBtn').addEventListener('click', async () => {
|
||||
|
||||
refreshBtn.addEventListener('click', () => loadVMs());
|
||||
|
||||
// ── Settings (Windows only — VirtViewer's install folder name carries the
|
||||
// version number, so auto-detection can miss non-standard installs) ──
|
||||
|
||||
initSettings();
|
||||
|
||||
async function initSettings() {
|
||||
const platform = await api.settings.platform();
|
||||
if (platform !== 'win32') return;
|
||||
|
||||
settingsBtn.classList.remove('hidden');
|
||||
settingsBtn.addEventListener('click', openSettings);
|
||||
document.getElementById('closeSettingsBtn').addEventListener('click', closeSettings);
|
||||
document.getElementById('browseViewerBtn').addEventListener('click', async () => {
|
||||
const chosen = await api.settings.browseViewerPath();
|
||||
if (chosen) await refreshViewerPathDisplay();
|
||||
});
|
||||
document.getElementById('resetViewerBtn').addEventListener('click', async () => {
|
||||
await api.settings.clearViewerPath();
|
||||
await refreshViewerPathDisplay();
|
||||
});
|
||||
}
|
||||
|
||||
async function openSettings() {
|
||||
await refreshViewerPathDisplay();
|
||||
settingsOverlay.classList.remove('hidden');
|
||||
}
|
||||
|
||||
function closeSettings() {
|
||||
settingsOverlay.classList.add('hidden');
|
||||
}
|
||||
|
||||
async function refreshViewerPathDisplay() {
|
||||
const viewerPath = await api.settings.getViewerPath();
|
||||
viewerPathDisplay.textContent = viewerPath || 'automatisch erkannt';
|
||||
}
|
||||
|
||||
// ── Load on mount ─────────────────────────────────────────
|
||||
|
||||
async function loadVMs() {
|
||||
|
||||
Reference in New Issue
Block a user