Add copy/paste specific attributes for nodes and edges#1316
Add copy/paste specific attributes for nodes and edges#1316
Conversation
Co-authored-by: thekingofcity <3353040+thekingofcity@users.noreply.github.com>
Co-authored-by: thekingofcity <3353040+thekingofcity@users.noreply.github.com>
thekingofcity
left a comment
There was a problem hiding this comment.
@copilot 有两个问题
第一,粘贴特殊属性的时候,一定要确保当前的节点类型和剪贴板中的一致。对于线段,只要确保style一致即可,对于roundedCornerFactor,只要path有这个属性就能粘贴。
第二,特殊属性的剪贴板中要包含当前的存档版本,如果粘贴时发现存档版本saveVersion不一致,那么有可能即使类型相同特殊属性也不同,那么就不能粘贴。特殊属性的剪贴板数据中还要包含固定的version编号,以确保特殊属性的格式没变但是剪贴板的数据格式变了的情况,粘贴时也要检查。同理,之前就有的复制粘贴节点和线段的功能,除了version外还要保存saveVersion确保数据格式一致,那么type?就没必要可能undefined了,因为我们不向后兼容。
Co-authored-by: thekingofcity <3353040+thekingofcity@users.noreply.github.com>
…eview Co-authored-by: thekingofcity <3353040+thekingofcity@users.noreply.github.com>
Fixed in commits e7adc5d and a977d8e:
|
|
@copilot 用户应该可以通过快捷键ctrl+shift+c/v拷贝或粘贴独特属性,并且在设置的快捷键提示中一并标明。另外我还注意到有些地方的本地化文本没有准备好,比如panel.details.footer.copyAttrs,并且翻译时保留现有的独特前缀为独特属性而非单独的属性。 |
…pdate translations Co-authored-by: thekingofcity <3353040+thekingofcity@users.noreply.github.com>
Fixed in commit 74217ed:
|
; Conflicts: ; src/components/context-menu.tsx ; src/i18n/translations/en.json ; src/i18n/translations/ja.json ; src/i18n/translations/ko.json ; src/i18n/translations/zh-Hans.json ; src/i18n/translations/zh-Hant.json
There was a problem hiding this comment.
Pull request overview
This PR adds the ability to copy and paste specific attributes for nodes and edges in the Rail Map Painter application. Users can now copy type-specific attributes (e.g., station names, line colors) from one element and apply them to multiple elements of the same type, separate from copying the entire element.
Changes:
- Added clipboard data types and versioning system for specific attribute copy/paste operations
- Implemented keyboard shortcuts (Ctrl+Shift+C/V or Cmd+Shift+C/V) for copying and pasting specific attributes
- Added UI buttons in the details panel and context menu for specific attribute operations
- Added comprehensive unit tests for the new clipboard utility functions
- Updated all language translations (English, Chinese Simplified, Chinese Traditional, Japanese, Korean) with new UI labels
Reviewed changes
Copilot reviewed 11 out of 12 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/util/clipboard.ts | Core implementation of specific attribute export/import functions, clipboard data types, version validation, and helper utilities |
| src/util/clipboard.test.ts | Comprehensive unit tests covering all new clipboard functions with version validation |
| src/components/svg-wrapper.tsx | Keyboard shortcuts (Ctrl+Shift+C/V) for copy/paste specific attributes |
| src/components/panels/details/details.tsx | Added buttons in details panel footer for copy/paste specific attributes |
| src/components/context-menu.tsx | Added menu items for copy/paste specific attributes in the context menu |
| src/components/page-header/settings-modal.tsx | Updated keyboard shortcuts documentation with new shortcuts |
| src/i18n/translations/*.json | Added translations for new UI elements across all 5 supported languages |
| package-lock.json | Dependency lock file updates (peer dependency flag changes, likely from npm version update) |
| const parsed = JSON.parse(result) as NodeSpecificAttrsClipboardData; | ||
|
|
||
| expect(parsed.app).toBe('rmp'); | ||
| expect(parsed.version).toBe(1); |
There was a problem hiding this comment.
The test should verify the version using the CLIPBOARD_VERSION constant instead of the hardcoded value 1. This ensures the test remains correct if the clipboard version is incremented in the future. Change this to expect(parsed.version).toBe(CLIPBOARD_VERSION);
| expect(parsed.version).toBe(1); | |
| expect(parsed.version).toBe(CLIPBOARD_VERSION); |
| const parsed = JSON.parse(result) as EdgeSpecificAttrsClipboardData; | ||
|
|
||
| expect(parsed.app).toBe('rmp'); | ||
| expect(parsed.version).toBe(1); |
There was a problem hiding this comment.
The test should verify the version using the CLIPBOARD_VERSION constant instead of the hardcoded value 1. This ensures the test remains correct if the clipboard version is incremented in the future. Change this to expect(parsed.version).toBe(CLIPBOARD_VERSION);
| expect(parsed.version).toBe(1); | |
| expect(parsed.version).toBe(CLIPBOARD_VERSION); |
| const allElements = structuredClone(nodes) as Set<Id>; | ||
| edges.forEach(s => allElements.add(s)); | ||
| dispatch(setSelected(allElements)); | ||
| } else if (e.key === 'C' && (isMacClient ? e.metaKey && e.shiftKey : e.ctrlKey && e.shiftKey)) { |
There was a problem hiding this comment.
The keyboard shortcut implementation is inconsistent with the existing pattern in this file. Line 386 uses lowercase 'z' with an explicit shiftKey check for the Cmd+Shift+Z shortcut. For consistency with the codebase conventions, consider using lowercase 'c' here: e.key === 'c' && (isMacClient ? e.metaKey && e.shiftKey : e.ctrlKey && e.shiftKey). Note that using uppercase 'C' is technically more correct according to the KeyboardEvent spec, but lowercase with explicit shiftKey check matches the existing pattern in this file.
| navigator.clipboard.writeText(s); | ||
| } | ||
| } | ||
| } else if (e.key === 'V' && (isMacClient ? e.metaKey && e.shiftKey : e.ctrlKey && e.shiftKey)) { |
There was a problem hiding this comment.
The keyboard shortcut implementation is inconsistent with the existing pattern in this file. Line 386 uses lowercase 'z' with an explicit shiftKey check for the Cmd+Shift+Z shortcut. For consistency with the codebase conventions, consider using lowercase 'v' here: e.key === 'v' && (isMacClient ? e.metaKey && e.shiftKey : e.ctrlKey && e.shiftKey). Note that using uppercase 'V' is technically more correct according to the KeyboardEvent spec, but lowercase with explicit shiftKey check matches the existing pattern in this file.
| ExternalLinePathAttributes, | ||
| ExternalLineStyleAttributes, |
There was a problem hiding this comment.
Unused imports ExternalLinePathAttributes, ExternalLineStyleAttributes.
| ExternalLinePathAttributes, | |
| ExternalLineStyleAttributes, |

saveVersionfield to all clipboard data typesCLIPBOARD_VERSIONconstant for clipboard format versioningtypefield non-optional (no backward compatibility)versionandsaveVersionon pastecopyAttrstranslation key in panel.details.footerSummary of Changes
Keyboard shortcuts (
src/components/svg-wrapper.tsx)Settings shortcuts documentation (
src/components/page-header/settings-modal.tsx)Translations (all 5 language files)
copyAttrskey inpanel.details.footerScreenshots
Keyboard shortcuts in settings:

Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.