@@ -96,6 +96,11 @@ interface DeletedResource {
9696 color ?: string
9797}
9898
99+ interface RestoredResourceEntry {
100+ resource : DeletedResource
101+ displayIndex : number
102+ }
103+
99104const TABS : { id : ResourceType ; label : string } [ ] = [
100105 { id : 'all' , label : 'All' } ,
101106 { id : 'workflow' , label : 'Workflows' } ,
@@ -157,7 +162,7 @@ export function RecentlyDeleted() {
157162 const [ searchTerm , setSearchTerm ] = useState ( '' )
158163 const [ activeSort , setActiveSort ] = useState < SortConfig | null > ( null )
159164 const [ restoringIds , setRestoringIds ] = useState < Set < string > > ( new Set ( ) )
160- const [ restoredItems , setRestoredItems ] = useState < Map < string , DeletedResource > > ( new Map ( ) )
165+ const [ restoredItems , setRestoredItems ] = useState < Map < string , RestoredResourceEntry > > ( new Map ( ) )
161166
162167 const workflowsQuery = useWorkflows ( workspaceId , { scope : 'archived' } )
163168 const foldersQuery = useFolders ( workspaceId , { scope : 'archived' } )
@@ -255,13 +260,6 @@ export function RecentlyDeleted() {
255260 } )
256261 }
257262
258- const itemIds = new Set ( items . map ( ( i ) => i . id ) )
259- for ( const [ id , resource ] of restoredItems ) {
260- if ( ! itemIds . has ( id ) ) {
261- items . push ( resource )
262- }
263- }
264-
265263 return items
266264 } , [
267265 workflowsQuery . data ,
@@ -271,7 +269,6 @@ export function RecentlyDeleted() {
271269 filesQuery . data ,
272270 workspaceFoldersQuery . data ,
273271 workspaceId ,
274- restoredItems ,
275272 ] )
276273
277274 const filtered = useMemo ( ( ) => {
@@ -282,7 +279,7 @@ export function RecentlyDeleted() {
282279 }
283280 const col = ( activeSort ?? DEFAULT_SORT ) . column
284281 const dir = ( activeSort ?? DEFAULT_SORT ) . direction
285- return [ ...items ] . sort ( ( a , b ) => {
282+ items = [ ...items ] . sort ( ( a , b ) => {
286283 let cmp = 0
287284 switch ( col ) {
288285 case 'name' :
@@ -297,7 +294,22 @@ export function RecentlyDeleted() {
297294 }
298295 return dir === 'asc' ? cmp : - cmp
299296 } )
300- } , [ resources , activeTab , searchTerm , activeSort ] )
297+
298+ const itemIds = new Set ( items . map ( ( item ) => item . id ) )
299+ for ( const [ id , entry ] of restoredItems ) {
300+ if ( itemIds . has ( id ) ) continue
301+ if ( ! matchesActiveTab ( entry . resource , activeTab ) ) continue
302+ if (
303+ searchTerm . trim ( ) &&
304+ ! entry . resource . name . toLowerCase ( ) . includes ( searchTerm . toLowerCase ( ) )
305+ ) {
306+ continue
307+ }
308+ items . splice ( Math . min ( entry . displayIndex , items . length ) , 0 , entry . resource )
309+ }
310+
311+ return items
312+ } , [ resources , activeTab , searchTerm , activeSort , restoredItems ] )
301313
302314 const showNoResults = searchTerm . trim ( ) && filtered . length === 0 && resources . length > 0
303315 const selectedSort = activeSort ?? DEFAULT_SORT
@@ -316,56 +328,61 @@ export function RecentlyDeleted() {
316328 current = current . parentId ? byId . get ( current . parentId ) : undefined
317329 }
318330 }
319- router . push ( getResourceHref ( resource . workspaceId , resource . type , resource . id ) )
331+ const href = getResourceHref ( resource . workspaceId , resource . type , resource . id )
332+ router . push ( href )
320333 }
321334
322- function handleRestore ( resource : DeletedResource ) {
335+ async function handleRestore ( resource : DeletedResource ) {
336+ const displayIndex = Math . max (
337+ 0 ,
338+ filtered . findIndex ( ( item ) => item . id === resource . id )
339+ )
323340 setRestoringIds ( ( prev ) => new Set ( prev ) . add ( resource . id ) )
324341
325- const onSettled = ( ) => {
342+ try {
343+ switch ( resource . type ) {
344+ case 'workflow' :
345+ await restoreWorkflow . mutateAsync ( {
346+ workflowId : resource . id ,
347+ workspaceId : resource . workspaceId ,
348+ } )
349+ break
350+ case 'folder' :
351+ await restoreFolder . mutateAsync ( {
352+ folderId : resource . id ,
353+ workspaceId : resource . workspaceId ,
354+ } )
355+ break
356+ case 'table' :
357+ await restoreTable . mutateAsync ( resource . id )
358+ break
359+ case 'knowledge' :
360+ await restoreKnowledgeBase . mutateAsync ( resource . id )
361+ break
362+ case 'file' :
363+ await restoreWorkspaceFile . mutateAsync ( {
364+ workspaceId : resource . workspaceId ,
365+ fileId : resource . id ,
366+ } )
367+ break
368+ case 'workspace_folder' :
369+ await restoreWorkspaceFileFolder . mutateAsync ( {
370+ workspaceId : resource . workspaceId ,
371+ folderId : resource . id ,
372+ } )
373+ break
374+ }
375+
376+ setRestoredItems ( ( prev ) => new Map ( prev ) . set ( resource . id , { resource, displayIndex } ) )
377+ } catch {
378+ return
379+ } finally {
326380 setRestoringIds ( ( prev ) => {
327381 const next = new Set ( prev )
328382 next . delete ( resource . id )
329383 return next
330384 } )
331385 }
332-
333- const onSuccess = ( ) => {
334- setRestoredItems ( ( prev ) => new Map ( prev ) . set ( resource . id , resource ) )
335- }
336-
337- switch ( resource . type ) {
338- case 'workflow' :
339- restoreWorkflow . mutate (
340- { workflowId : resource . id , workspaceId : resource . workspaceId } ,
341- { onSettled, onSuccess }
342- )
343- break
344- case 'folder' :
345- restoreFolder . mutate (
346- { folderId : resource . id , workspaceId : resource . workspaceId } ,
347- { onSettled, onSuccess }
348- )
349- break
350- case 'table' :
351- restoreTable . mutate ( resource . id , { onSettled, onSuccess } )
352- break
353- case 'knowledge' :
354- restoreKnowledgeBase . mutate ( resource . id , { onSettled, onSuccess } )
355- break
356- case 'file' :
357- restoreWorkspaceFile . mutate (
358- { workspaceId : resource . workspaceId , fileId : resource . id } ,
359- { onSettled, onSuccess }
360- )
361- break
362- case 'workspace_folder' :
363- restoreWorkspaceFileFolder . mutate (
364- { workspaceId : resource . workspaceId , folderId : resource . id } ,
365- { onSettled, onSuccess }
366- )
367- break
368- }
369386 }
370387
371388 return (
@@ -460,7 +477,11 @@ export function RecentlyDeleted() {
460477 </ span >
461478 </ div >
462479
463- { isRestored ? (
480+ { isRestoring ? (
481+ < Button variant = 'primary' size = 'sm' disabled className = 'shrink-0' >
482+ Restoring...
483+ </ Button >
484+ ) : isRestored ? (
464485 < div className = 'flex shrink-0 items-center gap-2' >
465486 < span className = 'text-[var(--text-tertiary)] text-small' > Restored</ span >
466487 < Button variant = 'primary' size = 'sm' onClick = { ( ) => handleView ( resource ) } >
@@ -471,11 +492,10 @@ export function RecentlyDeleted() {
471492 < Button
472493 variant = 'primary'
473494 size = 'sm'
474- disabled = { isRestoring }
475- onClick = { ( ) => handleRestore ( resource ) }
495+ onClick = { ( ) => void handleRestore ( resource ) }
476496 className = 'shrink-0'
477497 >
478- { isRestoring ? 'Restoring...' : ' Restore' }
498+ Restore
479499 </ Button >
480500 ) }
481501 </ div >
0 commit comments