What it solves
The leave tracker is a spreadsheet where the status is the cell’s fill colour. Not a word in the cell — the colour is the data. That is perfectly readable to a human scrolling the sheet, and completely invisible to everything else.
The consequence is sharper than it first sounds: a CSV export of that spreadsheet comes out blank. There is no text to export. So the data cannot be queried, summarised, joined to teams, or put in front of anyone who doesn’t have the file open. Every question — who is out the week of the 14th, is this team thin enough to worry about — gets answered by eye, by one person, again each time someone asks.
This reads the fill colours directly out of the .xlsx (stdlib zipfile + xml.etree, no
dependencies) and turns them into real records. Once leave is data rather than formatting, the month
calendar, the per-person picker and the team-risk heatmap with its live coverage threshold are just
views over it.
The spreadsheet on the left is not missing data — it is storing it as formatting, which is why the export is empty. Parsing the fills turns leave into records, and coverage questions become a view rather than a squint.
What it does
Makes a colour-coded leave-tracker spreadsheet legible and answerable:
- a month calendar of who is out,
- a person multi-select to build a calendar for just the people you care about,
- a team-risk heatmap with a live percentage threshold, so you can see which teams thin out and when,
- PNG export that matches the current theme,
- an Add person form that opens a prefilled PR creating
leave/overrides/<slug>.json(one file can hold several people, so one PR covers a batch), with an in-app preview before you file it.
Where the data comes from
The Leave Tracker composite action parses the committed .xlsx — reading cell fill colours, not
text — into leaves_<slug>.{csv,json} plus a leave_coverage_<slug>.json rollup, and publishes them
to the leave-tracker/report branch. The SPA reads leave_manifest.json at runtime and falls back
to the bundled snapshot in public/data/.
Because the branch name contains a slash, the raw URL needs the /refs/heads/ form.
The action needs no token and no network.
Run it locally
cd leave-dashboard
npm install
npm run dev
# Regenerate from the spreadsheet (stdlib-only, offline):
python leave/generate_leave_tracker.py \
--xlsx-path "leave/source/DSE Leave Tracker - 26.4.xlsx" --out-dir reports
Related
- The generating Action:
NASA-IMPACT/veda-github-actions/leave@v1 - Colour map, overrides and the two automatic update paths:
docs/LEAVE_TRACKER.md