Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ How to use this file:

### Changed

- The note confirming the payslips added goes after five seconds: it
dissolves, then the room it took closes smoothly; not while the pointer
or the focus is on it.
- In the web app the page no longer lists the files: it says only how many
need a look, if any. The files are in a sheet of their own, opened from
that line or from "Files read" under the report: what needs a look
Expand Down
50 changes: 47 additions & 3 deletions web/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -321,9 +321,51 @@ function added(files) {
let text = t('web.added.none');
if (months.length === 1) text = t('web.added.one', months[0]);
if (months.length > 1) text = t('web.added.many', months.length, months.join(', '));
$('added').textContent = text;
$('added').classList.toggle('none', months.length === 0);
$('added').hidden = false;
const note = $('added');
note.textContent = text;
note.classList.toggle('none', months.length === 0);
note.classList.remove('fading', 'going');
note.style.height = '';
note.hidden = false;
fadeAdded();
}

// The confirmation goes after a few seconds, dissolving and then folding
// away so that the report rises smoothly under it; not while the pointer
// or the focus is on it, so that it can be read.
const ADDED_FOR = 5000;
let addedTimer = 0, addedTurn = 0;
function fadeAdded() {
clearTimeout(addedTimer);
// A note shown again ends the fading of the one before.
const turn = ++addedTurn;
addedTimer = setTimeout(() => {
const note = $('added');
if (note.hidden) return;
if (note.matches(':hover, :focus-within')) {
fadeAdded();
return;
}
if (calm()) {
note.hidden = true;
return;
}
// First it dissolves, then the room it took closes.
note.classList.add('fading');
note.addEventListener('transitionend', () => {
if (turn !== addedTurn) return;
note.style.height = `${note.offsetHeight}px`;
note.getBoundingClientRect();
note.classList.add('going');
note.style.height = '0px';
note.addEventListener('transitionend', () => {
if (turn !== addedTurn) return;
note.hidden = true;
note.classList.remove('fading', 'going');
note.style.height = '';
}, { once: true });
}, { once: true });
}, ADDED_FOR);
}

// progress shows how many files have been read, or hides the bar.
Expand All @@ -347,6 +389,8 @@ async function handle(fileList) {
// the progress and any password.
const adding = !$('result').hidden;
const before = state.files.length;
clearTimeout(addedTimer);
addedTurn++;
$('added').hidden = true;
if (adding) {
$('pick').hidden = false;
Expand Down
3 changes: 3 additions & 0 deletions web/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ h1 { font-size: clamp(30px, 6vw, 40px); line-height: 1.1; margin: 0 0 12px; lett
.added::before { content: "✓ "; color: var(--good); font-weight: 700; }
.added.none { background: var(--raised); color: var(--ink-2); }
.added.none::before { content: ""; }
.added.fading { opacity: 0; transition: opacity .6s ease; }
.added.going { overflow: hidden; margin-bottom: 0; padding-top: 0; padding-bottom: 0;
transition: height .25s ease, margin .25s ease, padding .25s ease; }
.misread { margin: 16px 0 0; text-align: center; }
.report-tabs { display: flex; gap: 4px; margin: 0 -16px; padding: 0 16px; overflow-x: auto; scrollbar-width: none; border-top: 1px solid var(--line); }
.report-tabs[hidden] { display: none; }
Expand Down
2 changes: 2 additions & 0 deletions web/test/e2e.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,8 @@ test('adds payslips to a report', async () => {
await frame.waitForFunction(() => document.querySelectorAll('.picker button').length === 3);
// The report opens on the latest month again.
assert.equal(await frame.$eval('.picker button[aria-pressed="true"]', (b) => b.textContent), 'Mar 26');
// The confirmation goes by itself after a few seconds.
await page.waitForSelector('#added', { state: 'hidden', timeout: 8000 });
assert.deepEqual(seen.errors, []);
onlyThisSite(seen);
await page.close();
Expand Down
Loading