Skip to content

Commit 5361351

Browse files
authored
Merge pull request #349 from avinxshKD/feat/copy-paste-nodes
feat: add copy/paste support for nodes
2 parents 7181e6e + 7c4d761 commit 5361351

6 files changed

Lines changed: 64 additions & 1 deletion

File tree

src/graph-builder/graph-core/3-component.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,31 @@ class GraphComponent extends GraphCanvas {
267267
}
268268
}
269269

270+
copySelected() {
271+
const selected = this.cy.$('node[type="ordin"]:selected');
272+
return selected.map((node) => ({
273+
label: node.data('label'),
274+
style: this.getStyle(node.id()),
275+
position: { ...node.position() },
276+
}));
277+
}
278+
279+
pasteClipboard(nodes) {
280+
if (!nodes.length) return;
281+
const tid = this.getTid();
282+
nodes.forEach((node) => {
283+
this.addNode(
284+
node.label,
285+
node.style,
286+
'ordin',
287+
{ x: node.position.x + 20, y: node.position.y + 20 },
288+
{},
289+
undefined,
290+
tid,
291+
);
292+
});
293+
}
294+
270295
validiateNode(label, style, id, type) {
271296
if (id) {
272297
const node = this.getById(id);

src/reducer/actionType.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ const actionType = {
4646
SET_LOGS_MESSAGE: 'SET_LOGS_MESSAGE',
4747
SET_GRAPH_INSTANCE: 'SET_GRAPH_INSTANCE',
4848
TOGGLE_DARK_MODE: 'TOGGLE_DARK_MODE',
49+
SET_CLIPBOARD: 'SET_CLIPBOARD',
4950
SET_CONFIRM_MODAL: 'SET_CONFIRM_MODAL',
5051
};
5152

src/reducer/initialState.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ const initialState = {
3939
logs: false,
4040
logsmessage: '',
4141
darkMode: false,
42+
clipboard: [],
4243
confirmModal: { open: false, message: '', onConfirm: null },
4344
};
4445

src/reducer/reducer.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,10 @@ const reducer = (state, action) => {
261261
return { ...state, darkMode: !state.darkMode };
262262
}
263263

264+
case T.SET_CLIPBOARD: {
265+
return { ...state, clipboard: action.payload };
266+
}
267+
264268
default:
265269
return state;
266270
}

src/toolbarActions/toolbarFunctions.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,17 @@ const redo = (state) => {
178178
if (getGraphFun(state)) getGraphFun(state).redo();
179179
};
180180

181+
const copySelected = (state, dispatcher) => {
182+
if (!getGraphFun(state)) return;
183+
const nodes = getGraphFun(state).copySelected();
184+
if (nodes.length) dispatcher({ type: T.SET_CLIPBOARD, payload: nodes });
185+
};
186+
187+
const pasteClipboard = (state) => {
188+
if (!getGraphFun(state) || !state.clipboard.length) return;
189+
getGraphFun(state).pasteClipboard(state.clipboard);
190+
};
191+
181192
const openShareModal = (state, setState) => {
182193
setState({ type: T.SET_SHARE_MODAL, payload: true });
183194
};
@@ -202,5 +213,6 @@ export {
202213
createNode, editElement, deleteElem, downloadImg, saveAction, saveGraphMLFile,
203214
createFile, readFile, readTextFile, newProject, clearAll, editDetails, undo, redo,
204215
openShareModal, openSettingModal, viewHistory, resetAfterClear, toggleLogs,
216+
copySelected, pasteClipboard,
205217
toggleServer, optionModalToggle, contribute,
206218
};

src/toolbarActions/toolbarList.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import {
33
FaSave, FaUndo, FaRedo, FaTrash, FaFileImport, FaPlus, FaDownload, FaEdit, FaRegTimesCircle, FaHistory,
44
FaHammer, FaBug, FaBomb, FaToggleOn, FaThermometerEmpty, FaTrashRestore, FaCogs, FaPencilAlt, FaTerminal,
5+
FaCopy, FaPaste,
56
} from 'react-icons/fa';
67

78
import {
@@ -12,7 +13,7 @@ import {
1213
import {
1314
createNode, editElement, deleteElem, downloadImg, saveAction, saveGraphMLFile,
1415
createFile, readFile, clearAll, undo, redo, viewHistory, resetAfterClear,
15-
toggleServer, optionModalToggle, toggleLogs, contribute,
16+
toggleServer, optionModalToggle, toggleLogs, contribute, copySelected, pasteClipboard,
1617
// openSettingModal,
1718
} from './toolbarFunctions';
1819

@@ -117,6 +118,25 @@ const toolbarList = (state, dispatcher) => [
117118
hotkey: 'Delete,Backspace,Del,Clear',
118119
},
119120
{ type: 'vsep' },
121+
{
122+
type: 'action',
123+
text: 'Copy',
124+
icon: FaCopy,
125+
action: copySelected,
126+
active: state.curGraphInstance && state.eleSelected,
127+
visibility: true,
128+
hotkey: 'Ctrl+C',
129+
},
130+
{
131+
type: 'action',
132+
text: 'Paste',
133+
icon: FaPaste,
134+
action: pasteClipboard,
135+
active: state.curGraphInstance && state.clipboard.length > 0,
136+
visibility: true,
137+
hotkey: 'Ctrl+V',
138+
},
139+
{ type: 'vsep' },
120140
{
121141
type: 'action',
122142
text: 'History',

0 commit comments

Comments
 (0)