Files
Git-Manager-Gui/renderer/index.html
2026-03-25 23:07:07 +01:00

547 lines
26 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8" />
<title>Git Manager Explorer Pro</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https: http:; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none';">
<link rel="icon" type="image/png" href="./icon.png">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="app">
<!-- Titelbalken-Streifen -->
<div id="titlebar-strip">
<div class="titlebar-strip-brand">
<img src="./icon.png" alt="" class="titlebar-strip-icon">
<span class="titlebar-strip-title">Git Manager Explorer Pro</span>
</div>
<div class="win-controls" aria-label="Fenster-Steuerung">
<button class="win-btn win-btn--minimize" id="btnWinMinimize" title="Minimieren">
<svg width="10" height="1" viewBox="0 0 10 1"><rect width="10" height="1" fill="currentColor"/></svg>
</button>
<button class="win-btn win-btn--maximize" id="btnWinMaximize" title="Maximieren">
<svg width="10" height="10" viewBox="0 0 10 10"><rect x="0.5" y="0.5" width="9" height="9" rx="1" fill="none" stroke="currentColor"/></svg>
</button>
<button class="win-btn win-btn--close" id="btnWinClose" title="Schließen">
<svg width="10" height="10" viewBox="0 0 10 10"><line x1="0" y1="0" x2="10" y2="10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><line x1="10" y1="0" x2="0" y2="10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
</button>
</div>
</div>
<div id="toolbar">
<div class="toolbar-row toolbar-row--top">
<div class="toolbar-brand" aria-label="App Kopfbereich">
<div class="toolbar-brand-mark">
<img src="./icon.png" alt="Git Manager Logo" class="toolbar-brand-logo">
</div>
<div class="toolbar-brand-copy">
<span class="toolbar-kicker">Workspace Control</span>
<strong>Git Manager Explorer Pro</strong>
</div>
</div>
<div class="toolbar-top-actions">
<div class="tool-group tool-group--quick-actions">
<button id="btnOpenRepoActions" title="Neues Repository erstellen">🚀 New Repo</button>
<button id="btnOpenMigration" title="Repository von GitHub/GitLab zu Gitea migrieren">📥 Migrieren</button>
<button id="btnPush" title="Projekt pushen">⬆️ Push</button>
</div>
<div class="tool-group tool-group--utility">
<span class="tool-group-title">Steuerung</span>
<button id="btnSettings" title="Einstellungen">⚙️ Settings</button>
<button id="btnBatchActions" title="Batch-Aktionen">🧩 Batch</button>
<button id="btnOpenActivityLog" title="Aktivitätsprotokoll">📝 Activity</button>
<button id="btnRetryQueueNow" class="secondary" title="Retry-Queue jetzt verarbeiten">🔁 Queue (0)</button>
<button id="btnBack" class="secondary hidden" title="Zurück">⬅️ Zurück</button>
</div>
<div class="toolbar-status-wrap">
<span class="status-dot" aria-hidden="true"></span>
<span id="status" class="status">Bereit</span>
</div>
</div>
</div>
<div class="toolbar-row toolbar-row--bottom">
<div class="tool-group tool-group--workspace">
<span class="tool-group-title">Quelle</span>
<button id="btnSelectFolder" class="accent-btn" title="Lokalen Ordner öffnen">📂 Open Local</button>
<button id="btnLoadGiteaRepos" class="accent-btn" title="Projekte der gewählten Plattform laden">🌐 Load Projekte</button>
</div>
<div class="tool-group tool-group--repo">
<span class="tool-group-title">Repository</span>
<input id="platform" type="hidden" value="gitea">
<div class="platform-switch" role="tablist" aria-label="Plattform auswählen">
<button type="button" class="platform-option active" data-platform="gitea" aria-pressed="true">Gitea</button>
<button type="button" class="platform-option" data-platform="github" aria-pressed="false">GitHub</button>
</div>
<button id="btnCommits" class="hidden" title="Commit History anzeigen">📊 Commits</button>
<button id="btnReleases" class="hidden" title="Releases anzeigen">📦 Releases</button>
</div>
</div>
</div>
<div id="contentArea" class="content-area">
<aside id="favHistorySidebar" class="fav-history-sidebar" aria-label="Favoriten und Verlauf"></aside>
<main id="main">
<div id="explorerGrid" class="explorer-grid"></div>
</main>
</div>
<div id="settingsModal" class="modal hidden">
<div class="modalContent card settings-modal-content">
<button id="btnSettingsWatermark" class="settings-watermark-btn" title="Projektinformationen anzeigen" aria-label="Projektinformationen anzeigen"></button>
<div id="settingsWatermarkCard" class="settings-watermark-card hidden" role="dialog" aria-label="Projektinformationen">
<h4>Projektinformationen</h4>
<div class="settings-watermark-row"><span>Ersteller:</span><strong>M_Viper</strong></div>
<div class="settings-watermark-row"><span>Webseite:</span><a href="https://m-viper.de" target="_blank" rel="noopener noreferrer">https://m-viper.de</a></div>
<div class="settings-watermark-row"><span>Discord:</span><a id="watermarkDiscord" href="https://discord.com/invite/FdRs4BRd8D" target="_blank" rel="noopener noreferrer">discord.com/invite/FdRs4BRd8D</a></div>
<div class="settings-watermark-row"><span>E-Mail:</span><a id="watermarkMail" href="mailto:admin@m-viper.de">admin@m-viper.de</a></div>
<div class="settings-watermark-row"><span>Version:</span><strong id="watermarkVersion">-</strong></div>
<div class="settings-watermark-row"><span>Copyright:</span><strong id="watermarkCopyright">-</strong></div>
<div class="settings-watermark-row"><span>Projekt:</span><strong>Git Manager Explorer Pro</strong></div>
</div>
<div class="settings-header">
<div class="settings-header-inner">
<div class="settings-avatar-wrap" id="settingsAvatarWrap" title="Profilbild ändern">
<img id="settingsAvatarImg" class="settings-avatar-img" src="" alt="Avatar" style="display:none;">
<div id="settingsAvatarPlaceholder" class="settings-avatar-placeholder">👤</div>
<div class="settings-avatar-overlay">✏️</div>
<input id="settingsAvatarInput" type="file" accept="image/*" style="display:none;">
</div>
<button id="btnUploadAvatar" class="settings-avatar-upload-btn" title="Gespeichertes Bild jetzt auf Gitea hochladen">📤 Auf Gitea aktualisieren</button>
<div>
<div class="settings-eyebrow">Konfiguration</div>
<h2>⚙️ Einstellungen</h2>
<p class="settings-subtitle">Alle wichtigen Optionen auf einer Seite: Zugangsdaten, Verbindungscheck, Darstellung und Updates.</p>
</div>
</div>
</div>
<div class="settings-layout">
<div class="settings-column settings-column--left">
<section class="settings-panel settings-panel--credentials">
<div class="settings-panel-header">
<div>
<h3>Zugangsdaten</h3>
<p>API-Zugriffe für GitHub und Gitea konfigurieren.</p>
</div>
</div>
<div class="settings-credentials-grid">
<article class="settings-auth-card settings-auth-card--github">
<div class="settings-auth-card-header">
<h4>GitHub</h4>
<button id="btnTestGithubConnection" class="secondary" type="button">🔌 Verbindung testen</button>
</div>
<div class="input-group settings-auth-input">
<label for="githubToken">GitHub Token</label>
<input id="githubToken" type="password" placeholder="ghp_...">
</div>
<div class="settings-auth-spacer" aria-hidden="true">GitHub benötigt keine Server-URL</div>
<div id="githubTokenHint" class="settings-inline-hint">Hinweis: Der Token wird direkt über api.github.com geprüft.</div>
</article>
<article class="settings-auth-card settings-auth-card--gitea">
<div class="settings-auth-card-header">
<h4>Gitea</h4>
<button id="btnTestGiteaConnection" class="secondary" type="button">🔌 Verbindung testen</button>
</div>
<div class="input-group settings-auth-input">
<label for="giteaToken">Gitea Token</label>
<input id="giteaToken" type="password" placeholder="Token hier einfügen">
</div>
<div class="input-group settings-auth-input">
<label for="giteaURL">Gitea URL</label>
<input id="giteaURL" type="text" placeholder="https://gitea.example.com">
</div>
<div id="giteaUrlHint" class="settings-inline-hint">Hinweis: IPv6 mit Klammern eingeben, z.B. http://[2001:db8::1]:3000</div>
</article>
</div>
</section>
<section class="settings-panel settings-panel--display">
<div class="settings-panel-header">
<div>
<h3>Darstellung</h3>
<p>Übersicht und Explorer an deinen Arbeitsstil anpassen.</p>
</div>
</div>
<div class="settings-toggle-list">
<label class="settings-toggle-row" for="settingFavorites">
<span class="settings-toggle-info">
<span class="settings-toggle-title">⭐ Favoriten-Bereich anzeigen</span>
<span class="settings-toggle-desc">Pinnt wichtige Repositories und Ordner sichtbar im Kopfbereich.</span>
</span>
<span class="toggle-switch">
<input type="checkbox" id="settingFavorites" checked>
<span class="toggle-track"></span>
</span>
</label>
<label class="settings-toggle-row" for="settingRecent">
<span class="settings-toggle-info">
<span class="settings-toggle-title">🕐 Zuletzt geöffnet anzeigen</span>
<span class="settings-toggle-desc">Zeigt deine letzten Projekte direkt in der Übersicht an.</span>
</span>
<span class="toggle-switch">
<input type="checkbox" id="settingRecent" checked>
<span class="toggle-track"></span>
</span>
</label>
<label class="settings-toggle-row" for="settingCompact">
<span class="settings-toggle-info">
<span class="settings-toggle-title">⊞ Kompakt-Modus</span>
<span class="settings-toggle-desc">Verdichtet Karten und Abstände für kleinere Fenster.</span>
</span>
<span class="toggle-switch">
<input type="checkbox" id="settingCompact">
<span class="toggle-track"></span>
</span>
</label>
<label class="settings-toggle-row" for="settingColoredIcons">
<span class="settings-toggle-info">
<span class="settings-toggle-title">🎨 Farbige Datei-Icons</span>
<span class="settings-toggle-desc">Setzt stärkere Dateityp-Farben für schnellere Orientierung.</span>
</span>
<span class="toggle-switch">
<input type="checkbox" id="settingColoredIcons" checked>
<span class="toggle-track"></span>
</span>
</label>
</div>
</section>
</div>
<div class="settings-column settings-column--right">
<section class="settings-panel settings-panel--health">
<div class="settings-panel-header">
<div>
<h3>Verbindungsstatus</h3>
<p>Direkt sehen, ob URL, API und Auth sauber antworten.</p>
</div>
</div>
<div class="settings-health-box">
<div class="settings-health-row"><span>URL</span><strong id="healthUrl">Unbekannt</strong></div>
<div class="settings-health-row"><span>API</span><strong id="healthApi">Unbekannt</strong></div>
<div class="settings-health-row"><span>Auth</span><strong id="healthAuth">Unbekannt</strong></div>
<div class="settings-health-row"><span>Latenz</span><strong id="healthLatency">-</strong></div>
<div class="settings-health-row"><span>Server</span><strong id="healthVersion">-</strong></div>
<div class="settings-health-row"><span>Letzter Fehler</span><strong id="healthLastError">-</strong></div>
</div>
</section>
<section class="settings-panel settings-panel--system">
<div class="settings-panel-header">
<div>
<h3>System</h3>
<p>Verhalten beim Windows-Start steuern.</p>
</div>
</div>
<div class="settings-toggle-list">
<label class="settings-toggle-row" for="settingAutostart">
<span class="settings-toggle-info">
<span class="settings-toggle-title">🚀 Mit Windows starten</span>
<span class="settings-toggle-desc">Startet die App automatisch beim Anmelden, minimiert im System-Tray.</span>
</span>
<span class="toggle-switch">
<input type="checkbox" id="settingAutostart">
<span class="toggle-track"></span>
</span>
</label>
</div>
</section>
<section class="settings-panel settings-panel--app">
<div class="settings-panel-header">
<div>
<h3>App & Updates</h3>
<p>Version prüfen und neue Releases direkt anstoßen.</p>
</div>
</div>
<div class="settings-version-card">
<div class="input-group input-group--wide settings-version-field">
<label for="appVersion">App Version</label>
<input id="appVersion" class="settings-readonly-input" type="text" readonly>
</div>
<button id="btnCheckUpdates" class="settings-update-btn">🔄 Nach Updates suchen</button>
</div>
</section>
</div>
</div>
<div class="modal-buttons settings-modal-actions">
<button id="btnSaveSettings" class="accent-btn">Speichern</button>
<button id="btnCloseSettings" class="secondary">Abbrechen</button>
</div>
</div>
</div>
<div id="repoActionModal" class="modal hidden">
<div class="modalContent card">
<h2>🚀 Neues Repository erstellen</h2>
<div class="input-group">
<label>Repository Name</label>
<input id="repoName" type="text" placeholder="mein-projekt">
<div id="repoNameValidationHint" class="settings-inline-hint">Name prüfen: Duplikate, ähnliche Namen und ungültige Zeichen werden erkannt.</div>
</div>
<div class="input-group">
<label>Target Branch</label>
<input id="targetBranch" type="text" value="main" placeholder="main">
</div>
<div class="input-group">
<label>Lizenz</label>
<select id="licenseSelect">
<option value="">Keine Lizenz</option>
<option value="mit">MIT License</option>
<option value="apache-2.0">Apache 2.0</option>
<option value="gpl-3.0">GPL v3</option>
<option value="bsd-3-clause">BSD 3-Clause</option>
<option value="agpl-3.0">AGPL v3</option>
</select>
</div>
<div class="input-group">
<label style="display: flex; align-items: center; gap: 8px; cursor: pointer;">
<input type="checkbox" id="createReadme" checked>
<span style="text-transform: none; letter-spacing: normal;">README.md initialisieren</span>
</label>
</div>
<div class="input-group">
<label>Lokaler Push-Branch</label>
<select id="branchSelect">
<option value="main">main</option>
</select>
</div>
<div class="modal-buttons">
<button id="btnCreateRepo" class="accent-btn">Erstellen</button>
<button id="btnCloseRepoActions" class="secondary">Abbrechen</button>
</div>
</div>
</div>
<!-- Migration Modal -->
<div id="migrationModal" class="modal hidden">
<div class="modalContent card migration-modal-content">
<h2>📥 Repository migrieren</h2>
<p class="settings-subtitle">Ein Repository von GitHub, GitLab oder einer anderen Git-Quelle auf deine Gitea-Instanz kopieren.</p>
<div class="migration-fields">
<div class="input-group">
<label for="migrateCloneUrl">Quell-URL (Clone-URL)</label>
<input id="migrateCloneUrl" type="text" placeholder="https://github.com/benutzer/repo.git">
<div class="settings-inline-hint">Beispiel: https://github.com/M_Viper/NexTrade.git</div>
</div>
<div class="input-group">
<label for="migrateRepoName">Neuer Repository-Name auf Gitea</label>
<input id="migrateRepoName" type="text" placeholder="NexTrade">
</div>
<div class="input-group">
<label for="migrateDescription">Beschreibung (optional)</label>
<input id="migrateDescription" type="text" placeholder="">
</div>
<div class="migration-row-split">
<div class="input-group">
<label for="migrateAuthUsername">Auth-Benutzername (bei privaten Repos)</label>
<input id="migrateAuthUsername" type="text" placeholder="GitHub-Benutzername">
</div>
<div class="input-group">
<label for="migrateAuthToken">Auth-Token (bei privaten Repos)</label>
<input id="migrateAuthToken" type="password" placeholder="ghp_…">
</div>
</div>
<label class="settings-toggle-row" style="margin-top:4px;" for="migratePrivate">
<span class="settings-toggle-info">
<span class="settings-toggle-title">🔒 Privates Repository</span>
</span>
<span class="toggle-switch">
<input type="checkbox" id="migratePrivate">
<span class="toggle-track"></span>
</span>
</label>
</div>
<div id="migrationStatus" class="migration-status hidden"></div>
<div class="modal-buttons">
<button id="btnStartMigration" class="accent-btn">📥 Migration starten</button>
<button id="btnCloseMigration" class="secondary">Abbrechen</button>
</div>
</div>
</div>
<div id="batchActionModal" class="modal hidden">
<div class="modalContent card">
<h2>🧩 Batch-Aktionen</h2>
<div class="input-group">
<label>Aktion</label>
<select id="batchActionType">
<option value="refresh">Repos aktualisieren</option>
<option value="clone">Repos klonen</option>
<option value="create-tag">Tag erstellen</option>
<option value="create-release">Release erstellen</option>
</select>
</div>
<div class="input-group">
<label>Repositories (pro Zeile: owner/repo)</label>
<textarea id="batchRepoList" class="batch-textarea" placeholder="M_Viper/ProjektA&#10;M_Viper/ProjektB"></textarea>
</div>
<div id="batchCloneGroup" class="input-group hidden">
<label>Zielordner für Clone</label>
<div class="batch-inline-row">
<input id="batchCloneTarget" type="text" readonly placeholder="Bitte Zielordner auswählen">
<button id="btnSelectBatchCloneTarget" class="secondary">📁 Wählen</button>
</div>
<div id="batchCloneValidationHint" class="settings-inline-hint">Kollisionsprüfung aktiv: vorhandene Zielordner und Namenskonflikte werden angezeigt.</div>
</div>
<div id="batchTagGroup" class="input-group hidden">
<label>Tag</label>
<input id="batchTagName" type="text" placeholder="v1.0.0">
</div>
<div id="batchReleaseNameGroup" class="input-group hidden">
<label>Release-Name</label>
<input id="batchReleaseName" type="text" placeholder="Release v1.0.0">
</div>
<div id="batchReleaseBodyGroup" class="input-group hidden">
<label>Release-Text</label>
<textarea id="batchReleaseBody" class="batch-textarea" placeholder="Changelog..."></textarea>
</div>
<div class="modal-buttons">
<button id="btnRunBatchAction" class="accent-btn">Ausführen</button>
<button id="btnCloseBatchAction" class="secondary">Abbrechen</button>
</div>
</div>
</div>
<div id="activityLogModal" class="modal hidden">
<div class="modalContent card">
<h2>📝 Aktivitätsprotokoll</h2>
<div class="activity-toolbar">
<select id="activityFilterLevel">
<option value="all">Alle</option>
<option value="info">Info</option>
<option value="warning">Warn</option>
<option value="error">Error</option>
</select>
<button id="btnRetryQueueRefresh" class="secondary">🔁 Queue jetzt retry</button>
<button id="btnClearActivityLog" class="secondary">🧹 Log leeren</button>
</div>
<div id="activityQueueInfo" class="activity-queue-info">Retry-Queue: 0</div>
<div id="activityLogList" class="activity-log-list"></div>
<div class="modal-buttons">
<button id="btnCloseActivityLog" class="secondary">Schließen</button>
</div>
</div>
</div>
<div id="fileEditorModal" class="modal hidden">
<div class="file-editor-card">
<div class="file-editor-header">
<div class="file-editor-title">
<span id="fileEditorIcon">📄</span>
<span id="fileEditorName">file.txt</span>
</div>
<div class="file-editor-toolbar">
<button id="btnEditorSearch" class="editor-tool-btn" title="Suchen (Ctrl+F)">🔍</button>
<button id="btnEditorSave" class="editor-tool-btn" title="Speichern">💾</button>
<button id="btnCloseEditor" class="editor-tool-btn" title="Schließen"></button>
</div>
</div>
<div id="fileEditorTabs" class="file-editor-tabs"></div>
<div id="searchBar" class="search-bar hidden">
<input id="searchInput" type="text" class="search-input" placeholder="Suchen...">
<input id="replaceInput" type="text" class="search-input" placeholder="Ersetzen...">
<button id="btnReplace" class="search-btn">Ersetzen</button>
<button id="btnReplaceAll" class="search-btn">Alle</button>
<button id="btnCloseSearch" class="search-btn"></button>
<span id="searchInfo" class="search-info">0/0</span>
</div>
<div class="file-editor-container">
<div id="lineNumbers" class="line-numbers"></div>
<textarea id="fileEditorContent" class="file-editor-textarea" placeholder="Dateiinhalt..."></textarea>
<div id="imagePreview" class="image-preview hidden"></div>
</div>
<div class="file-editor-footer">
<div class="file-editor-info">
<span id="fileEditorPath" class="file-path">Pfad: /path/to/file</span>
<span id="fileEditorStats" class="file-stats"></span>
<span id="fileEditorCursor" class="file-cursor">Zeile 1, Spalte 1</span>
<span id="autoSaveStatus" class="auto-save-status" style="display:none;">✓ Gespeichert</span>
</div>
<div class="modal-buttons">
<button id="btnDiscardEdit" class="secondary">Verwerfen</button>
</div>
</div>
</div>
</div>
<div id="updateModal" class="modal hidden">
<div class="modalContent card" style="max-width: 450px; border: 1px solid var(--accent-primary); box-shadow: 0 0 30px rgba(0, 212, 255, 0.2);">
<div style="display: flex; align-items: center; gap: 20px; margin-bottom: 20px;">
<div style="font-size: 3rem; filter: drop-shadow(0 0 10px var(--accent-primary));">🚀</div>
<div>
<h2 style="margin: 0; background: var(--accent-gradient); background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">Update verfügbar!</h2>
<p id="updateVersionInfo" style="color: var(--text-secondary); margin: 5px 0 0 0; font-family: monospace;"></p>
</div>
</div>
<div class="input-group">
<label style="color: var(--accent-primary); font-size: 0.8rem; letter-spacing: 1px;">RELEASE NOTES</label>
<div id="updateChangelog" style="
background: rgba(0,0,0,0.25);
padding: 15px;
border-radius: 8px;
max-height: 180px;
overflow-y: auto;
font-size: 0.9rem;
line-height: 1.6;
color: var(--text-primary);
border: 1px solid rgba(255,255,255,0.05);
white-space: pre-wrap;
"></div>
</div>
<div class="modal-buttons" style="margin-top: 25px; gap: 12px;">
<button id="btnStartUpdate" class="accent-btn" style="flex: 2; height: 45px; font-weight: bold;">🚀 Jetzt installieren</button>
<button id="btnIgnoreUpdate" class="secondary" style="flex: 1; height: 45px;">Später</button>
</div>
</div>
</div>
</div> <script src="renderer.js"></script>
</body>
</html>