Skip to content

Undo and Redo

Undo returns cards to their earlier state; Redo reapplies the change. Use this after a move or a successful editor change rather than manually reconstructing source rows.

Interactive example

Undo and redo a move

History keeps accepted card changes.

Try it: Move research, then choose Undo and Redo in the toolbar.

Loading example…

What to notice: Undo returns research to To do; Redo moves it back to In progress.

TypeScript source

Install the packages from Getting Started, then use this source in your app.

state-and-filtering.ts
import type { KanbanPlugin } from '@revolist/kanban';
import type { WorkCard } from './first-board';
export function showHighPriority(kanban: KanbanPlugin<WorkCard>) {
kanban.setFilter({ predicate: card => card.priority === 'high' });
}
export function searchResearch(kanban: KanbanPlugin<WorkCard>) {
kanban.setFilter({ query: 'research', fields: ['title'] });
}
export function clearFilters(kanban: KanbanPlugin<WorkCard>) { kanban.setFilter(); }
// An app-owned snapshot of serializable data, not a Kanban remote-store API.
export function captureBoard(kanban: KanbanPlugin<WorkCard>) {
return { cards: kanban.getCards().map(card => ({ ...card })), columns: [...kanban.getColumnOrder()], collapsed: [...kanban.getCollapsedColumnProps()], selected: [...kanban.getSelectedCardIds()] };
}
export async function restoreBoard(grid: HTMLRevoGridElement, kanban: KanbanPlugin<WorkCard>, saved: ReturnType<typeof captureBoard>) {
grid.source = saved.cards.map(card => ({ ...card }));
await new Promise<void>(resolve => requestAnimationFrame(() => requestAnimationFrame(() => resolve())));
kanban.setColumnOrder(saved.columns);
for (const prop of kanban.getColumnOrder()) kanban.setColumnCollapsed(prop, saved.collapsed.includes(prop));
kanban.setSelectedCardIds(saved.selected);
}
// Persist JSON.stringify(captureBoard(kanban)) in your application's storage.
// Restore only data validated by your application; the live example stays in memory.
Download state-and-filtering.ts

Try it: move a card, choose Undo, then Redo. Watch both its column and its position.

grid.kanbanToolbar = {
actions: ['undo', 'redo'],
search: false, workflowFilter: false, viewSwitcher: false,
};

Move the first card, then undo and redo it. This is the same fixture with only history actions enabled: actions: ['undo', 'redo'], search: false, workflowFilter: false, viewSwitcher: false.

Kanban coordinates with EventManagerPlugin and HistoryPlugin. Each successful move or editor CRUD action contributes normal stable row patches plus typed card changes to the shared gridedit stream. Replay-only card state is kept in separate keyed history metadata. With EventManager collection enabled, consecutive operations merge by card ID into one transaction and one history step while preserving each card’s earliest prior state and latest committed state. Undo/redo is replayed through Kanban rather than against projected lane rows, including source-length changes.

History is not cleared merely because filtering, sorting, or board projection refreshes. Replacing grid.source with an externally authored dataset clears Kanban history so an old move cannot overwrite newer host data.

A local undo is not a server rollback by itself. If your application owns writes, save replayed card changes through the same committed event flow. The optional managed adapter coordinates accepted-only history and backend conflict decisions for a complete dataset.

Continue with save board state, application-owned saving and events. See the Kanban API for exact types and signatures.