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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ unreachable model within minutes, and the pipeline no longer imports the chat. N

### Changed

- **On a phone the toasts stack one high.** Below 48rem only the newest toast shows; an older one comes back
when the newest goes, unless its own time ran out first.
- **The warm-up waits for the chat to be used, and for the changes to pause.** Before the first open since start, a
run's end or a status change prepares nothing; after it, the warm-up starts once `leadgen.chat.suggestion-quiet-window`
(default 30 s) has passed without a further change, so triaging applications one by one costs one call from the
Expand Down
4 changes: 4 additions & 0 deletions docs/decisions/frontend-design-system.md
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,10 @@ One line at the edge of the screen after a write or a run, and the decisions tha
advert prose, which scrolls. The reveal's duration and easing are the first tokens in
`src/styles/motion.css`, off under `prefers-reduced-motion`; the lifetime and the cap
are constants beside the model, because the timer that reads them is TypeScript.
- **Below 48rem the pile is one toast high.** Full width above the bar, three in a row took a
third of a phone's height. The stylesheet shows the newest only; the older ones stay in the store
with their timers running and show when the newest goes. CSS rather than a smaller cap for
phones, because the cap is the store's and the store does not know the width.
- **The DOM-render screenshot never paints the fixed stack.** The toast stood in the DOM
with a measured rectangle while the capture showed nothing. The pictures in the spec
come from a pixel capture over CDP, taken past the reveal; a frame inside it reads as a
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {TestBed} from '@angular/core/testing';
import {provideRouter} from '@angular/router';
import {injectDispatch} from '@ngrx/signals/events';
import {cdp} from 'vitest/browser';
import {cdp, page} from 'vitest/browser';
import {shortlistEvents} from '@core/store/shortlist.events';
import {toastEvents} from '@core/toast/toast.events';
import {actionToast, toast} from '@core/toast/toast.model';
Expand Down Expand Up @@ -102,3 +102,48 @@ describe('ToastStack sizes (ISC-500)', () => {
}
});
});

/**
* Below 48rem the stack runs the full width above the bottom bar, and three toasts in a row took a
* third of a phone's height. There it shows the newest one only; the older ones stay in the store and
* come back as the newest goes.
*/
describe('ToastStack on a phone', () => {
let dispatch: ReturnType<typeof injectDispatch<typeof toastEvents>>;

beforeEach(() => {
TestBed.configureTestingModule({providers: [provideRouter([])]});
dispatch = TestBed.runInInjectionContext(() => injectDispatch(toastEvents));
});

afterEach(async () => {
await page.viewport(1280, 800);
});

function raiseThree(): HTMLElement[] {
const fixture = TestBed.createComponent(ToastStack);
fixture.detectChanges();
for (const title of ['First', 'Second', 'Third']) {
dispatch.raised(toast('info', 'toast.archived', {title}, '/shortlist/8'));
}
fixture.detectChanges();
return Array.from(fixture.nativeElement.querySelectorAll('.alert'));
}

const shown = (alerts: HTMLElement[]) => alerts.filter((alert) => alert.getClientRects().length > 0);

it('shows only the newest toast at 390px', async () => {
await page.viewport(390, 844);
const alerts = raiseThree();

expect(alerts).toHaveLength(3);
expect(shown(alerts)).toEqual([alerts[2]]);
expect(alerts[2]!.textContent).toContain('Third');
});

it('keeps the whole stack from 48rem up', async () => {
await page.viewport(1280, 800);

expect(shown(raiseThree())).toHaveLength(3);
});
});
7 changes: 7 additions & 0 deletions frontend/src/app/layout/toast-stack/toast-stack.css
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@
.alert {
width: 100%;
}

/* The newest toast only. Full width above the bar, three in a row took a third of a phone's
height. The older ones stay in the store, their timers running, and the next one shows
when the newest goes; each was announced when it arrived, so hiding it says nothing twice. */
.lg-toasts > :not(:last-child) {
display: none;
}
}

.alert {
Expand Down
Loading