@@ -30,12 +30,15 @@ import {
3030 IContextService ,
3131 ILogService ,
3232 Injector ,
33+ IPermissionService ,
3334 IUniverInstanceService ,
35+ PermissionService ,
3436 RANGE_DIRECTION ,
3537 UniverInstanceService ,
3638} from '@univerjs/core' ;
37- import { DocSelectionManagerService , SetTextSelectionsOperation } from '@univerjs/docs' ;
39+ import { DocSelectionManagerService , setDocumentPermissionValue , SetTextSelectionsOperation } from '@univerjs/docs' ;
3840import { NORMAL_TEXT_SELECTION_PLUGIN_STYLE } from '@univerjs/engine-render' ;
41+ import { UnitAction } from '@univerjs/protocol' ;
3942import { ComponentManager } from '@univerjs/ui' ;
4043import { Subject } from 'rxjs' ;
4144import { describe , expect , it } from 'vitest' ;
@@ -93,6 +96,7 @@ function createActiveFloatMenuHarness(
9396 runtimeFocusCoordinator ?: EmbedRuntimeFocusCoordinator
9497) {
9598 const injector = new Injector ( ) ;
99+ injector . add ( [ IPermissionService , { useClass : PermissionService } ] ) ;
96100 injector . add ( [ ILogService , { useClass : DesktopLogService } ] ) ;
97101 injector . add ( [ IConfigService , { useClass : ConfigService } ] ) ;
98102 injector . add ( [ IContextService , { useClass : ContextService } ] ) ;
@@ -125,6 +129,7 @@ function createActiveFloatMenuHarness(
125129describe ( 'DocFloatMenuService' , ( ) => {
126130 it ( 'does not register or show a floating toolbar inside internal document editors' , ( ) => {
127131 const injector = new Injector ( ) ;
132+ injector . add ( [ IPermissionService , { useClass : PermissionService } ] ) ;
128133 injector . add ( [ ILogService , { useClass : DesktopLogService } ] ) ;
129134 injector . add ( [ IConfigService , { useClass : ConfigService } ] ) ;
130135 injector . add ( [ IContextService , { useClass : ContextService } ] ) ;
@@ -143,6 +148,7 @@ describe('DocFloatMenuService', () => {
143148
144149 it ( 'shows one floating toolbar for a text selection and hides it when selection restarts' , ( ) => {
145150 const injector = new Injector ( ) ;
151+ injector . add ( [ IPermissionService , { useClass : PermissionService } ] ) ;
146152 injector . add ( [ ILogService , { useClass : DesktopLogService } ] ) ;
147153 injector . add ( [ IConfigService , { useClass : ConfigService } ] ) ;
148154 injector . add ( [ IContextService , { useClass : ContextService } ] ) ;
@@ -207,8 +213,47 @@ describe('DocFloatMenuService', () => {
207213 expect ( popupService . disposedCount ) . toBe ( 1 ) ;
208214 } ) ;
209215
216+ it ( 'hides the floating toolbar when document edit permission is revoked' , ( ) => {
217+ const unitId = 'doc-read-only-float-menu' ;
218+ const harness = createActiveFloatMenuHarness ( unitId , {
219+ dataStream : 'Hello world\r\n' ,
220+ paragraphs : [ { paragraphId : 'para_docs_ui_read_only_float_menu' , startIndex : 11 } ] ,
221+ sectionBreaks : [ ] ,
222+ customRanges : [ ] ,
223+ tables : [ ] ,
224+ textRuns : [ ] ,
225+ } ) ;
226+ const selection = {
227+ textRanges : [ { startOffset : 0 , endOffset : 5 , collapsed : false } ] ,
228+ rectRanges : [ ] ,
229+ segmentId : '' ,
230+ segmentPage : - 1 ,
231+ style : NORMAL_TEXT_SELECTION_PLUGIN_STYLE ,
232+ isEditing : true ,
233+ } ;
234+ harness . selectionManager . __replaceTextRangesWithNoRefresh ( selection , { unitId, subUnitId : unitId } ) ;
235+ expect ( harness . service . floatMenu ) . toMatchObject ( { start : 0 , end : 5 } ) ;
236+
237+ setDocumentPermissionValue (
238+ harness . injector . get ( IPermissionService ) ,
239+ unitId ,
240+ unitId ,
241+ UnitAction . Edit ,
242+ false
243+ ) ;
244+
245+ expect ( harness . service . floatMenu ) . toBeNull ( ) ;
246+ expect ( harness . popupService . disposedCount ) . toBe ( 1 ) ;
247+ harness . selectionManager . __replaceTextRangesWithNoRefresh ( {
248+ ...selection ,
249+ textRanges : [ { startOffset : 6 , endOffset : 11 , collapsed : false } ] ,
250+ } , { unitId, subUnitId : unitId } ) ;
251+ expect ( harness . popupService . ranges ) . toEqual ( [ '0:5' ] ) ;
252+ } ) ;
253+
210254 it ( 'does not show the floating toolbar for selections inside code blocks' , ( ) => {
211255 const injector = new Injector ( ) ;
256+ injector . add ( [ IPermissionService , { useClass : PermissionService } ] ) ;
212257 injector . add ( [ ILogService , { useClass : DesktopLogService } ] ) ;
213258 injector . add ( [ IConfigService , { useClass : ConfigService } ] ) ;
214259 injector . add ( [ IContextService , { useClass : ContextService } ] ) ;
0 commit comments