30 lines
1.7 KiB
JavaScript
30 lines
1.7 KiB
JavaScript
function createTomorrowPlan({fetchJson,localDate,timeZone,createId}={}) {
|
|
let plan={revision:0,ids:[],capacity_minutes:null,estimates:{}};
|
|
const state=()=>({...plan,ids:[...plan.ids],estimates:{...plan.estimates}});
|
|
function adopt(value) {
|
|
if (!Number.isInteger(value?.revision)||!Array.isArray(value?.ids)) return false;
|
|
plan={revision:value.revision,ids:[...value.ids],capacity_minutes:value.capacity_minutes??null,
|
|
estimates:{...(value.estimates||{})},...(value.plan_date?{plan_date:value.plan_date,timezone:value.timezone||null}:{})};
|
|
return state();
|
|
}
|
|
function nextLocalDate() {
|
|
const [y,m,d]=localDate().split('-').map(Number);
|
|
return new Date(Date.UTC(y,m-1,d+1)).toISOString().slice(0,10);
|
|
}
|
|
async function load(){return adopt(await fetchJson('api/v1/tomorrow'));}
|
|
async function save(value) {
|
|
const body={base_revision:plan.revision,ids:[...(value.ids||[])],
|
|
capacity_minutes:value.capacity_minutes??null,estimates:{...(value.estimates||{})},
|
|
plan_date:nextLocalDate(),timezone:timeZone()};
|
|
return adopt(await fetchJson('api/v1/tomorrow',{method:'PUT',headers:{'Content-Type':'application/json'},body:JSON.stringify(body)}));
|
|
}
|
|
async function promote(today_revision) {
|
|
if (!plan.plan_date||plan.plan_date!==localDate()||!plan.ids.length) return false;
|
|
const promotion_id=createId?.()||globalThis.crypto?.randomUUID?.()||`${plan.plan_date}-${plan.revision}`;
|
|
return fetchJson('api/v1/tomorrow/promote',{method:'POST',headers:{'Content-Type':'application/json'},
|
|
body:JSON.stringify({promotion_id,tomorrow_revision:plan.revision,today_revision})});
|
|
}
|
|
return {adopt,load,save,promote,state,nextLocalDate};
|
|
}
|
|
if(typeof module!=='undefined'&&module.exports)module.exports=createTomorrowPlan;
|