You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-**Note rendering partial.** Drag, resize, head/body editors, link icon exist. Missing: Teleport overlay during drag, drop zones, arrow link zones, read-only opacity states, scroll handling.
86
-
-**Page state screens done.**`PageStateScreens.vue` switcher + 8 components created and wired. Some states (`page-deleted`, `group-deleted`, `invited`, `rejected`) require richer API error codes to be fully distinguishable.
87
-
-**Context menu missing.** No `TableContextMenu` (right-click on canvas).
80
+
-**`docs/SPATIAL_PARITY_CHECKLIST.md` missing.** Phase 1 exit criterion requires this file; it was never created. Phase 6 cannot be declared done without it.
81
+
-**Left sidebar panels exist but are data-stubbed.**`PageEditorView.vue` passes `recentPageIds`, `favoritePageIds`, `selectedPageIds` as empty `ref<string[]>([])` to `RecentPagesCard`, `FavoritePagesCard`, `SelectedPagesCard`. Panels render shells with no data.
82
+
-**Right sidebar properties panels exist but lack depth.**`NotePropertiesCard.vue`, `ArrowPropertiesCard.vue`, `PagePropertiesCard.vue` are wired and visible, but many legacy properties (wrap, anchor, z-index, createdAt, editedAt, movedAt, etc.) are not exposed.
83
+
-**Toolbar is inline markup, not a reusable component.**`PageLayout.vue` contains the header shell directly; there is no `MainToolbar.vue` component. Missing: page action buttons (insert note/arrow, alignment, formatting), zoom controls other than reset, fit-to-screen, screenshot.
84
+
-**Arrow labels are raw `<input>` stubs, not Tiptap on `Y.XmlFragment`.**`DisplayArrow.vue` renders a plain `<input>` that deletes and re-inserts the entire `Y.XmlFragment` on blur. Legacy parity requires collaborative rich-text label editing.
85
+
-**Arrow geometry hardcodes note height at `80px`.**`DisplayArrow.vue` uses `const h1 = 80; const h2 = 80;` for endpoint calculations. Notes with variable heights (containers, expanded text) will produce misaligned arrows.
86
+
-**Note drag uses `Teleport` overlay but position tracking is incomplete.**`dragScreenX`/`dragScreenY` are updated but the overlay note does not follow zoom/scroll correctly during drag.
87
+
-**Page state screens exist but 4 states are indistinguishable.**`page-deleted`, `group-deleted`, `invited`, `rejected` all map to the same generic error UI because the API does not return distinct error codes.
88
+
-**Context menu exists for canvas but not for individual notes.**`CanvasContextMenu.vue` (right-click on empty canvas) is implemented. No per-note context menu exists.
| Select all (`Ctrl+A`) |**Done**|`onKeyDown` in `SpatialPageView.vue`|
22
-
| Active element / active region tracking |**Partial**|`useSpatialSelection` has `activeId` but no active-region concept|
22
+
| Active element / active region tracking |**Partial**|`useSpatialSelection` has `activeId`and `activeRegionId` ref but no real active-region UI or keyboard navigation|
23
23
24
24
### 2. Containers
25
25
| Item | Status | Notes |
26
26
|------|--------|-------|
27
27
| Note can contain child notes |**Done**|`container.enabled` and `container.children` wired in Yjs |
28
28
| Spatial container (free child positioning) |**Done**| Children rendered with world offset inside parent |
29
-
| Horizontal container (children in a row) |**Not started**|No horizontal layout logic|
29
+
| Horizontal container (children in a row) |**Done**|`container.horizontal` flag + `flex-row` class in `DisplayNote.vue`|
30
30
| Drag child out to detach |**Done**|`onNoteDragEnd` + `moveNoteOutOfContainer`|
31
31
| Drag note into container to attach |**Done**| Overlap-area heuristic in `SpatialPageView.vue`|
32
32
@@ -51,11 +51,11 @@ Achieve parity with the legacy `/pages/:pageId` immersive spatial canvas experie
51
51
| Item | Status | Notes |
52
52
|------|--------|-------|
53
53
| Fullscreen `PageEditorView.vue` shell |**Done**|`PageLayout.vue` replaces `DefaultLayout.vue` for `/pages/:pageId` via route meta |
54
-
|`MainToolbar` (shadcn) |**Done**|Header with logo, breadcrumb path, global nav, sidebar toggles |
55
-
|`LeftSidebar` (shadcn) — Recent, Favorites, Selected, Current path |**Done**| Resizable collapsible sidebar with path + collab status; Recent/Favorites/Selected sections implemented|
|`TableContextMenu` (shadcn) — right-click on canvas |**Done**|Canvas context menu with create note, paste, copy, cut, delete actions|
58
-
|`LoadingOverlay` during page bootstrap |**Partial**|Inline loading text in cards only; state screens handle loading/error|
54
+
|`MainToolbar` (shadcn) |**Partial**|`PageLayout.vue` inline header has logo, breadcrumb, global nav, sidebar toggles. No standalone `MainToolbar.vue`. Missing: page action buttons, insert dialogs, zoom other than reset, fit-to-screen|
55
+
|`LeftSidebar` (shadcn) — Recent, Favorites, Selected, Current path |**Partial**| Resizable collapsible sidebar shell exists. `CurrentPath` and `CollabStatus` wired. `RecentPagesCard`, `FavoritePagesCard`, `SelectedPagesCard` exist but receive empty stub arrays (`ref<string[]>([])`) — no actual data|
56
+
|`RightSidebar` (shadcn) — Note/Page/Arrow properties |**Partial**|`NotePropertiesCard`, `ArrowPropertiesCard`, `PagePropertiesCard` are wired and visible. Many legacy fields (wrap, anchor, z-index, timestamps) not exposed. Snapshots, management, backlinks exist|
57
+
|`TableContextMenu` (shadcn) — right-click on canvas |**Partial**|`CanvasContextMenu.vue` exists for canvas background. No per-note context menu|
58
+
|`LoadingOverlay` during page bootstrap |**Partial**|`PageStateScreens.vue` handles loading/error. No dedicated `LoadingOverlay` component over the canvas|
59
59
| Global CSS for spatial routes (`user-select: none`, `overflow: hidden`, `touch-action: none`) |**Done**|`PageLayout.vue` applies `select-none overflow-hidden` on the shell |
60
60
| Remove `PageEditorTiptapCard.vue` from page route |**Done**| File deleted; no longer imported or rendered |
61
61
| Dedicated fullscreen state screens (8 total) |**Done**|`PageStateScreens.vue` switcher + 8 components in `features/pages/screens/`. Detectable states: `loading`, `error`, `page-nonexistent`, `unauthorized`, `password`. `page-deleted`, `group-deleted`, `invited`, `rejected` require richer API error codes to distinguish. |
@@ -67,13 +67,13 @@ Achieve parity with the legacy `/pages/:pageId` immersive spatial canvas experie
67
67
| Selection ring |**Partial**|`ring-2 ring-primary` exists, but not legacy blue `#2196f3`|
|`Teleport` to global overlay during drag/resize |**Done**| Teleport overlay during drag to avoid z-index clipping |
70
-
|`NoteDropZones`|**Done**|Visual feedback when dragging over container|
71
-
|`NoteArrowHandles` — 4 directional arrow handles |**Partial**| 4 small dots exist, but not full arrow-creation flow |
72
-
|`ArrowLinkZones`|**Done**| Connection zones at arrow endpoints for reconnection|
70
+
|`NoteDropZones`|**Partial**|`isDropTarget` prop + `ring-accent`feedback exists. No dedicated `NoteDropZones` component|
71
+
|`NoteArrowHandles` — 4 directional arrow handles |**Partial**| 4 small dots exist and emit `arrowDragStart`. Drag-to-create-arrow flow is wired in `SpatialPageView.vue`|
72
+
|`ArrowLinkZones`|**Partial**| Connection zones (SVG circles) at endpoints exist. "Link zones" proper (hover-to-preview-link) not implemented|
73
73
|`NoteLinkIcon` (external link indicator) |**Done**|`ExternalLink` icon shown in header when `link.value` set |
74
74
|`NoteResizeHandles` — 8 handles |**Done**| NW, N, NE, E, SE, S, SW, W with correct cursors |
75
-
| Scrollbar handling in `NoteContent`|**Done**|`overscroll-behavior: contain` added to prevent pull-to-refresh|
| Arrow label (editable `Y.XmlFragment`) |**Done**|Editable label at arrow midpoint using Y.XmlFragment |
86
+
| Arrow label (editable `Y.XmlFragment`) |**Stub**|Plain `<input>` at midpoint. On blur, deletes entire `Y.XmlFragment` and inserts a single `Y.XmlText`. Not Tiptap. Not collaborative rich-text|
| Drag-to-reconnect |**Done**| Connection zones at arrow endpoints for reconnection|
89
-
| Color matching note color logic |**Done**|Arrow color mapped via same 10-color map as notes|
88
+
| Drag-to-reconnect |**Done**| Connection zones + `onReconnectPointerMove/Up` in `SpatialPageView.vue` wired|
89
+
| Color matching note color logic |**Partial**|Same hardcoded 10-color map used, but `inherit` logic may not cascade correctly for arrows|
90
90
91
91
### 9. Find and replace
92
92
| Item | Status | Notes |
93
93
|------|--------|-------|
94
-
| Search across note head/body |**Done**|`FindReplaceDialog.vue`with search UI|
94
+
| Search across note head/body |**Partial**|`FindReplaceDialog.vue`searches `Y.XmlFragment.toString()`. No rich-text-aware search (e.g., ignoring formatting marks)|
95
95
| Replace text |**Done**| Replace current and replace all implemented |
96
96
97
97
### 10. Visual polish
@@ -107,18 +107,21 @@ Achieve parity with the legacy `/pages/:pageId` immersive spatial canvas experie
107
107
108
108
## Verification
109
109
110
-
-[ ] Each deliverable has a test (unit, component, or integration).
111
-
-[ ] Phase 1 checklist is >80% marked done.
110
+
-[ ] Each deliverable has a test (unit, component, or integration). (Missing: `DisplayNote.vue`, `DisplayArrow.vue`, `SpatialPageView.vue`, sidebar/toolbar integration tests.)
111
+
-[ ] Phase 1 checklist is >80% marked done. (Blocked: `docs/SPATIAL_PARITY_CHECKLIST.md` does not exist.)
112
112
113
113
---
114
114
115
115
## Exit criteria
116
116
117
+
-[ ]`docs/SPATIAL_PARITY_CHECKLIST.md` exists and is reviewed for completeness.
117
118
-[ ] Phase 1 checklist ≥ 80% complete.
118
119
-[ ] No "P1" checklist item remains open.
119
120
-[ ]`PageEditorView.vue` renders as a full-screen immersive shell (no scrolling card page).
120
-
-[ ] All 8 dedicated page-state screens exist and are reachable (error, nonexistent, deleted, group-deleted, invited, rejected, unauthorized, password).
-[ ]`DisplayArrow.vue` supports curve + line bodies, arrow heads, labels, hitboxes, and drag-to-reconnect.
123
-
-[ ]`MainToolbar`, `LeftSidebar`, `RightSidebar`, and `TableContextMenu` are implemented with shadcn and visible on `/pages/:pageId`.
121
+
-[ ] All 8 dedicated page-state screens exist and are reachable. (`page-deleted`/`group-deleted`/`invited`/`rejected` are indistinguishable without richer API error codes.)
122
+
-[ ]`DisplayNote.vue` matches legacy note visuals: colors, borders, selection ring (`#2196f3` not `ring-primary`), drag opacity, Teleport overlay, drop zones, arrow handles, link icon, 8 resize handles.
123
+
-[ ]`DisplayArrow.vue` supports curve + line bodies, arrow heads, labels (**Tiptap on `Y.XmlFragment`**, not raw `<input>`), hitboxes, and drag-to-reconnect.
124
+
-[ ]`MainToolbar`, `LeftSidebar`, `RightSidebar`, and `TableContextMenu` are implemented as standalone shadcn components and visible on `/pages/:pageId`.
125
+
-[ ] Sidebar panels (`RecentPages`, `FavoritePages`, `SelectedPages`) display real data from API.
126
+
-[ ] Arrow geometry reads actual note heights instead of hardcoding `80px`.
124
127
-[ ] Manual QA session with 3+ users finds no blocking usability issues.
0 commit comments