Skip to content

10 Editing and Data

zhuoguangming edited this page Oct 5, 2026 · 1 revision

Editing and Data

Undo / redo

All data changes go through the command layer, so they're all undoable:

  • Ctrl+Z (macOS Cmd+Z) to undo
  • Ctrl+Shift+Z / Cmd+Shift+Z to redo

A few design details:

  • One drag = one undo (no half state where "the date came back but the duration stayed")
  • A bulk action leaves only one record: bulk assignment, bulk deletion of multiple tasks—a single Ctrl+Z restores it all
  • One Enter that creates a sibling task = two records (rename + create)—they're two things
  • In the menu bar "Edit" you can see "Undo: "

When focus is inside a text field, the undo shortcut doesn't take over (otherwise it would fight the text box's own undo).

Shortcut reference

Shortcut Action
Ctrl/Cmd + Z / Shift+Z Undo / redo
Ctrl/Cmd + click Toggle that row's selection
Shift + click Select the range from the anchor to that row
Shift + ↑ / ↓ Extend the selection with the keyboard
Esc Cancel multi-selection / cancel cell editing
Double-click a cell Enter inline editing
Enter (while editing a task name) Commit the rename + create a sibling task
Enter / blur (other cells) Commit
Double-click the header divider Reset that column's width
Ctrl/Cmd + wheel Continuous timeline zoom
Ctrl/Cmd + + / - / 0 Zoom in / out / reset

Where the data lives

All inside your browser: projects are stored in IndexedDB, with debounced auto-save—no manual save after a change, and no loss on refresh.

Therefore:

  • No server, no account—no login required, and nothing is uploaded
  • A different browser / device / cleared browser data → you won't see the same project
  • To move data away, see "Import/export" below

The data structure has a version number and is migrated version by version on upgrade—old saves can always be opened.

Importing OmniPlan files

The repo ships with a conversion script that turns real OmniPlan documents (.oplx) into Planit project JSON:

python3 scripts/importOmniPlan.py path/to/xxx.oplx -o out.json

Import is one-way and lossy: OmniPlan's resource leveling results (leveled-start) are not brought over, and Planit recomputes with its own CPM + leveling—the differences in dates between the two sides are exactly what to watch when testing the engine against real data.

Interface language

Supports 简体中文 / English / 日本語, switched in the top bar (or the "More" menu on narrow screens), taking effect immediately. All copy, including undo hints, is fully translated.

Known limitations

The following items are all confirmed by testing and intentionally kept for now, not bugs:

1. Re-render jank when changing the calendar on large projects

Solving itself is no longer the bottleneck (the engine runs on a Web Worker; for 10k tasks, main-thread blocking dropped from 797ms to ~40ms). The remaining jank is in re-rendering, and only occurs when changing working days (10,000 tasks, production build, measured at roughly 300ms per frame).

The cause: changing the calendar rebuilds the entire timeline and the non-working-day shading—a long chain of 1000 nodes stretches the timeline to about 4200 days, and the shading alone produces 1200 DOM nodes.

⚠️ Measuring this requires a production build. React dev build overhead at the ten-thousand scale can take up more than half the render time (the same operation: dev 746ms vs production 17ms); using dev numbers leads to completely wrong conclusions.

2. Tasks scheduled before the project start are covered by the left columns

The timeline origin is fixed at the project start date. If a task is scheduled before the origin (manually pinned, or pushed out by a negative lag), its bar is drawn to the left of the origin (with a negative left) and gets covered by the pinned left columns.

Example: project start 2026-03-02, a task manually pinned to finish 2026-03-03 with a 3-day duration, back-computed start day is 2026-02-27—3 calendar days earlier than the origin.

3. Column widths don't support keyboard adjustment

Outline column widths can only be dragged with a mouse / touch on the header divider (double-click to reset). The handle has no keyboard entry point. Width preferences are stored in the browser's localStorage, and don't go into the project file or the undo stack.

4. Three earned-value columns are disabled

ACWP / CV / EAC are disabled as whole columns because they lack a data source of "actual-cost entry" (see Baselines and Earned Value).

Troubleshooting

  • The interface looks wrong: refresh once first; hot updates during development can occasionally scramble module state.
  • Solving is slow: check whether the status bar shows "Computing schedule…". Very large projects (ten-thousand-task scale) take a moment on the first solve, then it's incremental recomputation.
  • Want to give feedback: https://github.com/zgm4z/planit/issues

Back to Overview.

Clone this wiki locally