From 9f7eacecb9d639b4ace673b72571d48ca60ac74d Mon Sep 17 00:00:00 2001
From: Alexander Sabino <32822107+asabino2@users.noreply.github.com>
Date: Sun, 10 May 2026 10:45:37 +0100
Subject: [PATCH] =?UTF-8?q?atualiza=20vers=C3=A3o=20para=200.1.5;=20adicio?=
=?UTF-8?q?na=20bot=C3=A3o=20de=20log=20na=20aba=20Backup=20Runs,=20novo?=
=?UTF-8?q?=20endpoint=20para=20detalhes=20de=20backup=20e=20melhora=20a?=
=?UTF-8?q?=20exibi=C3=A7=C3=A3o=20do=20changelog?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 16 +++++++--
package.json | 2 +-
public/app.js | 62 +++++++++++++++++++++++++++++++-
public/index.html | 19 ++++++++--
public/styles.css | 84 ++++++++++++++++++++++++++++++++++++++++++--
src/backupService.js | 4 +++
src/server.js | 13 +++++++
7 files changed, 192 insertions(+), 8 deletions(-)
diff --git a/README.md b/README.md
index c18f7cb..ff5785b 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-
+
@@ -9,7 +9,7 @@
-
+
@@ -23,6 +23,18 @@ Versão atual: **0.1.4**
---
## � Changelog
+### [0.1.5] — 2026-05-10
+
+#### Adicionado
+- **Botão `Log` na aba Backup Runs:** cada run exibe agora um botão que abre um modal com o log completo do backup por container, incluindo saída do tar, avisos e erros ocorridos durante a execução.
+- **Endpoint `GET /api/backups/:backupId`:** novo endpoint que retorna os dados completos de um backup (incluindo logs) a partir do seu ID.
+- **Logs persistidos por container no backup:** o array de logs gerado durante o backup (`pushLog`) é agora salvo em `containerBackup.logs` e persistido no `store.json`, disponível para consulta posterior.
+
+#### Melhorado
+- **Dropdowns estilizados como campos de texto:** todos os elementos `` dentro de `.form-field` e o `.settings-select` passaram a usar o mesmo estilo visual dos inputs de texto (borda, padding, tipografia), com ícone de seta customizado via SVG.
+- **Tela Sobre — posição do autor:** o texto `Desenvolvido por Alexander Sabino em 2026` foi movido para logo abaixo da descrição da aplicação.
+- **Tela Sobre — changelog limitado:** a seção de changelog exibe agora apenas as últimas 4 entradas de versão.
+
### [0.1.4] — 2026-05-09
#### Corrigido
diff --git a/package.json b/package.json
index 4a59dae..ef0bc96 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "dockerbackup-app",
- "version": "0.1.4",
+ "version": "0.1.5",
"description": "Aplicacao web para backup e restauracao de volumes Docker",
"main": "src/server.js",
"scripts": {
diff --git a/public/app.js b/public/app.js
index ac30f77..1a96a6f 100644
--- a/public/app.js
+++ b/public/app.js
@@ -635,6 +635,7 @@ async function loadAllRuns() {
${fileCount || '—'}
${sizeStr}
${escapeHtml(new Date(b.createdAt).toLocaleString('pt-BR'))}
+ Log
`;
}).join('');
@@ -1818,7 +1819,7 @@ function markdownInline(raw) {
.replace(/`([^`]+)`/g, '$1');
}
-function parseChangelogSection(markdown) {
+function parseChangelogSection(markdown, maxEntries = 4) {
// Extract from ## Changelog (or ## 🗂 Changelog etc.) to next ##
const start = markdown.search(/^##\s+[^\n]*[Cc]hangelog/m);
if (start === -1) return null;
@@ -1829,6 +1830,7 @@ function parseChangelogSection(markdown) {
const lines = section.split('\n');
let html = '';
let inList = false;
+ let entryCount = 0;
for (const line of lines) {
const h3 = line.match(/^###\s+(.+)/);
@@ -1836,12 +1838,16 @@ function parseChangelogSection(markdown) {
const li = line.match(/^-\s+(.+)/);
if (h3) {
+ if (entryCount >= maxEntries) break;
if (inList) { html += ''; inList = false; }
html += `${markdownInline(h3[1].replace(/\[([^\]]+)\]/, '$1'))} `;
+ entryCount += 1;
} else if (h4) {
+ if (entryCount > maxEntries) break;
if (inList) { html += ''; inList = false; }
html += `${markdownInline(h4[1])} `;
} else if (li) {
+ if (entryCount > maxEntries) break;
if (!inList) { html += ''; inList = true; }
html += `${markdownInline(li[1])} `;
} else if (line.startsWith('---') || line.startsWith('## ')) {
@@ -1939,6 +1945,60 @@ elements.profilesList.addEventListener('click', handleProfileAction);
document.querySelector('#backupsViewList').addEventListener('click', handleProfileAction);
document.querySelector('#refreshRuns')?.addEventListener('click', () => loadAllRuns());
+// Run log modal
+document.querySelector('#allRunsBody')?.addEventListener('click', async (e) => {
+ const btn = e.target.closest('.run-log-btn');
+ if (!btn) return;
+ const backupId = btn.dataset.backupId;
+ if (!backupId) return;
+ openRunLogModal(backupId);
+});
+
+document.querySelector('#runLogModalClose')?.addEventListener('click', () => {
+ document.querySelector('#runLogModal')?.classList.add('hidden');
+});
+document.querySelector('#runLogModal')?.addEventListener('click', (e) => {
+ if (e.target.dataset.action === 'close-run-log-modal') {
+ document.querySelector('#runLogModal').classList.add('hidden');
+ }
+});
+
+async function openRunLogModal(backupId) {
+ const modal = document.querySelector('#runLogModal');
+ const content = document.querySelector('#runLogContent');
+ if (!modal || !content) return;
+ modal.classList.remove('hidden');
+ content.innerHTML = 'Carregando log...
';
+ try {
+ const backup = await api(`/api/backups/${encodeURIComponent(backupId)}`);
+ const containers = backup.containers || [];
+ if (!containers.length) {
+ content.innerHTML = 'Nenhum log disponível para este backup.
';
+ return;
+ }
+ let html = '';
+ for (const c of containers) {
+ const name = escapeHtml(c.containerName || c.containerId || '?');
+ const status = escapeHtml(c.status || '—');
+ html += ``;
+ html += `
${name} ${status} `;
+ if (c.error) {
+ html += `
Erro: ${escapeHtml(c.error)}
`;
+ }
+ const logs = c.logs || [];
+ if (logs.length) {
+ html += `
${logs.map((l) => escapeHtml(l)).join('\n')} `;
+ } else {
+ html += `
Sem log detalhado (backup pode ter sido criado antes desta versão).
`;
+ }
+ html += `
`;
+ }
+ content.innerHTML = html;
+ } catch (err) {
+ content.innerHTML = `Erro ao carregar log: ${escapeHtml(err.message)}
`;
+ }
+}
+
// Apply translations early (before auth check so login page is translated)
applyTranslations();
checkAuthAndInit();
\ No newline at end of file
diff --git a/public/index.html b/public/index.html
index aa937b7..0ac824c 100644
--- a/public/index.html
+++ b/public/index.html
@@ -193,10 +193,11 @@
Files
Size
Started
+ Actions
- Nenhum run encontrado.
+ Nenhum run encontrado.
@@ -296,6 +297,7 @@
DockerBackup
Aplicação web para backup e restauração de volumes Docker com suporte a snapshots incrementais e restore seletivo.
+ Desenvolvido por Alexander Sabino em 2026
@@ -319,7 +321,6 @@
Carregando changelog...
- Desenvolvido por Alexander Sabino em 2026
@@ -579,6 +580,20 @@
+
+
+