diff --git a/apps/client/src/widgets/ribbon/NoteActionsCustom.tsx b/apps/client/src/widgets/ribbon/NoteActionsCustom.tsx index 482cd1a693..4c91c1323b 100644 --- a/apps/client/src/widgets/ribbon/NoteActionsCustom.tsx +++ b/apps/client/src/widgets/ribbon/NoteActionsCustom.tsx @@ -189,7 +189,7 @@ function SwitchSplitOrientationButton({ note, isReadOnly, isDefaultViewMode }: N export function ToggleReadOnlyButton({ note, isDefaultViewMode }: NoteActionsCustomInnerProps) { const [ isReadOnly, setReadOnly ] = useNoteLabelBoolean(note, "readOnly"); const isSavedSqlite = note.isTriliumSqlite() && !note.isHiddenCompletely(); - const isEnabled = ([ "mermaid", "mindMap", "canvas" ].includes(note.type) || isSavedSqlite) + const isEnabled = ([ "mermaid", "mindMap", "canvas", "spreadsheet" ].includes(note.type) || isSavedSqlite) && note.isContentAvailable() && isDefaultViewMode; return isEnabled && { @@ -152,3 +154,40 @@ function usePersistence(note: FNote, noteContext: NoteContext | null | undefined }; }, []); } + +function useReadOnly(note: FNote, apiRef: MutableRef) { + const [ readOnly ] = useNoteLabelBoolean(note, "readOnly"); + + useEffect(() => { + const univerAPI = apiRef.current; + if (!univerAPI) return; + + function apply() { + const workbook = univerAPI?.getActiveWorkbook(); + if (!workbook) return; + + const permission = workbook.getPermission(); + if (readOnly) { + workbook.disableSelection(); + } else { + workbook.enableSelection(); + } + permission.setWorkbookEditPermission(workbook.getId(), !readOnly); + permission.setPermissionDialogVisible(false); + } + + // Try immediately (covers post-init changes). + apply(); + + // Also listen for lifecycle in case Univer isn't ready yet. + const disposable = univerAPI.addEvent( + univerAPI.Event.LifeCycleChanged, + ({ stage }) => { + if (stage === univerAPI.Enum.LifecycleStages.Rendered) { + apply(); + } + } + ); + return () => disposable.dispose(); + }, [ readOnly, apiRef ]); +}