From 267740d4c84c653a029114bc6bf2ec80fcfdf79e Mon Sep 17 00:00:00 2001 From: Ku7eKam Date: Sun, 13 Apr 2025 15:15:10 +0530 Subject: [PATCH 1/5] fix issue #3454: file-renaming via double click --- client/modules/IDE/components/FileNode.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/client/modules/IDE/components/FileNode.jsx b/client/modules/IDE/components/FileNode.jsx index 3c84d31196..9e15009521 100644 --- a/client/modules/IDE/components/FileNode.jsx +++ b/client/modules/IDE/components/FileNode.jsx @@ -271,6 +271,7 @@ const FileNode = ({ aria-label={updatedName} className="sidebar__file-item-name" onClick={handleFileClick} + onDoubleClick={handleClickRename} data-testid="file-name" > From b50aafa58387f260467f09ed026aba520c5ec63a Mon Sep 17 00:00:00 2001 From: Ku7eKam Date: Wed, 16 Apr 2025 17:33:19 +0530 Subject: [PATCH 2/5] Fixes issue #3456: prevents renaming a file to an existing sibling file --- client/modules/IDE/components/FileNode.jsx | 30 +++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/client/modules/IDE/components/FileNode.jsx b/client/modules/IDE/components/FileNode.jsx index 9e15009521..cb872eb982 100644 --- a/client/modules/IDE/components/FileNode.jsx +++ b/client/modules/IDE/components/FileNode.jsx @@ -3,6 +3,7 @@ import classNames from 'classnames'; import React, { useState, useRef } from 'react'; import { connect } from 'react-redux'; import { useTranslation } from 'react-i18next'; +import { useSelector } from 'react-redux'; import * as IDEActions from '../actions/ide'; import * as FileActions from '../actions/files'; @@ -88,6 +89,24 @@ const FileNode = ({ const [isDeleting, setIsDeleting] = useState(false); const [updatedName, setUpdatedName] = useState(name); + const files = useSelector((state) => state.files); + + const checkDuplicate = (newName) => { + const parentFolder = files.find((f) => f.id === parentId); + if (!parentFolder) return false; + + const siblingFiles = parentFolder.children + .map((childId) => files.find((f) => f.id === childId)) + .filter(Boolean) + .filter((file) => file.id !== id); + + const isDuplicate = siblingFiles.some( + (f) => f.name.trim().toLowerCase() === newName.trim().toLowerCase() + ); + + return isDuplicate; + }; + const { t } = useTranslation(); const fileNameInput = useRef(null); const fileOptionsRef = useRef(null); @@ -157,7 +176,7 @@ const FileNode = ({ }; const saveUpdatedFileName = () => { - if (updatedName !== name) { + if (!checkDuplicate(updatedName) && updatedName !== name) { updateFileName(id, updatedName); } }; @@ -198,8 +217,13 @@ const FileNode = ({ }; const handleFileNameBlur = () => { - validateFileName(); - hideEditFileName(); + if (!checkDuplicate(updatedName)) { + validateFileName(); + hideEditFileName(); + } else { + setUpdatedName(name); + hideEditFileName(); + } }; const toggleFileOptions = (event) => { From 122021117ed74d3458adb9abe1ee08a8dd58b47a Mon Sep 17 00:00:00 2001 From: Ku7eKam Date: Wed, 16 Apr 2025 18:29:34 +0530 Subject: [PATCH 3/5] updated test file for FileNode.jsx --- .../IDE/components/FileNode.unit.test.jsx | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/client/modules/IDE/components/FileNode.unit.test.jsx b/client/modules/IDE/components/FileNode.unit.test.jsx index 8676a817d8..e162e424f6 100644 --- a/client/modules/IDE/components/FileNode.unit.test.jsx +++ b/client/modules/IDE/components/FileNode.unit.test.jsx @@ -1,4 +1,7 @@ import React from 'react'; +import { Provider } from 'react-redux'; +import configureStore from 'redux-mock-store'; +import thunk from 'redux-thunk'; import { fireEvent, @@ -9,6 +12,8 @@ import { } from '../../../test-utils'; import { FileNode } from './FileNode'; +const mockStore = configureStore([thunk]); + describe('', () => { const changeName = (newFileName) => { const renameButton = screen.getByText(/Rename/i); @@ -45,7 +50,20 @@ describe('', () => { setProjectName: jest.fn() }; - render(); + const mockFiles = [ + { id: '0', name: props.name, parentId: null }, + { id: '1', name: 'sketch.js', parentId: '0', isSelectedFile: true } + ]; + + const store = mockStore({ + files: mockFiles + }); + + render( + + + + ); return props; }; From 3bd84eca507fb906f1c2b3d01eff49c30280f1a9 Mon Sep 17 00:00:00 2001 From: Ku7eKam Date: Wed, 16 Apr 2025 18:40:42 +0530 Subject: [PATCH 4/5] updated test file for FileNode.jsx --- .../IDE/components/FileNode.unit.test.jsx | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/client/modules/IDE/components/FileNode.unit.test.jsx b/client/modules/IDE/components/FileNode.unit.test.jsx index e162e424f6..81a74e3921 100644 --- a/client/modules/IDE/components/FileNode.unit.test.jsx +++ b/client/modules/IDE/components/FileNode.unit.test.jsx @@ -51,8 +51,28 @@ describe('', () => { }; const mockFiles = [ - { id: '0', name: props.name, parentId: null }, - { id: '1', name: 'sketch.js', parentId: '0', isSelectedFile: true } + { + id: '0', + name: props.name, + parentId: 'parent-folder-id' + }, + { + id: '1', + name: 'sketch.js', + parentId: '0', + isSelectedFile: true + }, + { + id: 'parent-folder-id', + name: 'parent', + parentId: null, + children: ['0', 'some-other-file-id'] + }, + { + id: 'some-other-file-id', + name: 'duplicate.js', + parentId: 'parent-folder-id' + } ]; const store = mockStore({ From 38f886c9a589051f5821a72a09b79bf06eeaba6f Mon Sep 17 00:00:00 2001 From: Ku7eKam Date: Wed, 16 Apr 2025 18:51:37 +0530 Subject: [PATCH 5/5] updated test file for FileNode.jsx --- client/modules/IDE/components/FileNode.unit.test.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/client/modules/IDE/components/FileNode.unit.test.jsx b/client/modules/IDE/components/FileNode.unit.test.jsx index 81a74e3921..0c9fd6fb5a 100644 --- a/client/modules/IDE/components/FileNode.unit.test.jsx +++ b/client/modules/IDE/components/FileNode.unit.test.jsx @@ -37,6 +37,7 @@ describe('', () => { fileType, canEdit: true, children: [], + parentId: 'parent-folder-id', authenticated: false, setSelectedFile: jest.fn(), deleteFile: jest.fn(),