@@ -86,6 +86,7 @@ export function WorkflowList({
8686 const workflowId = params . workflowId as string
8787
8888 const { isLoading : foldersLoading } = useFolders ( workspaceId )
89+ const folders = useFolderStore ( ( state ) => state . folders )
8990 const { getFolderTree, expandedFolders, getFolderPath, setExpanded } = useFolderStore ( )
9091
9192 const {
@@ -119,7 +120,10 @@ export function WorkflowList({
119120 }
120121 } , [ scrollContainerRef , setScrollContainer ] )
121122
122- const folderTree = workspaceId ? getFolderTree ( workspaceId ) : [ ]
123+ const folderTree = useMemo (
124+ ( ) => ( workspaceId ? getFolderTree ( workspaceId ) : [ ] ) ,
125+ [ workspaceId , folders , getFolderTree ]
126+ )
123127
124128 const activeWorkflowFolderId = useMemo ( ( ) => {
125129 if ( ! workflowId || isLoading || foldersLoading ) return null
@@ -225,49 +229,135 @@ export function WorkflowList({
225229 const orderedFolderIds = useMemo ( ( ) => {
226230 const ids : string [ ] = [ ]
227231
228- const collectFolderIds = ( folder : FolderTreeNode ) => {
232+ const collectFromFolder = ( folder : FolderTreeNode ) => {
229233 ids . push ( folder . id )
230- for ( const childFolder of folder . children ) {
231- collectFolderIds ( childFolder )
234+ const workflowsInFolder = workflowsByFolder [ folder . id ] || [ ]
235+ const childItems : Array < {
236+ type : 'folder' | 'workflow'
237+ id : string
238+ sortOrder : number
239+ createdAt ?: Date
240+ data : FolderTreeNode | WorkflowMetadata
241+ } > = [ ]
242+ for ( const child of folder . children ) {
243+ childItems . push ( {
244+ type : 'folder' ,
245+ id : child . id ,
246+ sortOrder : child . sortOrder ,
247+ createdAt : child . createdAt ,
248+ data : child ,
249+ } )
250+ }
251+ for ( const wf of workflowsInFolder ) {
252+ childItems . push ( {
253+ type : 'workflow' ,
254+ id : wf . id ,
255+ sortOrder : wf . sortOrder ,
256+ createdAt : wf . createdAt ,
257+ data : wf ,
258+ } )
259+ }
260+ childItems . sort ( compareByOrder )
261+ for ( const item of childItems ) {
262+ if ( item . type === 'folder' ) {
263+ collectFromFolder ( item . data as FolderTreeNode )
264+ }
232265 }
233266 }
234267
268+ const rootLevelItems : Array < {
269+ type : 'folder' | 'workflow'
270+ id : string
271+ sortOrder : number
272+ createdAt ?: Date
273+ data : FolderTreeNode | WorkflowMetadata
274+ } > = [ ]
235275 for ( const folder of folderTree ) {
236- collectFolderIds ( folder )
276+ rootLevelItems . push ( {
277+ type : 'folder' ,
278+ id : folder . id ,
279+ sortOrder : folder . sortOrder ,
280+ createdAt : folder . createdAt ,
281+ data : folder ,
282+ } )
283+ }
284+ const rootWfs = workflowsByFolder . root || [ ]
285+ for ( const wf of rootWfs ) {
286+ rootLevelItems . push ( {
287+ type : 'workflow' ,
288+ id : wf . id ,
289+ sortOrder : wf . sortOrder ,
290+ createdAt : wf . createdAt ,
291+ data : wf ,
292+ } )
293+ }
294+ rootLevelItems . sort ( compareByOrder )
295+
296+ for ( const item of rootLevelItems ) {
297+ if ( item . type === 'folder' ) {
298+ collectFromFolder ( item . data as FolderTreeNode )
299+ }
237300 }
238301
239302 return ids
240- } , [ folderTree ] )
303+ } , [ folderTree , workflowsByFolder ] )
241304
242- const workflowFolderMap = useMemo ( ( ) => {
243- const map : Record < string , string > = { }
244- for ( const wf of regularWorkflows ) {
245- if ( wf . folderId ) {
246- map [ wf . id ] = wf . folderId
305+ const {
306+ workflowAncestorFolderIds,
307+ folderDescendantWorkflowIds,
308+ folderAncestorIds,
309+ folderDescendantIds,
310+ } = useMemo ( ( ) => {
311+ const wfAncestors : Record < string , string [ ] > = { }
312+ const fDescWfs : Record < string , string [ ] > = { }
313+ const fAncestors : Record < string , string [ ] > = { }
314+ const fDescendants : Record < string , string [ ] > = { }
315+
316+ const buildMaps = ( folder : FolderTreeNode , ancestors : string [ ] ) => {
317+ fAncestors [ folder . id ] = ancestors
318+ const wfsInFolder = ( workflowsByFolder [ folder . id ] || [ ] ) . map ( ( w ) => w . id )
319+ const allDescWfs = [ ...wfsInFolder ]
320+ const allDescFolders : string [ ] = [ ]
321+
322+ for ( const child of folder . children ) {
323+ buildMaps ( child , [ ...ancestors , folder . id ] )
324+ allDescFolders . push ( child . id , ...( fDescendants [ child . id ] || [ ] ) )
325+ allDescWfs . push ( ...( fDescWfs [ child . id ] || [ ] ) )
247326 }
327+
328+ fDescendants [ folder . id ] = allDescFolders
329+ fDescWfs [ folder . id ] = allDescWfs
248330 }
249- return map
250- } , [ regularWorkflows ] )
251331
252- const folderWorkflowIds = useMemo ( ( ) => {
253- const map : Record < string , string [ ] > = { }
254- for ( const [ folderId , workflows ] of Object . entries ( workflowsByFolder ) ) {
255- if ( folderId !== 'root' ) {
256- map [ folderId ] = workflows . map ( ( w ) => w . id )
332+ for ( const folder of folderTree ) {
333+ buildMaps ( folder , [ ] )
334+ }
335+
336+ for ( const wf of regularWorkflows ) {
337+ if ( wf . folderId && fAncestors [ wf . folderId ] !== undefined ) {
338+ wfAncestors [ wf . id ] = [ wf . folderId , ...fAncestors [ wf . folderId ] ]
257339 }
258340 }
259- return map
260- } , [ workflowsByFolder ] )
341+
342+ return {
343+ workflowAncestorFolderIds : wfAncestors ,
344+ folderDescendantWorkflowIds : fDescWfs ,
345+ folderAncestorIds : fAncestors ,
346+ folderDescendantIds : fDescendants ,
347+ }
348+ } , [ folderTree , workflowsByFolder , regularWorkflows ] )
261349
262350 const { handleWorkflowClick } = useWorkflowSelection ( {
263351 workflowIds : orderedWorkflowIds ,
264352 activeWorkflowId : workflowId ,
265- workflowFolderMap ,
353+ workflowAncestorFolderIds ,
266354 } )
267355
268356 const { handleFolderClick } = useFolderSelection ( {
269357 folderIds : orderedFolderIds ,
270- folderWorkflowIds,
358+ folderDescendantWorkflowIds,
359+ folderAncestorIds,
360+ folderDescendantIds,
271361 } )
272362
273363 const isWorkflowActive = useCallback (
@@ -472,9 +562,8 @@ export function WorkflowList({
472562 const handleContainerClick = useCallback (
473563 ( e : React . MouseEvent < HTMLDivElement > ) => {
474564 if ( e . target !== e . currentTarget ) return
475- const { selectOnly, clearSelection, clearFolderSelection } = useFolderStore . getState ( )
476- clearFolderSelection ( )
477- workflowId ? selectOnly ( workflowId ) : clearSelection ( )
565+ const { selectOnly, clearAllSelection } = useFolderStore . getState ( )
566+ workflowId ? selectOnly ( workflowId ) : clearAllSelection ( )
478567 } ,
479568 [ workflowId ]
480569 )
0 commit comments