From 8c7bf5fbd277db1d3735c1df391577835db44fc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Alby?= Date: Tue, 5 Jan 2021 11:56:58 +0100 Subject: [PATCH] Merge pull request #3502 from overleaf/ta-file-tree-select-created [ReactFileTree] Auto-Select Entities Created by User GitOrigin-RevId: b45d54cbe124c51be819456b8ea17ddd075b1922 --- .../src/Features/Editor/EditorController.js | 33 +++++++++++++----- .../Features/Editor/EditorHttpController.js | 4 ++- .../Project/ProjectEntityUpdateHandler.js | 3 +- .../Uploads/FileSystemImportManager.js | 3 +- .../contexts/file-tree-selectable.js | 5 +++ .../hooks/file-tree-socket-listener.js | 34 ++++++++++++++----- .../unit/src/Editor/EditorControllerTests.js | 29 ++++++++++------ 7 files changed, 80 insertions(+), 31 deletions(-) diff --git a/services/web/app/src/Features/Editor/EditorController.js b/services/web/app/src/Features/Editor/EditorController.js index 2c3c372639..f8c2142381 100644 --- a/services/web/app/src/Features/Editor/EditorController.js +++ b/services/web/app/src/Features/Editor/EditorController.js @@ -80,7 +80,8 @@ const EditorController = { 'reciveNewDoc', folder_id, doc, - source + source, + user_id ) return callback(err, doc) } @@ -124,7 +125,8 @@ const EditorController = { folder_id, fileRef, source, - linkedFileData + linkedFileData, + user_id ) return callback(err, fileRef) } @@ -157,7 +159,8 @@ const EditorController = { 'reciveNewDoc', folder_id, doc, - source + source, + user_id ) } return callback(err, doc) @@ -205,7 +208,8 @@ const EditorController = { folder_id, newFile, source, - linkedFileData + linkedFileData, + user_id ) return callback(null, newFile) } @@ -243,7 +247,8 @@ const EditorController = { 'reciveNewDoc', lastFolder._id, doc, - source + source, + user_id ) } return callback() @@ -295,7 +300,8 @@ const EditorController = { lastFolder._id, newFile, source, - linkedFileData + linkedFileData, + user_id ) return callback() } @@ -304,7 +310,7 @@ const EditorController = { ) }, - addFolder(project_id, folder_id, folderName, source, callback) { + addFolder(project_id, folder_id, folderName, source, userId, callback) { if (callback == null) { callback = function(error, folder) {} } @@ -328,6 +334,7 @@ const EditorController = { project_id, folder_id, folder, + userId, function(err) { if (err != null) { return callback(err) @@ -677,13 +684,20 @@ const EditorController = { project_id, folder.parentFolder_id, folder, + null, cb ), callback ) }, - _notifyProjectUsersOfNewFolder(project_id, folder_id, folder, callback) { + _notifyProjectUsersOfNewFolder( + project_id, + folder_id, + folder, + userId, + callback + ) { if (callback == null) { callback = function(error) {} } @@ -691,7 +705,8 @@ const EditorController = { project_id, 'reciveNewFolder', folder_id, - folder + folder, + userId ) return callback() } diff --git a/services/web/app/src/Features/Editor/EditorHttpController.js b/services/web/app/src/Features/Editor/EditorHttpController.js index dc14b80e45..d62b1081cf 100644 --- a/services/web/app/src/Features/Editor/EditorHttpController.js +++ b/services/web/app/src/Features/Editor/EditorHttpController.js @@ -170,6 +170,7 @@ async function addFolder(req, res, next) { const projectId = req.params.Project_id const { name } = req.body const parentFolderId = req.body.parent_folder_id + const userId = AuthenticationController.getLoggedInUserId(req) if (!_nameIsAcceptableLength(name)) { return res.sendStatus(400) } @@ -178,7 +179,8 @@ async function addFolder(req, res, next) { projectId, parentFolderId, name, - 'editor' + 'editor', + userId ) res.json(doc) } catch (err) { diff --git a/services/web/app/src/Features/Project/ProjectEntityUpdateHandler.js b/services/web/app/src/Features/Project/ProjectEntityUpdateHandler.js index 0d21a757cc..5ce7c565aa 100644 --- a/services/web/app/src/Features/Project/ProjectEntityUpdateHandler.js +++ b/services/web/app/src/Features/Project/ProjectEntityUpdateHandler.js @@ -1643,7 +1643,8 @@ const ProjectEntityUpdateHandler = { folder._id, fileRef, 'convertDocToFile', - null + null, + userId ) callback(null, fileRef) } diff --git a/services/web/app/src/Features/Uploads/FileSystemImportManager.js b/services/web/app/src/Features/Uploads/FileSystemImportManager.js index 26389f034c..cfba5be997 100644 --- a/services/web/app/src/Features/Uploads/FileSystemImportManager.js +++ b/services/web/app/src/Features/Uploads/FileSystemImportManager.js @@ -71,7 +71,8 @@ async function addFolder(userId, projectId, folderId, name, path, replace) { projectId, folderId, name, - 'upload' + 'upload', + userId ) await addFolderContents(userId, projectId, newFolder._id, path, replace) return newFolder diff --git a/services/web/frontend/js/features/file-tree/contexts/file-tree-selectable.js b/services/web/frontend/js/features/file-tree/contexts/file-tree-selectable.js index 2022d5f19d..7c27376ab5 100644 --- a/services/web/frontend/js/features/file-tree/contexts/file-tree-selectable.js +++ b/services/web/frontend/js/features/file-tree/contexts/file-tree-selectable.js @@ -154,12 +154,17 @@ export function useSelectableEntity(id) { export function useFileTreeSelectable() { const { selectedEntityIds, dispatch } = useContext(FileTreeSelectableContext) + function select(id) { + dispatch({ type: ACTION_TYPES.SELECT, id }) + } + function unselect(id) { dispatch({ type: ACTION_TYPES.UNSELECT, id }) } return { selectedEntityIds, + select, unselect } } 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 98d90666ad..cc669e7dea 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,4 +1,4 @@ -import { useEffect } from 'react' +import { useCallback, useEffect } from 'react' import { useFileTreeMutable } from '../contexts/file-tree-mutable' import { useFileTreeSelectable } from '../contexts/file-tree-selectable' @@ -12,9 +12,18 @@ export function useFileTreeSocketListener() { dispatchCreateDoc, dispatchCreateFile } = useFileTreeMutable() - const { unselect } = useFileTreeSelectable() + const { select, unselect } = useFileTreeSelectable() const socket = window._ide && window._ide.socket + const selectEntityIfCreatedByUser = useCallback( + (entityId, userId) => { + if (window.user && window.user.id && window.user.id === userId) { + select(entityId) + } + }, + [select] + ) + useEffect(() => { function handleDispatchRename(entityId, name) { dispatchRename(entityId, name) @@ -48,34 +57,43 @@ export function useFileTreeSocketListener() { }, [socket, dispatchMove]) useEffect(() => { - function handleDispatchCreateFolder(parentFolderId, folder) { + function handleDispatchCreateFolder(parentFolderId, folder, userId) { dispatchCreateFolder(parentFolderId, folder) + selectEntityIfCreatedByUser(folder._id, userId) } if (socket) socket.on('reciveNewFolder', handleDispatchCreateFolder) return () => { if (socket) socket.removeListener('reciveNewFolder', handleDispatchCreateFolder) } - }, [socket, dispatchCreateFolder]) + }, [socket, dispatchCreateFolder, selectEntityIfCreatedByUser]) useEffect(() => { - function handleDispatchCreateDoc(parentFolderId, doc) { + function handleDispatchCreateDoc(parentFolderId, doc, _source, userId) { dispatchCreateDoc(parentFolderId, doc) + selectEntityIfCreatedByUser(doc._id, userId) } if (socket) socket.on('reciveNewDoc', handleDispatchCreateDoc) return () => { if (socket) socket.removeListener('reciveNewDoc', handleDispatchCreateDoc) } - }, [socket, dispatchCreateDoc]) + }, [socket, dispatchCreateDoc, selectEntityIfCreatedByUser]) useEffect(() => { - function handleDispatchCreateFile(parentFolderId, file) { + function handleDispatchCreateFile( + parentFolderId, + file, + _source, + _linkedFileData, + userId + ) { dispatchCreateFile(parentFolderId, file) + selectEntityIfCreatedByUser(file._id, userId) } if (socket) socket.on('reciveNewFile', handleDispatchCreateFile) return () => { if (socket) socket.removeListener('reciveNewFile', handleDispatchCreateFile) } - }, [socket, dispatchCreateFile]) + }, [socket, dispatchCreateFile, selectEntityIfCreatedByUser]) } diff --git a/services/web/test/unit/src/Editor/EditorControllerTests.js b/services/web/test/unit/src/Editor/EditorControllerTests.js index 2369e5fef6..361e677453 100644 --- a/services/web/test/unit/src/Editor/EditorControllerTests.js +++ b/services/web/test/unit/src/Editor/EditorControllerTests.js @@ -22,11 +22,13 @@ const modulePath = require('path').join( ) const MockClient = require('../helpers/MockClient') const assert = require('assert') +const { ObjectId } = require('mongodb') describe('EditorController', function() { beforeEach(function() { this.project_id = 'test-project-id' this.source = 'dropbox' + this.user_id = new ObjectId() this.doc = { _id: (this.doc_id = 'test-doc-id') } this.docName = 'doc.tex' @@ -112,7 +114,8 @@ describe('EditorController', function() { 'reciveNewDoc', this.folder_id, this.doc, - this.source + this.source, + this.user_id ) .should.equal(true) }) @@ -160,7 +163,8 @@ describe('EditorController', function() { this.folder_id, this.file, this.source, - this.linkedFileData + this.linkedFileData, + this.user_id ) .should.equal(true) }) @@ -225,7 +229,8 @@ describe('EditorController', function() { 'reciveNewDoc', this.folder_id, this.doc, - this.source + this.source, + this.user_id ) .should.equal(true) }) @@ -291,7 +296,8 @@ describe('EditorController', function() { this.folder_id, this.file, this.source, - this.linkedFileData + this.linkedFileData, + this.user_id ) .should.equal(true) }) @@ -343,7 +349,8 @@ describe('EditorController', function() { 'reciveNewDoc', this.folder_id, this.doc, - this.source + this.source, + this.user_id ) .should.equal(true) }) @@ -442,7 +449,8 @@ describe('EditorController', function() { this.folder_id, this.file, this.source, - this.linkedFileData + this.linkedFileData, + this.user_id ) .should.equal(true) }) @@ -502,6 +510,7 @@ describe('EditorController', function() { this.folder_id, this.folderName, this.source, + this.user_id, this.callback ) }) @@ -513,11 +522,9 @@ describe('EditorController', function() { }) it('should notifyProjectUsersOfNewFolder', function() { - return this.EditorController._notifyProjectUsersOfNewFolder.calledWith( - this.project_id, - this.folder_id, - this.folder - ) + return this.EditorController._notifyProjectUsersOfNewFolder + .calledWith(this.project_id, this.folder_id, this.folder, this.user_id) + .should.equal(true) }) it('should return the folder in the callback', function() {