Procházet zdrojové kódy

Merge pull request #33690 from overleaf/mj-prune-deleted-tabs

[web] Prune non-existent tabs when file tree changes

GitOrigin-RevId: 97e68a88a201acc2d1e582911ca64e1f72f9bfe1
Mathias Jakobsen před 3 měsíci
rodič
revize
6538c00742

+ 18 - 0
services/web/frontend/js/features/ide-react/context/tabs-context.tsx

@@ -241,6 +241,24 @@ export const TabsProvider: FC<React.PropsWithChildren> = ({ children }) => {
     })
   }, [openEntity, previewTabs, setOpenTabs, tabsEnabled])
 
+  useEffect(() => {
+    if (!tabsEnabled) {
+      return
+    }
+    // Make sure file tree is ready for lookup before pruning tabs, to avoid
+    // accidentally closing tabs that are still valid but not yet available
+    if (!fileTreeData?._id) {
+      return
+    }
+    setOpenTabs(current => {
+      const pruned = current.filter(tab => findInTree(fileTreeData, tab.id))
+      if (pruned.length === current.length) {
+        return current
+      }
+      return pruned
+    })
+  }, [fileTreeData, setOpenTabs, tabsEnabled])
+
   const value = useMemo(
     () => ({
       tabs,

+ 27 - 0
services/web/test/frontend/features/source-editor/components/tabs.spec.tsx

@@ -947,6 +947,33 @@ describe('File Tabs', function () {
     })
   })
 
+  describe('Pruning deleted files', function () {
+    it('prunes persisted tabs whose files are no longer in the tree', function () {
+      cy.then(() => selectDoc(DOC_IDS.main))
+      cy.then(() => selectDoc(DOC_IDS.intro))
+      cy.then(() => selectDoc(DOC_IDS.appendix))
+
+      cy.findAllByRole('tab').should('have.length', 3)
+
+      // Re-mount with a tree containing only appendix.tex, then verify
+      // the last remaining tab cannot be closed
+      const trimmedRootFolder = makeRootFolder([
+        { _id: DOC_IDS.appendix, name: 'appendix.tex' },
+      ])
+      mountTabs({ rootFolder: trimmedRootFolder })
+
+      cy.findAllByRole('tab').should('have.length', 1)
+      cy.findByRole('tab', { name: /appendix\.tex/ }).should('exist')
+
+      cy.findByRole('tab', { name: /appendix\.tex/ }).within(() => {
+        cy.findByRole('button', { name: 'Close tab' }).click()
+      })
+
+      cy.findAllByRole('tab').should('have.length', 1)
+      cy.findByRole('tab', { name: /appendix\.tex/ }).should('exist')
+    })
+  })
+
   describe('SplitTestBadge', function () {
     it('renders the labs badge icon in the tabs container', function () {
       cy.window().then(win => {