Spaces:
Running
Running
File size: 2,103 Bytes
ffcad5d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | /**
* Server persistence helpers for Workspace + Documents (phd-canvas API).
* Failures are soft — callers keep localStorage as a fallback cache.
*/
const apiBase = () => process.env.REACT_APP_API_URL || '';
const authHeaders = (token) => ({
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
});
export async function fetchCanvas(authToken) {
if (!authToken) return null;
try {
const resp = await fetch(`${apiBase()}/api/phd-canvas`, {
headers: authHeaders(authToken),
});
if (!resp.ok) return null;
return await resp.json();
} catch {
return null;
}
}
export async function saveWorkspace(authToken, workspace) {
if (!authToken) return false;
try {
const resp = await fetch(`${apiBase()}/api/phd-canvas/workspace`, {
method: 'PUT',
headers: authHeaders(authToken),
body: JSON.stringify({
layout: workspace.layout || [],
states: workspace.states || {},
view: workspace.view ?? undefined,
task_statuses: workspace.task_statuses ?? undefined,
}),
});
return resp.ok;
} catch {
return false;
}
}
export async function saveDeliverables(authToken, store) {
if (!authToken) return false;
try {
const resp = await fetch(`${apiBase()}/api/phd-canvas/deliverables`, {
method: 'PUT',
headers: authHeaders(authToken),
body: JSON.stringify({
activeProjectId: store.activeProjectId ?? null,
projects: store.projects || {},
}),
});
return resp.ok;
} catch {
return false;
}
}
/** Simple debounce — returns a cancelable scheduler. */
export function debounce(fn, ms = 800) {
let t = null;
const wrapped = (...args) => {
if (t) clearTimeout(t);
t = setTimeout(() => {
t = null;
fn(...args);
}, ms);
};
wrapped.cancel = () => {
if (t) clearTimeout(t);
t = null;
};
wrapped.flush = (...args) => {
if (t) clearTimeout(t);
t = null;
fn(...args);
};
return wrapped;
}
|