Update from Git Manager GUI

This commit is contained in:
2026-02-03 22:52:35 +01:00
parent df9790177d
commit 20a9d601ff

View File

@@ -1827,11 +1827,23 @@ async function loadRepoReleases(owner, repo) {
</div>
`;
// Event-Listener MUSS VOR innerHTML += gesetzt werden
const newBtn = grid.querySelector('.btn-new-release');
newBtn.onclick = () => showCreateReleaseModal(owner, repo);
if (newBtn) {
newBtn.onclick = () => {
console.log('New Release button clicked');
showCreateReleaseModal(owner, repo);
};
} else {
console.error('New Release button not found in DOM');
}
if (!res.releases || res.releases.length === 0) {
grid.innerHTML += '<div style="grid-column: 1/-1; text-align: center; padding: 60px; color: var(--text-muted); font-size: 16px;">📭 Noch keine Releases veröffentlicht</div>';
// WICHTIG: appendChild statt innerHTML +=, um Event-Listener zu erhalten
const emptyMsg = document.createElement('div');
emptyMsg.style.cssText = 'grid-column: 1/-1; text-align: center; padding: 60px; color: var(--text-muted); font-size: 16px;';
emptyMsg.textContent = '📭 Noch keine Releases veröffentlicht';
grid.appendChild(emptyMsg);
setStatus('No releases');
return;
}
@@ -2134,10 +2146,12 @@ function createReleaseCard(release, isLatest) {
CREATE RELEASE MODAL
------------------------- */
function showCreateReleaseModal(owner, repo) {
let selectedFiles = [];
const modal = document.createElement('div');
modal.className = 'modal';
modal.innerHTML = `
<div class="card" style="width: 600px; max-width: 90vw;">
<div class="card" style="width: 650px; max-width: 90vw;">
<h2>🚀 Neues Release erstellen</h2>
<div class="input-group">
@@ -2173,6 +2187,23 @@ function showCreateReleaseModal(owner, repo) {
<input id="releaseTarget" type="text" value="main" placeholder="main">
</div>
<div class="input-group">
<label>📎 Release Assets (optional)</label>
<button id="btnSelectAssets" style="
width: 100%;
padding: 12px;
background: var(--bg-tertiary);
border: 2px dashed rgba(255, 255, 255, 0.2);
border-radius: var(--radius-md);
color: var(--text-secondary);
cursor: pointer;
transition: all 0.2s;
">
📁 Dateien auswählen (z.B. .exe, .zip, .tar.gz)
</button>
<div id="assetsList" style="margin-top: 10px;"></div>
</div>
<div class="input-group" style="display: flex; gap: 20px;">
<label style="display: flex; align-items: center; gap: 8px; cursor: pointer;">
<input type="checkbox" id="releasePrerelease"> Pre-Release
@@ -2191,6 +2222,52 @@ function showCreateReleaseModal(owner, repo) {
document.body.appendChild(modal);
// Asset-Auswahl Handler
$('btnSelectAssets').onclick = async () => {
const res = await window.electronAPI.selectFile();
if (res.ok && res.files && res.files.length > 0) {
selectedFiles = res.files;
updateAssetsList();
}
};
function updateAssetsList() {
const list = $('assetsList');
if (selectedFiles.length === 0) {
list.innerHTML = '';
return;
}
list.innerHTML = selectedFiles.map((file, idx) => `
<div style="
display: flex;
align-items: center;
gap: 10px;
padding: 8px 12px;
background: var(--bg-tertiary);
border-radius: var(--radius-sm);
margin-bottom: 6px;
">
<span style="flex: 1; color: var(--text-primary); font-size: 13px;">📄 ${file.name}</span>
<button onclick="removeAsset(${idx})" style="
background: rgba(255, 59, 48, 0.2);
color: #ff3b30;
border: none;
padding: 4px 8px;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
">✕</button>
</div>
`).join('');
}
// Asset entfernen (global für onclick)
window.removeAsset = (idx) => {
selectedFiles.splice(idx, 1);
updateAssetsList();
};
$('btnCreateRelease').onclick = async () => {
const tag = $('releaseTag').value.trim();
const name = $('releaseName').value.trim() || tag;
@@ -2204,6 +2281,11 @@ function showCreateReleaseModal(owner, repo) {
return;
}
const btnCreate = $('btnCreateRelease');
const originalText = btnCreate.textContent;
btnCreate.disabled = true;
btnCreate.textContent = 'Erstelle Release...';
setStatus('Creating release...');
try {
@@ -2219,15 +2301,43 @@ function showCreateReleaseModal(owner, repo) {
});
if (res.ok) {
// Assets hochladen, falls vorhanden
if (selectedFiles.length > 0) {
btnCreate.textContent = `Lade Assets (0/${selectedFiles.length})...`;
setStatus(`Uploading ${selectedFiles.length} asset(s)...`);
for (let i = 0; i < selectedFiles.length; i++) {
const file = selectedFiles[i];
btnCreate.textContent = `Lade Assets (${i + 1}/${selectedFiles.length})...`;
try {
await window.electronAPI.uploadReleaseAsset({
owner,
repo,
releaseId: res.release.id,
filePath: file.path,
fileName: file.name
});
} catch (err) {
console.error('Asset upload error:', err);
// Weiter mit nächster Datei
}
}
}
modal.remove();
setStatus('Release created!');
setStatus('Release created successfully!');
loadRepoReleases(owner, repo); // Reload
} else {
setStatus('Failed: ' + res.error);
btnCreate.disabled = false;
btnCreate.textContent = originalText;
}
} catch (error) {
console.error('Create release error:', error);
setStatus('Create failed');
btnCreate.disabled = false;
btnCreate.textContent = originalText;
}
};
@@ -2250,8 +2360,9 @@ async function showUploadAssetDialog(release) {
return;
}
const filePath = res.files[0];
const fileName = filePath.split(/[\\/]/).pop();
const file = res.files[0];
const filePath = file.path;
const fileName = file.name;
setStatus(`Uploading ${fileName}...`);
showProgress(0, `Uploading ${fileName}...`);