diff --git a/backend/app/routers/git_mgr.py b/backend/app/routers/git_mgr.py
index c7f50ad..6c421eb 100644
--- a/backend/app/routers/git_mgr.py
+++ b/backend/app/routers/git_mgr.py
@@ -185,9 +185,13 @@ def git_status():
@router.get("/log")
-def git_log():
+def git_log(diagram_id: Optional[int] = None):
repo_root = _repo_root()
- r = _run("log", "--pretty=format:%H|%h|%s|%an|%ai", "-30", cwd=repo_root)
+ cmd = ["log", "--pretty=format:%H|%h|%s|%an|%ai", "--follow", "-50"]
+ if diagram_id is not None:
+ # Filter to commits that touched this diagram's file (glob by id prefix)
+ cmd += ["--", f"diagrams/{diagram_id:04d}_*.json"]
+ r = _run(*cmd, cwd=repo_root)
if r.returncode != 0:
return []
entries = []
diff --git a/frontend/css/main.css b/frontend/css/main.css
index 84df00e..7c58792 100644
--- a/frontend/css/main.css
+++ b/frontend/css/main.css
@@ -326,6 +326,14 @@ button:active { background: #1a1a3a; }
.git-hash { font-family: monospace; color: #6688cc; font-size: 11px; }
.git-msg { color: #bbc; font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.git-date { color: #445; font-size: 10px; text-align: right; }
+.git-scope-btn {
+ font-size: 10px; padding: 2px 8px;
+ background: #111122; border: 1px solid #2a2a44; color: #445566; cursor: pointer;
+}
+.git-scope-btn:first-of-type { border-radius: 3px 0 0 3px; }
+.git-scope-btn:last-of-type { border-radius: 0 3px 3px 0; border-left: none; }
+.git-scope-btn.active { background: #1a2840; border-color: #334466; color: #88aadd; }
+.git-scope-btn:disabled { opacity: 0.35; cursor: default; }
.git-restore-btn {
font-size: 10px; padding: 2px 6px;
background: #1a2840; border: 1px solid #334466; border-radius: 3px;
diff --git a/frontend/index.html b/frontend/index.html
index b0ec60c..2d25f91 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -449,8 +449,14 @@
-
-
+
+
+
+
+
+
+
+
diff --git a/frontend/js/api.js b/frontend/js/api.js
index 3bb63c2..d4af115 100644
--- a/frontend/js/api.js
+++ b/frontend/js/api.js
@@ -62,7 +62,7 @@ const api = {
},
git: {
status: () => apiFetch("/git/status"),
- log: () => apiFetch("/git/log"),
+ log: (diagram_id) => apiFetch(diagram_id != null ? `/git/log?diagram_id=${diagram_id}` : "/git/log"),
commit: (message, diagram_id) => apiFetch("/git/commit", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ message, diagram_id: diagram_id ?? null }) }),
push: () => apiFetch("/git/push", { method: "POST" }),
history: (hash) => apiFetch(`/git/history/${hash}`),
diff --git a/frontend/js/app.js b/frontend/js/app.js
index 25247a9..a206e17 100644
--- a/frontend/js/app.js
+++ b/frontend/js/app.js
@@ -2024,8 +2024,26 @@ class WiringApp {
commitBtn._gitBound = true;
commitBtn.addEventListener("click", () => this._gitCommit());
document.getElementById("btn-git-push").addEventListener("click", () => this._gitPush());
+
+ // History scope toggle
+ const btnDiagram = document.getElementById("btn-git-log-diagram");
+ const btnAll = document.getElementById("btn-git-log-all");
+ btnDiagram.addEventListener("click", () => {
+ btnDiagram.classList.add("active"); btnAll.classList.remove("active");
+ this._gitLoadLog();
+ });
+ btnAll.addEventListener("click", () => {
+ btnAll.classList.add("active"); btnDiagram.classList.remove("active");
+ this._gitLoadLog();
+ });
}
+ // Default scope: "this diagram" if one is open, else "all"
+ const hasDiagram = !!this.diagramId;
+ document.getElementById("btn-git-log-diagram").classList.toggle("active", hasDiagram);
+ document.getElementById("btn-git-log-all").classList.toggle("active", !hasDiagram);
+ document.getElementById("btn-git-log-diagram").disabled = !hasDiagram;
+
await this._gitRefresh();
}
@@ -2051,9 +2069,13 @@ class WiringApp {
async _gitLoadLog() {
const list = document.getElementById("git-log-list");
if (!list) return;
+ const diagramScope = document.getElementById("btn-git-log-diagram")?.classList.contains("active");
+ const diagramId = diagramScope && this.diagramId ? this.diagramId : null;
+ const title = document.getElementById("git-log-title");
+ if (title) title.textContent = diagramId ? "History — this diagram" : "History — all commits";
list.innerHTML = 'Loading…
';
try {
- const entries = await api.git.log();
+ const entries = await api.git.log(diagramId);
if (!entries.length) {
list.innerHTML = 'No commits yet
';
return;