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
fix(web): fix note property mutations in PageEditorView
Vue 3's automatic ref unwrapping in reactive proxies broke mutations
on nested refs inside noteModel objects passed to the properties panel.
Changes:
- Use shallowRef for selectedNoteModel/selectedArrowModel to prevent
Vue from auto-unwrapping nested Yjs-backed refs (colorValue, etc.)
- Expose writeable refs (colorValue, widthExpanded, posX, anchorX, etc.)
from useNoteModel so consumers can mutate Yjs data directly
- Make yjs-reactivity.ts two-way (watch + flush: sync) so Vue ref
assignments write back to Yjs maps
- Fix NotePropertiesCard color computed to use colorValue (string) instead
of color (computed object) for ColorPalette :model-value
- Extract all inline @update:* handlers in PageEditorView.vue into explicit
handler functions to avoid Vue compiler quirks
Fixes color, width, height, pos, anchor, collapsible, and container
property changes in the right sidebar. Includes regression tests.
function handleSelectNote(id:string|null, model:any) {
89
+
selectedNoteId.value=id??null;
90
+
selectedNoteModel.value=model??null;
91
+
}
92
+
93
+
function handleSelectArrow(id:string|null, model:any) {
94
+
selectedArrowId.value=id??null;
95
+
selectedArrowModel.value=model??null;
96
+
}
97
+
98
+
// Note property update handlers
99
+
function onUpdateNoteLink(v:string) { if (selectedNoteModel.value) selectedNoteModel.value.link.value=v; }
100
+
function onUpdateNoteHeadEnabled(v:boolean) { if (selectedNoteModel.value) selectedNoteModel.value.head.enabled.value=v; }
101
+
function onUpdateNoteBodyEnabled(v:boolean) { if (selectedNoteModel.value) selectedNoteModel.value.body.enabled.value=v; }
102
+
function onUpdateNoteHeadWrap(v:boolean) { if (selectedNoteModel.value) selectedNoteModel.value.head.wrap.value=v; }
103
+
function onUpdateNoteBodyWrap(v:boolean) { if (selectedNoteModel.value) selectedNoteModel.value.body.wrap.value=v; }
104
+
function onUpdateNotePosX(v:number) { if (selectedNoteModel.value) selectedNoteModel.value.posX.value=v; }
105
+
function onUpdateNotePosY(v:number) { if (selectedNoteModel.value) selectedNoteModel.value.posY.value=v; }
106
+
function onUpdateNoteAnchorX(v:number) { if (selectedNoteModel.value) selectedNoteModel.value.anchorX.value=v; }
107
+
function onUpdateNoteAnchorY(v:number) { if (selectedNoteModel.value) selectedNoteModel.value.anchorY.value=v; }
108
+
function onUpdateNoteWidth(v:string) { if (selectedNoteModel.value) selectedNoteModel.value.widthExpanded.value=v; }
109
+
function onUpdateNoteHeight(v:string) { if (selectedNoteModel.value) selectedNoteModel.value.heightExpanded.value=v; }
110
+
function onUpdateNoteColor(v:string) { if (selectedNoteModel.value) selectedNoteModel.value.colorValue.value=v; }
111
+
function onUpdateNoteColorInherit(v:boolean) { if (selectedNoteModel.value) selectedNoteModel.value.colorInherit.value=v; }
112
+
function onUpdateNoteCollapsible(v:boolean) { if (selectedNoteModel.value) selectedNoteModel.value.collapsing.enabled.value=v; }
113
+
function onUpdateNoteCollapsed(v:boolean) { if (selectedNoteModel.value) selectedNoteModel.value.collapsing.collapsed.value=v; }
114
+
function onUpdateNoteMovable(v:boolean) { if (selectedNoteModel.value) selectedNoteModel.value.movable.value=v; }
115
+
function onUpdateNoteResizable(v:boolean) { if (selectedNoteModel.value) selectedNoteModel.value.resizable.value=v; }
116
+
function onUpdateNoteReadOnly(v:boolean) { if (selectedNoteModel.value) selectedNoteModel.value.readOnly.value=v; }
117
+
function onUpdateNoteContainerEnabled(v:boolean) { if (selectedNoteModel.value) selectedNoteModel.value.container.enabled.value=v; }
118
+
function onUpdateNoteContainerHorizontal(v:boolean) { if (selectedNoteModel.value) selectedNoteModel.value.container.horizontal.value=v; }
119
+
function onUpdateNoteContainerSpatial(v:boolean) { if (selectedNoteModel.value) selectedNoteModel.value.container.spatial.value=v; }
120
+
function onUpdateNoteContainerWrapChildren(v:boolean) { if (selectedNoteModel.value) selectedNoteModel.value.container.wrapChildren.value=v; }
121
+
function onUpdateNoteContainerStretchChildren(v:boolean) { if (selectedNoteModel.value) selectedNoteModel.value.container.stretchChildren.value=v; }
122
+
function onUpdateNoteContainerForceColorInheritance(v:boolean) { if (selectedNoteModel.value) selectedNoteModel.value.container.forceColorInheritance.value=v; }
123
+
function onUpdateNoteLocalCollapsing(v:boolean) { if (selectedNoteModel.value) selectedNoteModel.value.collapsing.localCollapsing.value=v; }
124
+
function onUpdateNoteLocallyCollapsed(v:boolean) { if (selectedNoteModel.value) selectedNoteModel.value.collapsing.locallyCollapsed.value=v; }
125
+
126
+
// Arrow property update handlers
127
+
function onUpdateArrowBodyType(v:string) { if (selectedArrowModel.value) selectedArrowModel.value.bodyType.value=v; }
128
+
function onUpdateArrowBodyStyle(v:string) { if (selectedArrowModel.value) selectedArrowModel.value.bodyStyle.value=v; }
129
+
function onUpdateArrowSourceHead(v:string) { if (selectedArrowModel.value) selectedArrowModel.value.sourceHead.value=v; }
130
+
function onUpdateArrowTargetHead(v:string) { if (selectedArrowModel.value) selectedArrowModel.value.targetHead.value=v; }
131
+
function onUpdateArrowColor(v:string) { if (selectedArrowModel.value) selectedArrowModel.value.color.value=v; }
132
+
function onUpdateArrowColorInherit(_v:boolean) { /* arrow model has no color.inherit */ }
133
+
function onUpdateArrowReadOnly(v:boolean) { if (selectedArrowModel.value) selectedArrowModel.value.readOnly.value=v; }
134
+
function onUpdateArrowSourceAnchor(v:string) { if (selectedArrowModel.value) selectedArrowModel.value.sourceAnchor.value=v==='null'?null:JSON.parse(v); }
135
+
function onUpdateArrowTargetAnchor(v:string) { if (selectedArrowModel.value) selectedArrowModel.value.targetAnchor.value=v==='null'?null:JSON.parse(v); }
87
136
88
137
// Track recent/favorite/selected pages for left sidebar
0 commit comments