diff --git a/frontend/src/components/modal/TagRenameDialog.vue b/frontend/src/components/modal/TagRenameDialog.vue index 1bd8c08..750c8eb 100644 --- a/frontend/src/components/modal/TagRenameDialog.vue +++ b/frontend/src/components/modal/TagRenameDialog.vue @@ -2,25 +2,55 @@ Rename tag - - - {{ errorMsg }} -
- Merging two tags into one lands in FC-2c. -
-
+ + +
- Cancel - Rename + +
@@ -35,22 +65,41 @@ const emit = defineEmits(['renamed', 'cancel']) const api = useApi() const newName = ref(props.tag.name) const errorMsg = ref(null) -const isCollision = ref(false) +const collision = ref(null) const busy = ref(false) async function submit() { if (!newName.value.trim() || newName.value === props.tag.name) return busy.value = true errorMsg.value = null - isCollision.value = false try { const updated = await api.patch(`/api/tags/${props.tag.id}`, { body: { name: newName.value.trim() } }) emit('renamed', updated) + } catch (e) { + // 409 → the new name collides with an existing tag of the same + // (kind, fandom). Offer to merge into it rather than dead-ending. + if (e.status === 409 && e.body && e.body.target) { + collision.value = e.body + } else { + errorMsg.value = e.message + } + } finally { + busy.value = false + } +} + +async function onMerge() { + busy.value = true + errorMsg.value = null + try { + await api.post(`/api/tags/${props.tag.id}/merge`, { + body: { target_id: collision.value.target.id } + }) + emit('renamed', { id: collision.value.target.id, name: collision.value.target.name }) } catch (e) { errorMsg.value = e.message - isCollision.value = e.status === 409 } finally { busy.value = false }