|
| 1 | +# 复制链接按钮位置调整 - 更新说明 |
| 2 | + |
| 3 | +## 变更概述 |
| 4 | + |
| 5 | +根据用户反馈,将"复制链接"功能从 **Manage 菜单(⋮)** 移至 **标题旁边的复制按钮** 位置,使其更显眼、更易访问。 |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## 变更前后对比 |
| 10 | + |
| 11 | +### 之前的位置 ❌ |
| 12 | +``` |
| 13 | +标题 [复制按钮] [关注] [...Manage] |
| 14 | + ↓ 点击展开 |
| 15 | + ┌────────────────┐ |
| 16 | + │ 复制名称链接 │ |
| 17 | + │ 复制永久链接 │ |
| 18 | + ├────────────────┤ |
| 19 | + │ Export │ |
| 20 | + │ Rename │ |
| 21 | + └────────────────┘ |
| 22 | +``` |
| 23 | + |
| 24 | +### 现在的位置 ✅ |
| 25 | +``` |
| 26 | +标题 [复制按钮▼] [关注] [...Manage] |
| 27 | + ↓ 点击展开 |
| 28 | + ┌────────────────┐ |
| 29 | + │ 🔗 Copy Name-based Link │ |
| 30 | + │ 📋 Copy Permanent Link │ |
| 31 | + └────────────────┘ |
| 32 | +``` |
| 33 | + |
| 34 | +**优势:** |
| 35 | +- ✅ 更显眼 - 直接在标题旁边 |
| 36 | +- ✅ 更直观 - 符合用户预期(复制按钮就在标题旁边) |
| 37 | +- ✅ 更简洁 - Manage 菜单不再臃肿 |
| 38 | + |
| 39 | +--- |
| 40 | + |
| 41 | +## 修改的文件 |
| 42 | + |
| 43 | +### 1. EntityHeaderTitle.component.tsx |
| 44 | +**位置:** `openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityHeaderTitle/` |
| 45 | + |
| 46 | +**主要变更:** |
| 47 | +- 新增 `entityId` 和 `entityFqn` props |
| 48 | +- 将单一复制按钮改为下拉菜单 |
| 49 | +- 添加两个选项:复制名称链接、复制永久链接 |
| 50 | +- 如果没有 `entityId` 和 `entityFqn`,则显示原始的单一复制按钮(保持向后兼容) |
| 51 | + |
| 52 | +**关键代码:** |
| 53 | +```typescript |
| 54 | +// 新增 props |
| 55 | +interface EntityHeaderTitleProps { |
| 56 | + // ... |
| 57 | + entityId?: string; |
| 58 | + entityFqn?: string; |
| 59 | +} |
| 60 | + |
| 61 | +// 复制逻辑 |
| 62 | +const handleCopyFqnLink = async () => { |
| 63 | + const fqnUrl = `${window.location.origin}/glossary/${encodeURIComponent(entityFqn)}`; |
| 64 | + await navigator.clipboard.writeText(fqnUrl); |
| 65 | + showSuccessToast(t('message.fqn-link-copied')); |
| 66 | +}; |
| 67 | + |
| 68 | +const handleCopyPermanentLink = async () => { |
| 69 | + const permanentUrl = `${window.location.origin}/glossary/${entityId}`; |
| 70 | + await navigator.clipboard.writeText(permanentUrl); |
| 71 | + showSuccessToast(t('message.permanent-link-copied')); |
| 72 | +}; |
| 73 | + |
| 74 | +// 渲染下拉菜单 |
| 75 | +{entityId && entityFqn ? ( |
| 76 | + <Dropdown menu={{ items: [...] }}> |
| 77 | + <Button icon={<Icon component={ShareIcon} />} /> |
| 78 | + </Dropdown> |
| 79 | +) : ( |
| 80 | + <Button onClick={handleShareButtonClick} /> // 原始行为 |
| 81 | +)} |
| 82 | +``` |
| 83 | +
|
| 84 | +### 2. EntityHeaderTitle.interface.ts |
| 85 | +**位置:** `openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityHeaderTitle/` |
| 86 | +
|
| 87 | +**变更:** |
| 88 | +```typescript |
| 89 | +export interface EntityHeaderTitleProps { |
| 90 | + // ... 其他 props |
| 91 | + entityId?: string; // 新增 |
| 92 | + entityFqn?: string; // 新增 |
| 93 | +} |
| 94 | +``` |
| 95 | +
|
| 96 | +### 3. EntityHeader.component.tsx |
| 97 | +**位置:** `openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityHeader/` |
| 98 | +
|
| 99 | +**变更:** |
| 100 | +- 更新 Props interface,添加 `id` 字段 |
| 101 | +- 将 `entityData.id` 和 `entityData.fullyQualifiedName` 传递给 `EntityHeaderTitle` |
| 102 | +
|
| 103 | +```typescript |
| 104 | +interface Props { |
| 105 | + entityData: { |
| 106 | + // ... |
| 107 | + id?: string; // 新增 |
| 108 | + }; |
| 109 | +} |
| 110 | + |
| 111 | +// 传递给 EntityHeaderTitle |
| 112 | +<EntityHeaderTitle |
| 113 | + entityId={entityData.id} |
| 114 | + entityFqn={entityData.fullyQualifiedName} |
| 115 | + // ... 其他 props |
| 116 | +/> |
| 117 | +``` |
| 118 | +
|
| 119 | +### 4. GlossaryHeader.component.tsx |
| 120 | +**位置:** `openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryHeader/` |
| 121 | +
|
| 122 | +**变更:** |
| 123 | +- **移除** `handleCopyFqnLink` 函数 |
| 124 | +- **移除** `handleCopyPermanentLink` 函数 |
| 125 | +- **移除** `copyLinkMenuItems` 数组 |
| 126 | +- **移除** Manage 菜单中的复制链接选项和分隔符 |
| 127 | +- **清理** 不再使用的导入(`LinkIcon`, `CopyIcon`, `showSuccessToast`) |
| 128 | +
|
| 129 | +--- |
| 130 | +
|
| 131 | +## 技术亮点 |
| 132 | +
|
| 133 | +### 1. 向后兼容 ✅ |
| 134 | +```typescript |
| 135 | +{entityId && entityFqn ? ( |
| 136 | + // 新的下拉菜单(用于词汇表术语) |
| 137 | + <Dropdown>...</Dropdown> |
| 138 | +) : ( |
| 139 | + // 原始的单一按钮(用于其他实体) |
| 140 | + <Button onClick={handleShareButtonClick} /> |
| 141 | +)} |
| 142 | +``` |
| 143 | +
|
| 144 | +当 `entityId` 和 `entityFqn` 都存在时,显示下拉菜单;否则保持原始行为。 |
| 145 | +
|
| 146 | +### 2. 复用现有组件 ✅ |
| 147 | +- 使用项目自带的 SVG 图标(`link.svg`, `icon-copy.svg`) |
| 148 | +- 复用现有的翻译文本(`label.copy-fqn-link`, `label.copy-permanent-link`) |
| 149 | +- 沿用 Ant Design 的 `Dropdown` 组件 |
| 150 | +
|
| 151 | +### 3. 最小化侵入性 ✅ |
| 152 | +- 只修改 3 个核心组件 |
| 153 | +- 不影响其他实体类型的复制按钮行为 |
| 154 | +- 保持代码清晰简洁 |
| 155 | +
|
| 156 | +--- |
| 157 | +
|
| 158 | +## UI 效果演示 |
| 159 | +
|
| 160 | +### 点击复制按钮 |
| 161 | +
|
| 162 | +``` |
| 163 | +┌──────────────────────────────────────────┐ |
| 164 | +│ Glossary Term Name [📋▼] [⭐ Follow] │ |
| 165 | +│ ↓ │ |
| 166 | +│ ┌─────────────────────────┐ │ |
| 167 | +│ │ 🔗 Copy Name-based Link│ │ |
| 168 | +│ │ 📋 Copy Permanent Link │ │ |
| 169 | +│ └─────────────────────────┘ │ |
| 170 | +└──────────────────────────────────────────┘ |
| 171 | +``` |
| 172 | +
|
| 173 | +### 点击后的效果 |
| 174 | +- ✅ 显示 Toast 提示:"名称链接已复制到剪贴板" 或 "永久链接已复制到剪贴板" |
| 175 | +- ✅ 下拉菜单自动关闭 |
| 176 | +- ✅ 链接已在剪贴板中,可直接粘贴 |
| 177 | +
|
| 178 | +--- |
| 179 | +
|
| 180 | +## 适用范围 |
| 181 | +
|
| 182 | +### 支持下拉菜单的实体类型 |
| 183 | +- ✅ **Glossary Term** - 词汇表术语(主要使用场景) |
| 184 | +- ⚠️ 其他实体类型 - 需要传递 `entityId` 和 `entityFqn` 才能启用下拉菜单 |
| 185 | +
|
| 186 | +### 保持原始行为的实体类型 |
| 187 | +所有未提供 `entityId` 和 `entityFqn` 的实体类型将继续使用单一复制按钮,复制当前页面 URL。 |
| 188 | +
|
| 189 | +--- |
| 190 | +
|
| 191 | +## 测试验证 |
| 192 | +
|
| 193 | +### 测试步骤 |
| 194 | +
|
| 195 | +1. **启动应用并访问词汇表术语页面** |
| 196 | + ```bash |
| 197 | + cd /workspace/openmetadata-ui/src/main/resources/ui |
| 198 | + yarn build |
| 199 | + cd /workspace |
| 200 | + ./bin/openmetadata-server-start.sh |
| 201 | + ``` |
| 202 | +
|
| 203 | +2. **验证复制按钮位置** |
| 204 | + - 打开任意词汇表术语页面 |
| 205 | + - 确认标题旁边有复制按钮(📋图标) |
| 206 | +
|
| 207 | +3. **验证下拉菜单** |
| 208 | + - 点击复制按钮 |
| 209 | + - 应显示两个选项: |
| 210 | + - 🔗 Copy Name-based Link |
| 211 | + - 📋 Copy Permanent Link |
| 212 | +
|
| 213 | +4. **验证复制名称链接** |
| 214 | + - 点击 "Copy Name-based Link" |
| 215 | + - 验证 Toast 提示:"名称链接已复制到剪贴板" |
| 216 | + - 粘贴到浏览器,验证格式:`/glossary/{fqn}` |
| 217 | +
|
| 218 | +5. **验证复制永久链接** |
| 219 | + - 点击 "Copy Permanent Link" |
| 220 | + - 验证 Toast 提示:"永久链接已复制到剪贴板" |
| 221 | + - 粘贴到浏览器,验证格式:`/glossary/{uuid}` |
| 222 | +
|
| 223 | +6. **验证重命名后的稳定性** |
| 224 | + - 复制术语的永久链接 |
| 225 | + - 重命名术语 |
| 226 | + - 访问之前复制的链接 |
| 227 | + - ✅ 应该仍能正常访问 |
| 228 | +
|
| 229 | +7. **验证 Manage 菜单** |
| 230 | + - 点击 Manage 按钮(⋮) |
| 231 | + - 确认菜单中**不再有**复制链接相关选项 |
| 232 | + - 应直接显示 Export, Rename, Delete 等选项 |
| 233 | +
|
| 234 | +--- |
| 235 | +
|
| 236 | +## 兼容性说明 |
| 237 | +
|
| 238 | +### 浏览器兼容性 |
| 239 | +- ✅ Chrome 66+ |
| 240 | +- ✅ Firefox 63+ |
| 241 | +- ✅ Safari 13.1+ |
| 242 | +- ✅ Edge 79+ |
| 243 | +
|
| 244 | +(基于 `navigator.clipboard.writeText` API 支持) |
| 245 | +
|
| 246 | +### OpenMetadata 版本 |
| 247 | +- 适用于当前版本及后续版本 |
| 248 | +- 不影响现有功能 |
| 249 | +
|
| 250 | +--- |
| 251 | +
|
| 252 | +## 回滚方案 |
| 253 | +
|
| 254 | +如果需要回滚到 Manage 菜单中的实现: |
| 255 | +
|
| 256 | +1. **恢复 GlossaryHeader.component.tsx** |
| 257 | + - 恢复 `handleCopyFqnLink` 和 `handleCopyPermanentLink` 函数 |
| 258 | + - 恢复 `copyLinkMenuItems` 数组 |
| 259 | + - 在 `manageButtonContent` 中添加回链接选项 |
| 260 | +
|
| 261 | +2. **简化 EntityHeaderTitle.component.tsx** |
| 262 | + - 移除下拉菜单逻辑 |
| 263 | + - 恢复单一复制按钮 |
| 264 | +
|
| 265 | +--- |
| 266 | +
|
| 267 | +## 相关文档 |
| 268 | +
|
| 269 | +- [IMPLEMENTATION_SUMMARY.md](/workspace/IMPLEMENTATION_SUMMARY.md) - 完整实施总结 |
| 270 | +- [ICON_FIX_UPDATE.md](/workspace/ICON_FIX_UPDATE.md) - 图标修复说明 |
| 271 | +
|
| 272 | +--- |
| 273 | +
|
| 274 | +## 总结 |
| 275 | +
|
| 276 | +✅ **按钮位置更合理** - 从 Manage 菜单移至标题旁边 |
| 277 | +✅ **用户体验提升** - 更显眼、更易访问 |
| 278 | +✅ **代码更简洁** - GlossaryHeader 代码减少,逻辑更清晰 |
| 279 | +✅ **向后兼容** - 不影响其他实体类型 |
| 280 | +✅ **功能完整** - 两种链接格式都可复制 |
| 281 | +
|
| 282 | +--- |
| 283 | +
|
| 284 | +**更新日期:** 2025-10-28 |
| 285 | +**状态:** ✅ 已完成,待测试验证 |
0 commit comments