feat(playlists): act on the selected rows from the toolbar, and undo either
While rows are selected the toolbar's second row is the band: the count, the last target as one click, Move to, Remove, Clear selection. Both write in one request and undo back to the places; a video the target held before stays there. Delete takes the selection when there is one. A failure puts the rows back ticked. A row's own move goes through the same write, so it undoes too, and the single-row move route and service function are gone. A playlist row drops its grip below a 24rem table: the row menu keeps the moves.
This commit is contained in:
@@ -10,9 +10,15 @@ import { useActiveScopes } from "./keymap";
|
||||
|
||||
afterEach(cleanup);
|
||||
|
||||
function Rows({ selection }: { selection?: NavSelection }) {
|
||||
function Rows({
|
||||
selection,
|
||||
onDelete,
|
||||
}: {
|
||||
selection?: NavSelection;
|
||||
onDelete?: (index: number) => void;
|
||||
}) {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
useListNav(ref, { enabled: true, selection });
|
||||
useListNav(ref, { enabled: true, selection, onDelete });
|
||||
return (
|
||||
<div ref={ref}>
|
||||
{[0, 1, 2].map((i) => (
|
||||
@@ -39,6 +45,7 @@ function press(key: string, init: KeyboardEventInit = {}): KeyboardEvent {
|
||||
const selection = (cleared = true) => ({
|
||||
toggle: vi.fn<(index: number) => void>(),
|
||||
clear: vi.fn(() => cleared),
|
||||
removeSelected: vi.fn(() => false),
|
||||
});
|
||||
|
||||
describe("useListNav · selecting", () => {
|
||||
@@ -108,6 +115,25 @@ describe("useListNav · selecting", () => {
|
||||
expect(idle.clear).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("has Delete go to the selection first, wherever the focus is", () => {
|
||||
const s = selection();
|
||||
s.removeSelected.mockReturnValue(true);
|
||||
const onDelete = vi.fn();
|
||||
render(<Rows selection={s} onDelete={onDelete} />);
|
||||
expect(press("Delete").defaultPrevented).toBe(true);
|
||||
expect(s.removeSelected).toHaveBeenCalledTimes(1);
|
||||
expect(onDelete).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("has Delete go on to the walked row when there is no selection", () => {
|
||||
const s = selection();
|
||||
const onDelete = vi.fn();
|
||||
render(<Rows selection={s} onDelete={onDelete} />);
|
||||
press("j");
|
||||
press("Delete");
|
||||
expect(onDelete).toHaveBeenCalledExactlyOnceWith(0);
|
||||
});
|
||||
|
||||
it("leaves both keys alone in a list that takes no selection", () => {
|
||||
render(<Rows />);
|
||||
press("j");
|
||||
|
||||
Reference in New Issue
Block a user