practice entry points: sidebar filter, practice draft, graph picker
- Sidebar: the three-way kind filter (Teaching/All/Practice, persisted
in localStorage) above the search; two new-session doors (Teaching →
/chat/new, Practice → /chat/new?mode=practice); practice rows carry
the dumbbell badge and 'Practicing…' busy meta.
- Draft: ?mode=practice swaps the copy (title, empty state, 'What do
you want to practice?') and startDraftSession posts kind:'practice'.
- Graph entry (home composer): teach|practice switch on the stats row's
left edge (StatsBar leadingSlot); practice mode shows the propositions
chip that opens the chain table as a picker (its floating bar becomes
'Practice these' — no delete fence); the picks seed the opening prompt
('Propositions from the map:…') while the title stays the typed text.
This commit is contained in:
@@ -117,3 +117,22 @@ describe("timeAgo", () => {
|
||||
assert.equal(timeAgo("2026-01-02T12:01:00.000Z", now), "just now");
|
||||
});
|
||||
});
|
||||
|
||||
describe("SessionRow practice badge (practice sessions, 2026-10-04)", () => {
|
||||
it("a practice row carries the dumbbell badge and the Practicing meta while busy", () => {
|
||||
const html = render(item({ kind: "practice", busy: true }));
|
||||
assert.match(html, /Practicing…/);
|
||||
assert.match(html, /aria-label="Practice session"/);
|
||||
});
|
||||
|
||||
it("a teaching row carries neither", () => {
|
||||
const html = render(item({}));
|
||||
assert.doesNotMatch(html, /Practice session/);
|
||||
assert.doesNotMatch(html, /Practicing…/);
|
||||
});
|
||||
|
||||
it("busy teaching rows still say the teacher is working", () => {
|
||||
const html = render(item({ busy: true }));
|
||||
assert.match(html, /Teacher is working…/);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user