New clone option for folders

This commit is contained in:
Jérôme Dathueyt 2023-11-22 20:57:11 +01:00
parent e1e0696e3c
commit c62f96c96e
4 changed files with 69 additions and 43 deletions

View File

@ -306,28 +306,26 @@ const CollectionItem = ({ item, collection, searchText }) => {
> >
Rename Rename
</div> </div>
<div
className="dropdown-item"
onClick={(e) => {
dropdownTippyRef.current.hide();
setCloneItemModalOpen(true);
}}
>
Clone
</div>
{!isFolder && ( {!isFolder && (
<> <div
<div className="dropdown-item"
className="dropdown-item" onClick={(e) => {
onClick={(e) => { dropdownTippyRef.current.hide();
dropdownTippyRef.current.hide(); handleClick(null);
setCloneItemModalOpen(true); handleRun();
}} }}
> >
Clone Run
</div> </div>
<div
className="dropdown-item"
onClick={(e) => {
dropdownTippyRef.current.hide();
handleClick(null);
handleRun();
}}
>
Run
</div>
</>
)} )}
{!isFolder && item.type === 'http-request' && ( {!isFolder && item.type === 'http-request' && (
<div <div

View File

@ -319,7 +319,18 @@ export const cloneItem = (newName, itemUid, collectionUid) => (dispatch, getStat
} }
if (isItemAFolder(item)) { if (isItemAFolder(item)) {
throw new Error('Cloning folders is not supported yet'); const folderWithSameNameExists = find(
collection.items,
(i) => i.type === 'folder' && trim(i.name) === trim(newName)
);
if (folderWithSameNameExists) {
return reject(new Error('Duplicate folder names under same parent folder are not allowed'));
}
const collectionPath = `${collection.pathname}${PATH_SEPARATOR}${newName}`;
ipcRenderer.invoke('renderer:clone-folder', newName, item, collectionPath).then(resolve).catch(reject);
return;
} }
const parentItem = findParentItemInCollection(collectionCopy, itemUid); const parentItem = findParentItemInCollection(collectionCopy, itemUid);

View File

@ -12,7 +12,8 @@ const {
browseDirectory, browseDirectory,
createDirectory, createDirectory,
searchForBruFiles, searchForBruFiles,
sanitizeDirectoryName sanitizeDirectoryName,
parseCollectionItems
} = require('../utils/filesystem'); } = require('../utils/filesystem');
const { stringifyJson } = require('../utils/common'); const { stringifyJson } = require('../utils/common');
const { openCollectionDialog } = require('../app/collections'); const { openCollectionDialog } = require('../app/collections');
@ -335,25 +336,6 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
throw new Error(`collection: ${collectionPath} already exists`); throw new Error(`collection: ${collectionPath} already exists`);
} }
// Recursive function to parse the collection items and create files/folders
const parseCollectionItems = (items = [], currentPath) => {
items.forEach((item) => {
if (['http-request', 'graphql-request'].includes(item.type)) {
const content = jsonToBru(item);
const filePath = path.join(currentPath, `${item.name}.bru`);
fs.writeFileSync(filePath, content);
}
if (item.type === 'folder') {
const folderPath = path.join(currentPath, item.name);
fs.mkdirSync(folderPath);
if (item.items && item.items.length) {
parseCollectionItems(item.items, folderPath);
}
}
});
};
const parseEnvironments = (environments = [], collectionPath) => { const parseEnvironments = (environments = [], collectionPath) => {
const envDirPath = path.join(collectionPath, 'environments'); const envDirPath = path.join(collectionPath, 'environments');
if (!fs.existsSync(envDirPath)) { if (!fs.existsSync(envDirPath)) {
@ -391,6 +373,21 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
} }
}); });
ipcMain.handle('renderer:clone-folder', async (event, itemFolder, collectionPath) => {
try {
if (fs.existsSync(collectionPath)) {
throw new Error(`folder: ${collectionPath} already exists`);
}
await createDirectory(collectionPath);
// create folder and files based on another folder
await parseCollectionItems(itemFolder.items, collectionPath);
} catch (error) {
return Promise.reject(error);
}
});
ipcMain.handle('renderer:resequence-items', async (event, itemsToResequence) => { ipcMain.handle('renderer:resequence-items', async (event, itemsToResequence) => {
try { try {
for (let item of itemsToResequence) { for (let item of itemsToResequence) {

View File

@ -134,6 +134,25 @@ const sanitizeDirectoryName = (name) => {
return name.replace(/[<>:"/\\|?*\x00-\x1F]+/g, '-'); return name.replace(/[<>:"/\\|?*\x00-\x1F]+/g, '-');
}; };
// Recursive function to parse the folder and create files/folders
const parseCollectionItems = (items = [], currentPath) => {
items.forEach((item) => {
if (['http-request', 'graphql-request'].includes(item.type)) {
const content = jsonToBru(item);
const filePath = path.join(currentPath, `${item.name}.bru`);
fs.writeFileSync(filePath, content);
}
if (item.type === 'folder') {
const folderPath = path.join(currentPath, item.name);
fs.mkdirSync(folderPath);
if (item.items && item.items.length) {
parseCollectionItems(item.items, folderPath);
}
}
});
};
module.exports = { module.exports = {
isValidPathname, isValidPathname,
exists, exists,
@ -150,5 +169,6 @@ module.exports = {
chooseFileToSave, chooseFileToSave,
searchForFiles, searchForFiles,
searchForBruFiles, searchForBruFiles,
sanitizeDirectoryName sanitizeDirectoryName,
parseCollectionItems
}; };