Add project-scoped methods to Api backend
This commit is contained in:
+90
-6
@@ -263,14 +263,16 @@ const ApiBackend = {
|
||||
} catch { return {}; }
|
||||
},
|
||||
|
||||
async loadArchive() {
|
||||
const r = await fetch('/api/archive');
|
||||
async loadArchive(project = null) {
|
||||
const url = project ? `/api/projects/${encodeURIComponent(project)}/archive` : '/api/archive';
|
||||
const r = await fetch(url);
|
||||
if (!r.ok) throw new Error('API archive load failed: ' + r.status);
|
||||
return r.json(); // { content, checksum, exists }
|
||||
},
|
||||
|
||||
async saveArchive(backlogContent, archiveContent) {
|
||||
const r = await fetch('/api/archive', {
|
||||
async saveArchive(backlogContent, archiveContent, project = null) {
|
||||
const url = project ? `/api/projects/${encodeURIComponent(project)}/archive` : '/api/archive';
|
||||
const r = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ backlog: backlogContent, archive: archiveContent }),
|
||||
@@ -279,8 +281,9 @@ const ApiBackend = {
|
||||
return r.json();
|
||||
},
|
||||
|
||||
async restoreFromArchive(backlogContent, archiveContent) {
|
||||
const r = await fetch('/api/archive/restore', {
|
||||
async restoreFromArchive(backlogContent, archiveContent, project = null) {
|
||||
const url = project ? `/api/projects/${encodeURIComponent(project)}/archive/restore` : '/api/archive/restore';
|
||||
const r = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ backlog: backlogContent, archive: archiveContent }),
|
||||
@@ -288,6 +291,87 @@ const ApiBackend = {
|
||||
if (!r.ok) throw new Error('API archive restore failed: ' + r.status);
|
||||
return r.json();
|
||||
},
|
||||
|
||||
// ---- Project-scoped methods (multi-project server API) ----
|
||||
|
||||
async listProjects() {
|
||||
const r = await fetch('/api/projects');
|
||||
if (!r.ok) throw new Error('API projects failed: ' + r.status);
|
||||
return (await r.json()).projects || [];
|
||||
},
|
||||
|
||||
async registerProject(path, name = null) {
|
||||
const r = await fetch('/api/projects', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ path, name }),
|
||||
});
|
||||
return r.json(); // { ok, name, path }
|
||||
},
|
||||
|
||||
async unregisterProject(name, deleteFile = false) {
|
||||
const r = await fetch(`/api/projects/${encodeURIComponent(name)}${deleteFile ? '?delete_file=true' : ''}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
return r.json(); // { ok, name, deleted, warning? }
|
||||
},
|
||||
|
||||
async renameProject(name, newName) {
|
||||
const r = await fetch(`/api/projects/${encodeURIComponent(name)}/rename`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ newName }),
|
||||
});
|
||||
return r.json(); // { ok, name }
|
||||
},
|
||||
|
||||
async loadProject(name) {
|
||||
const r = await fetch(`/api/projects/${encodeURIComponent(name)}/backlog`);
|
||||
if (!r.ok) throw new Error('API project load failed: ' + r.status);
|
||||
return r.json(); // { content, checksum }
|
||||
},
|
||||
|
||||
async saveProject(name, content) {
|
||||
const r = await fetch(`/api/projects/${encodeURIComponent(name)}/backlog`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ content }),
|
||||
});
|
||||
if (!r.ok) throw new Error('API project save failed: ' + r.status);
|
||||
return r.json(); // { ok, checksum, saved }
|
||||
},
|
||||
|
||||
async loadProjectBackups(name) {
|
||||
try {
|
||||
const r = await fetch(`/api/projects/${encodeURIComponent(name)}/backups`);
|
||||
if (!r.ok) return [];
|
||||
return (await r.json()).backups || [];
|
||||
} catch { return []; }
|
||||
},
|
||||
|
||||
async loadAllProjects() {
|
||||
const list = await this.listProjects();
|
||||
return Promise.all(list.map(async p => {
|
||||
if (p.missing) {
|
||||
return { id: p.name, name: p.name, path: p.path, entries: [], history: [], meta: null, checksumOk: true, missing: true };
|
||||
}
|
||||
try {
|
||||
const raw = await this.loadProject(p.name);
|
||||
const parsed = await Parser.parse(raw.content);
|
||||
return {
|
||||
id: p.name,
|
||||
name: p.name,
|
||||
path: p.path,
|
||||
entries: parsed.entries,
|
||||
history: parsed.history,
|
||||
meta: parsed.meta,
|
||||
checksumOk: parsed.checksumOk,
|
||||
};
|
||||
} catch (e) {
|
||||
return { id: p.name, name: p.name, path: p.path, entries: [], history: [], meta: null, checksumOk: false, error: String(e.message || e) };
|
||||
}
|
||||
}));
|
||||
},
|
||||
};
|
||||
|
||||
// ---- Direct File Backend (File System Access API) ----
|
||||
|
||||
Reference in New Issue
Block a user