Skip to content

Commit a3ce8aa

Browse files
committed
[Feature request] Keyboard shortcut to duplicate and rename request/collection. usebruno#1610
1 parent 2cd0e06 commit a3ce8aa

File tree

2 files changed

+65
-2
lines changed

2 files changed

+65
-2
lines changed

packages/bruno-app/src/providers/Hotkeys/index.js

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import NetworkError from 'components/ResponsePane/NetworkError';
99
import NewRequest from 'components/Sidebar/NewRequest';
1010
import { sendRequest, saveRequest } from 'providers/ReduxStore/slices/collections/actions';
1111
import { findCollectionByUid, findItemInCollection } from 'utils/collections';
12-
import { closeTabs } from 'providers/ReduxStore/slices/tabs';
12+
import { closeTabs, cloneRequest, renameRequest } from 'providers/ReduxStore/slices/tabs';
1313

1414
export const HotkeysContext = React.createContext();
1515

@@ -154,6 +154,50 @@ export const HotkeysProvider = (props) => {
154154
};
155155
}, [activeTabUid]);
156156

157+
// clone request (ctrl/cmd + d)
158+
useEffect(() => {
159+
Mousetrap.bind(['command+d', 'ctrl+d'], (e) => {
160+
const activeTab = find(tabs, (t) => t.uid === activeTabUid);
161+
if (activeTab) {
162+
const collection = findCollectionByUid(collections, activeTab.collectionUid);
163+
if (collection) {
164+
const item = findItemInCollection(collection, activeTab.uid);
165+
if (item && item.uid) {
166+
dispatch(cloneRequest(item.uid, activeTab.collectionUid));
167+
}
168+
}
169+
}
170+
171+
return false; // this stops the event bubbling
172+
});
173+
174+
return () => {
175+
Mousetrap.unbind(['command+d', 'ctrl+d']);
176+
};
177+
}, [activeTabUid, tabs, collections]);
178+
179+
// rename request (ctrl/cmd + e)
180+
useEffect(() => {
181+
Mousetrap.bind(['command+e', 'ctrl+e'], (e) => {
182+
const activeTab = find(tabs, (t) => t.uid === activeTabUid);
183+
if (activeTab) {
184+
const collection = findCollectionByUid(collections, activeTab.collectionUid);
185+
if (collection) {
186+
const item = findItemInCollection(collection, activeTab.uid);
187+
if (item && item.uid) {
188+
dispatch(renameRequest(item.uid, activeTab.collectionUid));
189+
}
190+
}
191+
}
192+
193+
return false; // this stops the event bubbling
194+
});
195+
196+
return () => {
197+
Mousetrap.unbind(['command+e', 'ctrl+e']);
198+
};
199+
}, [activeTabUid, tabs, collections]);
200+
157201
return (
158202
<HotkeysContext.Provider {...props} value="hotkey">
159203
{showSaveRequestModal && (

packages/bruno-app/src/providers/ReduxStore/slices/tabs.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,23 @@ export const tabsSlice = createSlice({
101101
const collectionUid = action.payload.collectionUid;
102102
state.tabs = filter(state.tabs, (t) => t.collectionUid !== collectionUid);
103103
state.activeTabUid = null;
104+
},
105+
cloneRequest: (state, action) => {
106+
const { requestId, collectionId } = action.payload;
107+
const tab = find(state.tabs, (t) => t.uid === requestId && t.collectionUid === collectionId);
108+
109+
if (tab) {
110+
const clonedTab = { ...tab, uid: action.payload.uid };
111+
state.tabs.push(clonedTab);
112+
}
113+
},
114+
renameRequest: (state, action) => {
115+
const { requestId, collectionId, newName } = action.payload;
116+
const tab = find(state.tabs, (t) => t.uid === requestId && t.collectionUid === collectionId);
117+
118+
if (tab) {
119+
tab.name = newName;
120+
}
104121
}
105122
}
106123
});
@@ -112,7 +129,9 @@ export const {
112129
updateRequestPaneTab,
113130
updateResponsePaneTab,
114131
closeTabs,
115-
closeAllCollectionTabs
132+
closeAllCollectionTabs,
133+
cloneRequest,
134+
renameRequest
116135
} = tabsSlice.actions;
117136

118137
export default tabsSlice.reducer;

0 commit comments

Comments
 (0)