mirror of
https://github.com/nfonteyne/octane-website.git
synced 2026-09-03 23:24:48 +02:00
update: 3 -> 4 weeks in calendar
This commit is contained in:
parent
4e2983dddd
commit
bb12667a7c
6 changed files with 13 additions and 13 deletions
|
|
@ -15,7 +15,7 @@ async function loadPeople() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadSlots() {
|
async function loadSlots() {
|
||||||
state.slots = await api.get('/api/calendar/slots?weeks=3');
|
state.slots = await api.get('/api/calendar/slots?weeks=4');
|
||||||
renderCalendar();
|
renderCalendar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@ const DEFAULT_SLOT_CONFIG = {
|
||||||
weekday: { startHour: 18, startMinute: 30, endHour: 21, endMinute: 0 },
|
weekday: { startHour: 18, startMinute: 30, endHour: 21, endMinute: 0 },
|
||||||
weekend: { startHour: 15, startMinute: 0, endHour: 19, endMinute: 0 },
|
weekend: { startHour: 15, startMinute: 0, endHour: 19, endMinute: 0 },
|
||||||
};
|
};
|
||||||
const MAX_WEEKS = 3;
|
const MAX_WEEKS = 4;
|
||||||
|
|
||||||
// One slot per day for the next `weeks` weeks (capped at 3, same as the rest
|
// One slot per day for the next `weeks` weeks (capped at 4, same as the rest
|
||||||
// of the calendar feature), starting from today's Paris-local calendar date
|
// of the calendar feature), starting from today's Paris-local calendar date
|
||||||
// — not the server's own timezone, which may not be Europe/Paris.
|
// — not the server's own timezone, which may not be Europe/Paris.
|
||||||
function generateSlots(weeks = MAX_WEEKS, slotConfig = DEFAULT_SLOT_CONFIG) {
|
function generateSlots(weeks = MAX_WEEKS, slotConfig = DEFAULT_SLOT_CONFIG) {
|
||||||
|
|
|
||||||
|
|
@ -84,8 +84,8 @@ async function ingestSlots(slots) {
|
||||||
return summary;
|
return summary;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getSlots({ minPeople = 0, personIds = null, weeks = 3 } = {}) {
|
async function getSlots({ minPeople = 0, personIds = null, weeks = 4 } = {}) {
|
||||||
const cappedWeeks = Math.min(weeks || 3, 3);
|
const cappedWeeks = Math.min(weeks || 4, 4);
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const end = new Date(now);
|
const end = new Date(now);
|
||||||
end.setDate(end.getDate() + cappedWeeks * 7);
|
end.setDate(end.getDate() + cappedWeeks * 7);
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ router.get(
|
||||||
// ingested slot (heat-colored by availability ratio on the frontend),
|
// ingested slot (heat-colored by availability ratio on the frontend),
|
||||||
// not just slots where at least one person happens to be free.
|
// not just slots where at least one person happens to be free.
|
||||||
const minPeople = req.query.min_people !== undefined ? parseInt(req.query.min_people, 10) : 0;
|
const minPeople = req.query.min_people !== undefined ? parseInt(req.query.min_people, 10) : 0;
|
||||||
const weeks = req.query.weeks !== undefined ? parseInt(req.query.weeks, 10) : 3;
|
const weeks = req.query.weeks !== undefined ? parseInt(req.query.weeks, 10) : 4;
|
||||||
const personIds = req.query.person_ids
|
const personIds = req.query.person_ids
|
||||||
? req.query.person_ids.split(',').map(Number).filter((n) => !Number.isNaN(n))
|
? req.query.person_ids.split(',').map(Number).filter((n) => !Number.isNaN(n))
|
||||||
: null;
|
: null;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ const calendarRepo = require('../repositories/calendarRepo');
|
||||||
const { generateSlots, isBusyDuring, widenWindow } = require('../lib/calendarAvailability');
|
const { generateSlots, isBusyDuring, widenWindow } = require('../lib/calendarAvailability');
|
||||||
const { parisWallClockToUTC } = require('../lib/calendarDates');
|
const { parisWallClockToUTC } = require('../lib/calendarDates');
|
||||||
|
|
||||||
const RANGE_DAYS = 22; // slightly more than the 3 weeks generateSlots() covers
|
const RANGE_DAYS = 29; // slightly more than the 4 weeks generateSlots() covers
|
||||||
const FETCH_TIMEOUT_MS = 15000;
|
const FETCH_TIMEOUT_MS = 15000;
|
||||||
|
|
||||||
// Fetches one ICS feed and parses it into node-ical's raw component map.
|
// Fetches one ICS feed and parses it into node-ical's raw component map.
|
||||||
|
|
@ -84,7 +84,7 @@ function dateOnlyToParisSpan(dateOnly) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetches every registered feed, derives per-person busy/free for each of the
|
// Fetches every registered feed, derives per-person busy/free for each of the
|
||||||
// next 3 weeks' slots (using the admin-configured rehearsal hours, falling
|
// next 4 weeks' slots (using the admin-configured rehearsal hours, falling
|
||||||
// back to calendarAvailability's defaults if none are set), and ingests the
|
// back to calendarAvailability's defaults if none are set), and ingests the
|
||||||
// result via calendarRepo.ingestSlots — the same sink the old n8n-webhook flow
|
// result via calendarRepo.ingestSlots — the same sink the old n8n-webhook flow
|
||||||
// used to feed. A feed that fails to fetch is logged by id only (never its
|
// used to feed. A feed that fails to fetch is logged by id only (never its
|
||||||
|
|
@ -113,7 +113,7 @@ async function syncAvailability() {
|
||||||
intervalsByUser.set(feed.user_id, existing.concat(result.value));
|
intervalsByUser.set(feed.user_id, existing.concat(result.value));
|
||||||
});
|
});
|
||||||
|
|
||||||
const slots = generateSlots(3, slotConfig);
|
const slots = generateSlots(4, slotConfig);
|
||||||
const slotPayload = slots.map((slot) => {
|
const slotPayload = slots.map((slot) => {
|
||||||
// The margin only widens the *check* window (to account for travel time
|
// The margin only widens the *check* window (to account for travel time
|
||||||
// between back-to-back calendar events) — the slot itself, as stored and
|
// between back-to-back calendar events) — the slot itself, as stored and
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,14 @@ const { test } = require('node:test');
|
||||||
const assert = require('node:assert/strict');
|
const assert = require('node:assert/strict');
|
||||||
const { generateSlots, isBusyDuring, widenWindow } = require('../src/lib/calendarAvailability');
|
const { generateSlots, isBusyDuring, widenWindow } = require('../src/lib/calendarAvailability');
|
||||||
|
|
||||||
test('generateSlots: default 3 weeks produces one slot per day for 21 days', () => {
|
test('generateSlots: default 4 weeks produces one slot per day for 28 days', () => {
|
||||||
const slots = generateSlots();
|
const slots = generateSlots();
|
||||||
assert.equal(slots.length, 21);
|
assert.equal(slots.length, 28);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('generateSlots: caps weeks at 3 even if a larger value is requested', () => {
|
test('generateSlots: caps weeks at 4 even if a larger value is requested', () => {
|
||||||
const slots = generateSlots(10);
|
const slots = generateSlots(10);
|
||||||
assert.equal(slots.length, 21);
|
assert.equal(slots.length, 28);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('generateSlots: every slot has upper strictly after lower', () => {
|
test('generateSlots: every slot has upper strictly after lower', () => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue