feat: [planning-design] 블록 Ctrl+C/V 복사 붙여넣기 및 Delete 삭제
- Ctrl+C: 선택된 블록 클립보드 복사 - Ctrl+V: 클립보드 블록 붙여넣기 (24px 오프셋) - Delete/Backspace: 선택된 블록 삭제 - 연속 Ctrl+V 시 오프셋 누적으로 겹침 방지
This commit is contained in:
@@ -1961,6 +1961,7 @@ function planningCanvas() {
|
|||||||
_sbBlockDragIdx: null,
|
_sbBlockDragIdx: null,
|
||||||
_sbDrag: null, // { blk, startX, startY, origX, origY }
|
_sbDrag: null, // { blk, startX, startY, origX, origY }
|
||||||
_sbResize: null, // { blk, dir, startX, startY, origW, origH }
|
_sbResize: null, // { blk, dir, startX, startY, origW, origH }
|
||||||
|
_sbClipboard: null, // copied block data
|
||||||
sbTplOpen: false,
|
sbTplOpen: false,
|
||||||
sbTplTab: 'preset',
|
sbTplTab: 'preset',
|
||||||
sbTplSearch: '',
|
sbTplSearch: '',
|
||||||
@@ -2760,6 +2761,31 @@ function planningCanvas() {
|
|||||||
if ((e.ctrlKey || e.metaKey) && e.key === 'y') { e.preventDefault(); this.redoAction(); }
|
if ((e.ctrlKey || e.metaKey) && e.key === 'y') { e.preventDefault(); this.redoAction(); }
|
||||||
if ((e.ctrlKey || e.metaKey) && e.key === 's') { e.preventDefault(); this.saveProject(); }
|
if ((e.ctrlKey || e.metaKey) && e.key === 's') { e.preventDefault(); this.saveProject(); }
|
||||||
if ((e.ctrlKey || e.metaKey) && e.key === 'd') { e.preventDefault(); this.duplicateNode(); }
|
if ((e.ctrlKey || e.metaKey) && e.key === 'd') { e.preventDefault(); this.duplicateNode(); }
|
||||||
|
// 스토리보드 블록 Ctrl+C / Ctrl+V / Delete
|
||||||
|
if (this.viewMode === 'storyboard' && this.sbSelectedBlock) {
|
||||||
|
if ((e.ctrlKey || e.metaKey) && (e.key === 'c' || e.key === 'C')) {
|
||||||
|
e.preventDefault();
|
||||||
|
this.sbCopyBlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((e.ctrlKey || e.metaKey) && (e.key === 'v' || e.key === 'V')) {
|
||||||
|
e.preventDefault();
|
||||||
|
this.sbPasteBlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (e.key === 'Delete' || e.key === 'Backspace') {
|
||||||
|
e.preventDefault();
|
||||||
|
this.sbDeleteSelectedBlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.viewMode === 'storyboard' && !this.sbSelectedBlock) {
|
||||||
|
if ((e.ctrlKey || e.metaKey) && (e.key === 'v' || e.key === 'V') && this._sbClipboard) {
|
||||||
|
e.preventDefault();
|
||||||
|
this.sbPasteBlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
if ((e.ctrlKey || e.metaKey) && e.key === 'f') {
|
if ((e.ctrlKey || e.metaKey) && e.key === 'f') {
|
||||||
if (this.viewMode === 'kanban' || this.viewMode === 'list') {
|
if (this.viewMode === 'kanban' || this.viewMode === 'list') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -2990,6 +3016,39 @@ function planningCanvas() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
sbCopyBlock() {
|
||||||
|
const page = this.sbCurrentPage;
|
||||||
|
if (!page || !page.blocks) return;
|
||||||
|
const blk = page.blocks.find(b => b.id === this.sbSelectedBlock);
|
||||||
|
if (!blk) return;
|
||||||
|
this._sbClipboard = JSON.parse(JSON.stringify(blk));
|
||||||
|
},
|
||||||
|
|
||||||
|
sbPasteBlock() {
|
||||||
|
if (!this._sbClipboard) return;
|
||||||
|
const page = this.sbCurrentPage;
|
||||||
|
if (!page) return;
|
||||||
|
if (!page.blocks) page.blocks = [];
|
||||||
|
const copy = JSON.parse(JSON.stringify(this._sbClipboard));
|
||||||
|
copy.id = 'blk_' + Date.now() + '_' + Math.random().toString(36).slice(2, 5);
|
||||||
|
copy.x = (copy.x || 0) + 24;
|
||||||
|
copy.y = (copy.y || 0) + 24;
|
||||||
|
page.blocks.push(copy);
|
||||||
|
this.sbSelectedBlock = copy.id;
|
||||||
|
this._sbClipboard = copy; // 연속 붙여넣기 시 오프셋 누적
|
||||||
|
this.autoSave();
|
||||||
|
},
|
||||||
|
|
||||||
|
sbDeleteSelectedBlock() {
|
||||||
|
const page = this.sbCurrentPage;
|
||||||
|
if (!page || !page.blocks) return;
|
||||||
|
const idx = page.blocks.findIndex(b => b.id === this.sbSelectedBlock);
|
||||||
|
if (idx < 0) return;
|
||||||
|
page.blocks.splice(idx, 1);
|
||||||
|
this.sbSelectedBlock = null;
|
||||||
|
this.autoSave();
|
||||||
|
},
|
||||||
|
|
||||||
sbTableAddRow(blk) {
|
sbTableAddRow(blk) {
|
||||||
const colCount = blk.cols.length;
|
const colCount = blk.cols.length;
|
||||||
blk.rows.push(Array(colCount).fill(''));
|
blk.rows.push(Array(colCount).fill(''));
|
||||||
|
|||||||
Reference in New Issue
Block a user