diff --git a/services/web/frontend/js/features/file-tree/controllers/file-tree-controller.js b/services/web/frontend/js/features/file-tree/controllers/file-tree-controller.js index 8b62a91a34..76d54bf508 100644 --- a/services/web/frontend/js/features/file-tree/controllers/file-tree-controller.js +++ b/services/web/frontend/js/features/file-tree/controllers/file-tree-controller.js @@ -3,6 +3,7 @@ import { react2angular } from 'react2angular' import { cloneDeep } from 'lodash' import FileTreeRoot from '../components/file-tree-root' +import { rootContext } from '../../../shared/context/root-context' App.controller('ReactFileTreeController', function ( $scope, @@ -115,4 +116,10 @@ App.controller('ReactFileTreeController', function ( } }) -App.component('fileTreeRoot', react2angular(FileTreeRoot)) +App.component( + 'fileTreeRoot', + react2angular( + rootContext.use(FileTreeRoot), + Object.keys(FileTreeRoot.propTypes) + ) +) diff --git a/services/web/frontend/js/features/file-tree/hooks/file-tree-socket-listener.js b/services/web/frontend/js/features/file-tree/hooks/file-tree-socket-listener.js index 130b94be98..db57703300 100644 --- a/services/web/frontend/js/features/file-tree/hooks/file-tree-socket-listener.js +++ b/services/web/frontend/js/features/file-tree/hooks/file-tree-socket-listener.js @@ -1,10 +1,15 @@ import { useCallback, useEffect } from 'react' +import PropTypes from 'prop-types' +import { useApplicationContext } from '../../../shared/context/application-context' import { useFileTreeMutable } from '../contexts/file-tree-mutable' import { useFileTreeSelectable } from '../contexts/file-tree-selectable' import { findInTreeOrThrow } from '../util/find-in-tree' export function useFileTreeSocketListener() { + const { user } = useApplicationContext({ + user: PropTypes.shape({ id: PropTypes.string.isRequired }), + }) const { dispatchRename, dispatchDelete, @@ -25,14 +30,17 @@ export function useFileTreeSocketListener() { const selectEntityIfCreatedByUser = useCallback( // hack to automatically re-open refreshed linked files (entityId, entityName, userId) => { - if (window.user && window.user.id && window.user.id === userId) { + // If the created entity's user exists and is the current user + if (userId && user?.id === userId) { + // And we're expecting a refreshed socket for this entity if (window.expectingLinkedFileRefreshedSocketFor === entityName) { + // Then select it select(entityId) window.expectingLinkedFileRefreshedSocketFor = null } } }, - [select] + [user, select] ) useEffect(() => { diff --git a/services/web/frontend/stories/file-tree.stories.js b/services/web/frontend/stories/file-tree.stories.js index ef4c589fb0..8df74b7e75 100644 --- a/services/web/frontend/stories/file-tree.stories.js +++ b/services/web/frontend/stories/file-tree.stories.js @@ -1,6 +1,7 @@ import React from 'react' import MockedSocket from 'socket.io-mock' +import { ContextRoot } from '../js/shared/context/root-context' import { rootFolderBase } from './fixtures/file-tree-base' import { rootFolderLimit } from './fixtures/file-tree-limit' import FileTreeRoot from '../js/features/file-tree/components/file-tree-root' @@ -149,7 +150,9 @@ export default {
- + + +
diff --git a/services/web/test/frontend/features/file-tree/components/file-tree-root.test.js b/services/web/test/frontend/features/file-tree/components/file-tree-root.test.js index 70dda86a79..c95b496ee9 100644 --- a/services/web/test/frontend/features/file-tree/components/file-tree-root.test.js +++ b/services/web/test/frontend/features/file-tree/components/file-tree-root.test.js @@ -1,9 +1,13 @@ import { expect } from 'chai' import React from 'react' import sinon from 'sinon' -import { screen, render, fireEvent, waitFor } from '@testing-library/react' +import { screen, fireEvent, waitFor } from '@testing-library/react' import fetchMock from 'fetch-mock' +import { + renderWithEditorContext, + cleanUpContext, +} from '../../../helpers/render-with-context' import FileTreeRoot from '../../../../../frontend/js/features/file-tree/components/file-tree-root' describe('', function () { @@ -19,6 +23,7 @@ describe('', function () { fetchMock.restore() onSelect.reset() onInit.reset() + cleanUpContext() global.localStorage.clear() }) @@ -31,7 +36,7 @@ describe('', function () { fileRefs: [], }, ] - const { container } = render( + const { container } = renderWithEditorContext( ', function () { fileRefs: [], }, ] - render( + renderWithEditorContext( ', function () { }, ] - const { container } = render( + const { container } = renderWithEditorContext( ', function () { fileRefs: [], }, ] - render( + renderWithEditorContext( ', function () { fileRefs: [], }, ] - render( + renderWithEditorContext( + />, + { socket: new MockedSocket() } ) const newFolderName = 'Foo Bar In Root' @@ -95,7 +97,7 @@ describe('FileTree Create Folder Flow', function () { fileRefs: [], }, ] - render( + renderWithEditorContext( + />, + { socket: new MockedSocket() } ) const expandButton = screen.getByRole('button', { name: 'Expand' }) @@ -165,7 +168,7 @@ describe('FileTree Create Folder Flow', function () { fileRefs: [], }, ] - render( + renderWithEditorContext( + />, + { socket: new MockedSocket() } ) const newFolderName = 'Foo Bar In thefolder' @@ -224,7 +228,7 @@ describe('FileTree Create Folder Flow', function () { fileRefs: [], }, ] - render( + renderWithEditorContext( + />, + { socket: new MockedSocket() } ) var newFolderName = 'existingFile' diff --git a/services/web/test/frontend/features/file-tree/flows/delete-entity.test.js b/services/web/test/frontend/features/file-tree/flows/delete-entity.test.js index 7e3ec37cda..743cb5debb 100644 --- a/services/web/test/frontend/features/file-tree/flows/delete-entity.test.js +++ b/services/web/test/frontend/features/file-tree/flows/delete-entity.test.js @@ -1,27 +1,25 @@ import { expect } from 'chai' import React from 'react' import sinon from 'sinon' -import { screen, render, fireEvent, waitFor } from '@testing-library/react' +import { screen, fireEvent, waitFor } from '@testing-library/react' import fetchMock from 'fetch-mock' import MockedSocket from 'socket.io-mock' +import { + renderWithEditorContext, + cleanUpContext, +} from '../../../helpers/render-with-context' import FileTreeRoot from '../../../../../frontend/js/features/file-tree/components/file-tree-root' describe('FileTree Delete Entity Flow', function () { const onSelect = sinon.stub() const onInit = sinon.stub() - beforeEach(function () { - window._ide = { - socket: new MockedSocket(), - } - }) - afterEach(function () { fetchMock.restore() onSelect.reset() onInit.reset() - delete window._ide + cleanUpContext() }) describe('single entity', function () { @@ -34,7 +32,7 @@ describe('FileTree Delete Entity Flow', function () { fileRefs: [], }, ] - render( + renderWithEditorContext( + />, + { socket: new MockedSocket() } ) const treeitem = screen.getByRole('treeitem', { name: 'main.tex' }) @@ -151,7 +150,7 @@ describe('FileTree Delete Entity Flow', function () { fileRefs: [], }, ] - render( + renderWithEditorContext( + />, + { socket: new MockedSocket() } ) const expandButton = screen.queryByRole('button', { name: 'Expand' }) @@ -208,7 +208,7 @@ describe('FileTree Delete Entity Flow', function () { }, ] - render( + renderWithEditorContext( + />, + { socket: new MockedSocket() } ) // select two files diff --git a/services/web/test/frontend/features/file-tree/flows/rename-entity.test.js b/services/web/test/frontend/features/file-tree/flows/rename-entity.test.js index ba55d549b1..566f59c7d4 100644 --- a/services/web/test/frontend/features/file-tree/flows/rename-entity.test.js +++ b/services/web/test/frontend/features/file-tree/flows/rename-entity.test.js @@ -1,10 +1,14 @@ import { expect } from 'chai' import React from 'react' import sinon from 'sinon' -import { screen, render, fireEvent } from '@testing-library/react' +import { screen, fireEvent } from '@testing-library/react' import fetchMock from 'fetch-mock' import MockedSocket from 'socket.io-mock' +import { + renderWithEditorContext, + cleanUpContext, +} from '../../../helpers/render-with-context' import FileTreeRoot from '../../../../../frontend/js/features/file-tree/components/file-tree-root' describe('FileTree Rename Entity Flow', function () { @@ -12,9 +16,6 @@ describe('FileTree Rename Entity Flow', function () { const onInit = sinon.stub() beforeEach(function () { - window._ide = { - socket: new MockedSocket(), - } global.requestAnimationFrame = sinon.stub() }) @@ -23,7 +24,7 @@ describe('FileTree Rename Entity Flow', function () { fetchMock.restore() onSelect.reset() onInit.reset() - delete window._ide + cleanUpContext() }) beforeEach(function () { @@ -46,7 +47,7 @@ describe('FileTree Rename Entity Flow', function () { fileRefs: [], }, ] - render( + renderWithEditorContext( + />, + { socket: new MockedSocket() } ) })