Add 5-tier warning thresholds to staff rota footer
Replaces the 2-row (vs Booked / vs with Pickup) footer with a progressive 5-row breakdown: - Total Available (unchanged) - vs Booked — plain diff, room cleaning only - with Recurring Tasks — plain diff, adds recurring tasks - with Pickup — plain diff, adds pickup hours - with Adjustments — bold coloured final row with configurable thresholds New 5-tier icon system: red ⚠ / amber ⚠ / green ✓ / amber ✗ / red ✗, with defaults of 4h / 1h / 1h / 2h spare or short. Thresholds are editable in Settings. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
fee388db4c
commit
75ac7591d2
7 changed files with 256 additions and 20 deletions
|
|
@ -8,18 +8,24 @@ export async function configRoutes(app) {
|
|||
// ── GET /api/config — all settings at once ──────────────────────────────
|
||||
|
||||
app.get('/api/config', async (req) => {
|
||||
const [timeReqs, staffData, pickupData, generalTasks, lastReviewed, toleranceMins, workforceRota, workforceDepts, adjustments] =
|
||||
await Promise.all([
|
||||
getConfig('time_requirements', {}),
|
||||
getConfig('staff_data', []),
|
||||
getConfig('pickup_data', {}),
|
||||
getConfig('general_tasks', []),
|
||||
getConfig('last_reviewed', null),
|
||||
getConfig('tolerance_minutes', 30),
|
||||
getConfig('workforce_rota', null),
|
||||
getConfig('workforce_departments', []),
|
||||
getConfig('adjustments', []),
|
||||
])
|
||||
const [
|
||||
timeReqs, staffData, pickupData, generalTasks, lastReviewed,
|
||||
workforceRota, workforceDepts, adjustments,
|
||||
warnOverRed, warnOverAmber, warnUnderAmber, warnUnderRed,
|
||||
] = await Promise.all([
|
||||
getConfig('time_requirements', {}),
|
||||
getConfig('staff_data', []),
|
||||
getConfig('pickup_data', {}),
|
||||
getConfig('general_tasks', []),
|
||||
getConfig('last_reviewed', null),
|
||||
getConfig('workforce_rota', null),
|
||||
getConfig('workforce_departments', []),
|
||||
getConfig('adjustments', []),
|
||||
getConfig('warn_over_red_hrs', 4),
|
||||
getConfig('warn_over_amber_hrs', 1),
|
||||
getConfig('warn_under_amber_hrs', 1),
|
||||
getConfig('warn_under_red_hrs', 2),
|
||||
])
|
||||
|
||||
const today = new Date()
|
||||
const todayStr = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`
|
||||
|
|
@ -33,10 +39,13 @@ export async function configRoutes(app) {
|
|||
pickup_data: pickupData || {},
|
||||
general_tasks: generalTasks || [],
|
||||
last_reviewed: lastReviewed || yestStr,
|
||||
tolerance_minutes: toleranceMins != null ? toleranceMins : 30,
|
||||
workforce_rota: workforceRota || null,
|
||||
workforce_departments: workforceDepts || [],
|
||||
adjustments: adjustments || [],
|
||||
warn_over_red_hrs: warnOverRed != null ? warnOverRed : 4,
|
||||
warn_over_amber_hrs: warnOverAmber != null ? warnOverAmber : 1,
|
||||
warn_under_amber_hrs: warnUnderAmber != null ? warnUnderAmber : 1,
|
||||
warn_under_red_hrs: warnUnderRed != null ? warnUnderRed : 2,
|
||||
}
|
||||
})
|
||||
|
||||
|
|
@ -161,6 +170,20 @@ export async function configRoutes(app) {
|
|||
return { ok: true }
|
||||
})
|
||||
|
||||
// ── PUT /api/config/warning-thresholds ──────────────────────────────────
|
||||
|
||||
app.put('/api/config/warning-thresholds', { preHandler: requireCap('settings') }, async (req, reply) => {
|
||||
const { warn_over_red_hrs, warn_over_amber_hrs, warn_under_amber_hrs, warn_under_red_hrs } = req.body || {}
|
||||
const parse = (v, def) => { const n = parseFloat(v); return isNaN(n) || n < 0 ? def : n }
|
||||
await Promise.all([
|
||||
setConfig('warn_over_red_hrs', parse(warn_over_red_hrs, 4)),
|
||||
setConfig('warn_over_amber_hrs', parse(warn_over_amber_hrs, 1)),
|
||||
setConfig('warn_under_amber_hrs', parse(warn_under_amber_hrs, 1)),
|
||||
setConfig('warn_under_red_hrs', parse(warn_under_red_hrs, 2)),
|
||||
])
|
||||
return { ok: true }
|
||||
})
|
||||
|
||||
// ── GET /api/categories — settings cap required ──────────────────────────
|
||||
|
||||
app.get('/api/categories', { preHandler: requireCap('settings') }, async (req, reply) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue