84 lines
2.5 KiB
JavaScript
84 lines
2.5 KiB
JavaScript
function createAgendaReplan({ now = () => new Date(), update }) {
|
|
let items = [];
|
|
let index = 0;
|
|
let pending = false;
|
|
let active = false;
|
|
|
|
const dayKey = date => [
|
|
date.getFullYear(),
|
|
String(date.getMonth() + 1).padStart(2, '0'),
|
|
String(date.getDate()).padStart(2, '0'),
|
|
].join('-');
|
|
const dueDay = value => {
|
|
const match = String(value || '').match(/^(\d{4}-\d{2}-\d{2})(?:$|T)/);
|
|
return match ? match[1] : '';
|
|
};
|
|
const current = () => active ? items[index] || null : null;
|
|
const snapshot = () => ({
|
|
active,
|
|
index,
|
|
total: items.length,
|
|
current: current()?.key || null,
|
|
pending,
|
|
});
|
|
const advance = () => {
|
|
index += 1;
|
|
if (index >= items.length) active = false;
|
|
return { ok:true, done:!active };
|
|
};
|
|
const change = async dueDate => {
|
|
const item = current();
|
|
if (!item) return { ok:false, error:'No overdue deadline selected.' };
|
|
if (pending) return { ok:false, error:'Deadline update already in progress.' };
|
|
pending = true;
|
|
try {
|
|
await update(item, dueDate);
|
|
return advance();
|
|
} catch (error) {
|
|
return { ok:false, error:error?.message || 'Deadline could not be updated.' };
|
|
} finally {
|
|
pending = false;
|
|
}
|
|
};
|
|
|
|
return {
|
|
start(overdue) {
|
|
items = (overdue || []).slice().sort((left, right) =>
|
|
dueDay(left.due_date).localeCompare(dueDay(right.due_date)) ||
|
|
String(left.repository || '').localeCompare(String(right.repository || '')) ||
|
|
Number(left.number || 0) - Number(right.number || 0)
|
|
);
|
|
index = 0;
|
|
pending = false;
|
|
active = items.length > 0;
|
|
return snapshot();
|
|
},
|
|
snapshot,
|
|
current,
|
|
keep() {
|
|
if (pending) return Promise.resolve({ ok:false, error:'Deadline update already in progress.' });
|
|
if (!current()) return Promise.resolve({ ok:false, error:'No overdue deadline selected.' });
|
|
return Promise.resolve(advance());
|
|
},
|
|
tomorrow() {
|
|
const date = new Date(now());
|
|
date.setDate(date.getDate() + 1);
|
|
return change(dayKey(date) + 'T23:59:59Z');
|
|
},
|
|
choose(value) {
|
|
const chosen = String(value || '');
|
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(chosen) || chosen <= dayKey(now())) {
|
|
return Promise.resolve({ ok:false, error:'Choose a future date.' });
|
|
}
|
|
return change(chosen + 'T23:59:59Z');
|
|
},
|
|
cancel() {
|
|
active = false;
|
|
pending = false;
|
|
return snapshot();
|
|
},
|
|
};
|
|
}
|
|
|
|
if (typeof module !== 'undefined' && module.exports) module.exports = createAgendaReplan;
|