@@ -32,8 +32,9 @@ import {
3232 useExportFolder ,
3333 useExportSelection ,
3434} from '@/app/workspace/[workspaceId]/w/hooks'
35- import { useCreateFolder , useUpdateFolder } from '@/hooks/queries/folders'
35+ import { useCreateFolder , useFolderMap , useUpdateFolder } from '@/hooks/queries/folders'
3636import { getFolderMap } from '@/hooks/queries/utils/folder-cache'
37+ import { isFolderOrAncestorLocked } from '@/hooks/queries/utils/folder-tree'
3738import { getWorkflows } from '@/hooks/queries/utils/workflow-cache'
3839import { useCreateWorkflow } from '@/hooks/queries/workflows'
3940import { useFolderStore } from '@/stores/folders/store'
@@ -76,6 +77,10 @@ export function FolderItem({
7677 const selectedFolders = useFolderStore ( ( state ) => state . selectedFolders )
7778 const isSelected = selectedFolders . has ( folder . id )
7879
80+ const { data : foldersById = { } } = useFolderMap ( workspaceId )
81+ const inheritedFolderLocked = isFolderOrAncestorLocked ( folder . parentId , foldersById )
82+ const effectiveLocked = folder . locked || inheritedFolderLocked
83+
7984 const { canDeleteFolder, canDeleteWorkflows } = useCanDelete ( { workspaceId } )
8085
8186 const [ isDeleteModalOpen , setIsDeleteModalOpen ] = useState ( false )
@@ -144,7 +149,7 @@ export function FolderItem({
144149 const dragGhostRef = useRef < HTMLElement | null > ( null )
145150
146151 const handleCreateWorkflowInFolder = useCallback ( ( ) => {
147- if ( folder . locked ) return
152+ if ( effectiveLocked ) return
148153 const name = generateCreativeWorkflowName ( )
149154 const color = getNextWorkflowColor ( )
150155 const id = generateId ( )
@@ -161,10 +166,10 @@ export function FolderItem({
161166 expandFolder ( )
162167 router . push ( `/workspace/${ workspaceId } /w/${ id } ` )
163168 window . dispatchEvent ( new CustomEvent ( SIDEBAR_SCROLL_EVENT , { detail : { itemId : id } } ) )
164- } , [ createWorkflowMutation , workspaceId , folder . id , folder . locked , router , expandFolder ] )
169+ } , [ createWorkflowMutation , workspaceId , folder . id , effectiveLocked , router , expandFolder ] )
165170
166171 const handleCreateFolderInFolder = useCallback ( async ( ) => {
167- if ( folder . locked ) return
172+ if ( effectiveLocked ) return
168173 try {
169174 const result = await createFolderMutation . mutateAsync ( {
170175 workspaceId,
@@ -181,15 +186,16 @@ export function FolderItem({
181186 } catch ( error ) {
182187 logger . error ( 'Failed to create folder:' , error )
183188 }
184- } , [ createFolderMutation , workspaceId , folder . id , folder . locked , expandFolder ] )
189+ } , [ createFolderMutation , workspaceId , folder . id , effectiveLocked , expandFolder ] )
185190
186191 const handleToggleLock = useCallback ( ( ) => {
192+ if ( inheritedFolderLocked ) return
187193 updateFolderMutation . mutate ( {
188194 workspaceId,
189195 id : folder . id ,
190196 updates : { locked : ! folder . locked } ,
191197 } )
192- } , [ folder . id , folder . locked , updateFolderMutation , workspaceId ] )
198+ } , [ folder . id , folder . locked , inheritedFolderLocked , updateFolderMutation , workspaceId ] )
193199
194200 const onDragStart = useCallback (
195201 ( e : React . DragEvent ) => {
@@ -337,11 +343,11 @@ export function FolderItem({
337343 ( e : React . MouseEvent ) => {
338344 e . preventDefault ( )
339345 e . stopPropagation ( )
340- if ( ! folder . locked ) {
346+ if ( ! effectiveLocked ) {
341347 handleStartEdit ( )
342348 }
343349 } ,
344- [ folder . locked , handleStartEdit ]
350+ [ effectiveLocked , handleStartEdit ]
345351 )
346352
347353 const handleClick = useCallback (
@@ -491,7 +497,7 @@ export function FolderItem({
491497 onClick = { handleClick }
492498 onKeyDown = { handleKeyDown }
493499 onContextMenu = { handleContextMenu }
494- draggable = { ! isEditing && ! dragDisabled && ! folder . locked }
500+ draggable = { ! isEditing && ! dragDisabled && ! effectiveLocked }
495501 onDragStart = { handleDragStart }
496502 onDragEnd = { handleDragEnd }
497503 { ...hoverHandlers }
@@ -574,22 +580,22 @@ export function FolderItem({
574580 showRename = { ! isMixedSelection && selectedFolders . size <= 1 }
575581 showDuplicate = { true }
576582 showExport = { true }
577- disableRename = { ! userPermissions . canEdit || folder . locked }
583+ disableRename = { ! userPermissions . canEdit || effectiveLocked }
578584 disableCreate = {
579- ! userPermissions . canEdit || folder . locked || createWorkflowMutation . isPending
585+ ! userPermissions . canEdit || effectiveLocked || createWorkflowMutation . isPending
580586 }
581587 disableCreateFolder = {
582- ! userPermissions . canEdit || folder . locked || createFolderMutation . isPending
588+ ! userPermissions . canEdit || effectiveLocked || createFolderMutation . isPending
583589 }
584590 disableDuplicate = {
585591 ! userPermissions . canEdit || isDuplicatingSelection || ! hasExportableContent
586592 }
587593 disableExport = { ! userPermissions . canEdit || isExporting || ! hasExportableContent }
588- disableDelete = { ! userPermissions . canEdit || folder . locked || ! canDeleteSelection }
594+ disableDelete = { ! userPermissions . canEdit || effectiveLocked || ! canDeleteSelection }
589595 onToggleLock = { handleToggleLock }
590596 showLock = { ! isMixedSelection && selectedFolders . size <= 1 }
591- disableLock = { ! userPermissions . canAdmin }
592- isLocked = { folder . locked }
597+ disableLock = { ! userPermissions . canAdmin || inheritedFolderLocked }
598+ isLocked = { effectiveLocked }
593599 />
594600
595601 < DeleteModal
0 commit comments