48 lines
1.9 KiB
JavaScript
48 lines
1.9 KiB
JavaScript
// Remote planning storage, backed by a WebDAV client.
|
|
//
|
|
// This factory and createMemoryPlanningStore implement the SAME contract on
|
|
// purpose: loadWeek / saveWeek / describeStorage. The page picks one of them
|
|
// once and never has to test `client === null` afterwards. Two implementations,
|
|
// one contract — that is what makes this brick replaceable.
|
|
|
|
function buildPlanningPath(folder, weekId) {
|
|
return folder + '/plannings/' + weekId + '.json'
|
|
}
|
|
|
|
// MKCOL only creates one level at a time, so the root folder comes first.
|
|
async function ensurePlanningFolder(client, folder) {
|
|
await client.ensureFolder(folder)
|
|
return client.ensureFolder(folder + '/plannings')
|
|
}
|
|
|
|
export function createPlanningStore(client, folder) {
|
|
// No try/catch here: the client already turns every network failure into a
|
|
// result object (see app/services/webdav), so nothing below can throw.
|
|
async function loadWeek(weekId) {
|
|
const result = await client.readJson(buildPlanningPath(folder, weekId))
|
|
if (result.ok) return { ok: true, planning: result.data }
|
|
// A week that was never written is not an error, it is an empty week.
|
|
if (result.failure.kind === 'notFound') return { ok: true, planning: null }
|
|
return { ok: false, failure: result.failure }
|
|
}
|
|
|
|
async function saveWeek(weekId, planning) {
|
|
const path = buildPlanningPath(folder, weekId)
|
|
const result = await client.writeJson(path, planning)
|
|
if (result.ok) return { ok: true }
|
|
// 409 means the parent folder is missing: create it and retry once.
|
|
if (result.failure.kind !== 'conflict') return result
|
|
const folderResult = await ensurePlanningFolder(client, folder)
|
|
if (!folderResult.ok) return folderResult
|
|
return client.writeJson(path, planning)
|
|
}
|
|
|
|
function describeStorage() {
|
|
return {
|
|
kind: 'nextcloud',
|
|
label: 'Enregistré sur Nextcloud dans « ' + folder + ' »'
|
|
}
|
|
}
|
|
|
|
return { loadWeek, saveWeek, describeStorage }
|
|
}
|