Skip to content

v0.0.6 — Excel-parity wave (Pivots P1, drill-down, Sparklines, Goal Seek, dark theme, …)

Choose a tag to compare

@schnsrw schnsrw released this 23 May 15:37
· 170 commits to main since this release

What's new in v0.0.6 — the Excel-parity wave

Twenty-five commits, ~20 new user-facing features, and 20 extra e2e suites since v0.0.5. Highlights:

Analysis tools

  • Name Manager (Ctrl+F3) — list, create, rename, re-point, delete named ranges. Round-trips through xlsx defined-names.
  • Flash Fill (Ctrl+E) — heuristic pattern detection (identity, case, token-at-index, substring, prefix/suffix concat) fills the blanks below user examples.
  • Goal Seek — bisection + secant solver dialog (Set cell → Target value → By changing cell). Awaits Univer's worker-side recalc per probe; bails early on a constant function.

Pivots (P1 + drill-down)

  • Filter fields — dynamic value checklist driven by distinct values in the source column. Filtered records feed both buckets and the Grand Total.
  • Refresh PivotTables — re-runs every pivot from current source; tracks lastOutputExtent on the model so a shrunk pivot doesn't leave residual cells.
  • Drill-down (Ctrl+Shift+D) — examines the active selection, locates the containing pivot, pops the contributing source records in a scrollable modal.

Charts

  • Trendlines — ordinary-least-squares per series, rendered as a dashed ECharts markLine.
  • Date-axis detection — when every category cell parses as a date in 1900–2100, the axis flips to type: 'time' for auto-formatted tick labels.
  • Per-series colour overrides — Format Chart dialog row per series with a colour picker + Reset.

Sparklines (new)

  • In-cell mini-charts in three Excel-canonical types (line / column / win-loss).
  • Insert dialog (data range + target cell + type).
  • Persist through __casual_sheets_sparklines__ so they survive autosave, version-history, and xlsx round-trip.

View / display

  • Show Formulas (Ctrl+`) — non-destructive DOM overlay paints formula source on every formula cell. Works in light + dark.
  • Print Area — A1 field in Page Setup + File-menu "Set Print Area to selection" / "Clear".
  • Dark theme — title-bar sun/moon toggle, bridged to Univer's ThemeService so the canvas chrome flips too.
  • Status-bar customisation — right-click on the stats strip to toggle which appear; persists in localStorage.

Shell rewrites

  • Google-Docs-style title bar — logo + filename + classic menus merged into one chrome layer (one source of truth for --titlebar-row-pad so filename and File menu share a left edge).
  • Right-edge panel rail — always-visible icon column for Tables / Charts / Outline / Comments / History; panel mutex (ISidebarService subscription) so Comments and React panels can't co-exist.
  • Inline SVG icons — ~155 components lifted from sister doc-editor + Material Symbols. Sharp at every size, no font-load delay.
  • Brand mark swapped to match the sister doc-editor's shape language (folded-corner paper) in Excel green with a grid inside.

Co-edit hardening

  • Server-side view-only enforcement — Hocuspocus onAuthenticate flips connection.readOnly for view-role joiners. Closes the bypass where a crafted client could push mutations past the engine-layer gate.
  • Multi-range presence — peer cursors render every range in a Ctrl-click selection (extras drawn with thinner border, no duplicate name labels).
  • NamePill — in-room display-name edit affordance in the title bar; persists via the existing casual.collab.displayName slot.

Files / UX

  • Recent Files landing — new IndexedDB store (cap 10, 60-day TTL); surfaces on the blank Untitled workbook so first-visit / multi-file workflows have an entry point.
  • Paste Special dialog (Ctrl+Alt+V) — 6 Univer-native paste modes; co-edit + xlsx round-trip safe by construction.
  • Local version history — IndexedDB snapshot store (auto every ~10 min while dirty + manual "Save version…"); preview a snapshot, then Restore (auto-captures a "before restore" crumb for undo).
  • Per-mutation history panel — works in solo mode now (was previously co-edit-only via the Yjs op-log).
  • Quick-win shortcuts — Ctrl+Alt+L (re-apply filter), Ctrl+[ / Ctrl+] (precedent / dependent navigation).

Tests

357 Playwright e2e tests across 87 files (up from 337 / 79). Every feature above ships with its own spec.


Upgrading

docker pull schnsrw/casual-sheets:0.0.6
# or: docker pull schnsrw/casual-sheets:latest

No breaking changes to the API surface or room protocol. The IndexedDB version bumps from 2 → 3 (additive — adds recent-files); existing autosave + version-history data is preserved.


Hot patches on top of the initial v0.0.6 cut

v0.0.6 was re-tagged twice to bundle these fixes — no separate version row, same Docker tag:

  • Unified IndexedDB versioning — autosave, version-history, and recent-files were independently opening the shared casual-sheets DB at versions 1, 2, 3. Whichever module opened first set the live version; the others got VersionError and silently dropped reads (autosave banner stopped appearing, recent files vanished). All three now share VERSION=3 with an idempotent upgrade handler.
  • Collab auth handshake — the new server-side onAuthenticate made Hocuspocus require an auth submessage from every client. The provider only sends one when token is truthy; without it, joiners stayed pre-auth and awareness never propagated (you'd see only yourself in the avatar stack). Pass a placeholder token through the provider.
  • Compaction race — the bridge's lastCompactedAt was 0, so the first auto-compaction could fire on the first requestIdleCallback after the op threshold was crossed. Seeded to Date.now() so the first auto-compaction observes the full cooldown.
  • Autosave discard race — Discard called clearAutosave() fire-and-forget then hid the banner immediately; a fast reload re-read the un-cleared record and the banner returned. Now awaits the clear.
  • Dialog horizontal scroll.dialog was min(540px, 92vw) while .command-search declared min-width: 640px; the Tell Me dialog spawned a horizontal scrollbar on every open. Bumped dialog default to min(640px, 92vw), dropped command-search min-width, made .dialog__body y-only.

Full suite (lint + typecheck + 8 unit + 356 e2e + 1 skipped) green on the published tag.