From e678d1dfdf55f6f2be806679c24face547a395e7 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Wed, 3 Jun 2026 23:21:25 -0400 Subject: [PATCH] feat(tags): fandom-edit UI in tags directory + image modal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the missing UI to change a character tag's fandom, in both places: - FandomSetDialog (shared): pick an existing fandom, create a new one, or clear it; on a name collision in the target fandom it surfaces a merge confirmation and resolves via setFandom(merge:true). Reuses the tags store's fandom cache. - TagCard kebab gains "Set fandom…" for character tags (→ TagsView opens the dialog, reloads on success). - TagPanel chip kebab gains "Set fandom…" for character tags (→ reloads the modal's tag list on success). - tags store: setFandom(tagId, fandomId, {merge}) action + test. Co-Authored-By: Claude Opus 4.8 (1M context) --- frontend/src/components/discovery/TagCard.vue | 10 +- .../src/components/modal/FandomSetDialog.vue | 128 ++++++++++++++++++ frontend/src/components/modal/TagPanel.vue | 25 ++++ frontend/src/stores/tags.js | 15 +- frontend/src/views/TagsView.vue | 21 +++ frontend/test/tags.spec.js | 61 +++++++++ 6 files changed, 258 insertions(+), 2 deletions(-) create mode 100644 frontend/src/components/modal/FandomSetDialog.vue create mode 100644 frontend/test/tags.spec.js diff --git a/frontend/src/components/discovery/TagCard.vue b/frontend/src/components/discovery/TagCard.vue index 9eb27ad..db7b3df 100644 --- a/frontend/src/components/discovery/TagCard.vue +++ b/frontend/src/components/discovery/TagCard.vue @@ -55,6 +55,12 @@ /> + + + Fandom for “{{ tag.name }}” + + + + + + + + + + + + + + diff --git a/frontend/src/components/modal/TagPanel.vue b/frontend/src/components/modal/TagPanel.vue index 9453592..f1f83dd 100644 --- a/frontend/src/components/modal/TagPanel.vue +++ b/frontend/src/components/modal/TagPanel.vue @@ -28,6 +28,11 @@ Rename… + + Set fandom… + @@ -57,6 +62,13 @@ @renamed="onRenamed" @cancel="renameDialog = false" /> + + + + @@ -67,6 +79,7 @@ import { useTagStore } from '../../stores/tags.js' import TagAutocomplete from './TagAutocomplete.vue' import SuggestionsPanel from './SuggestionsPanel.vue' import TagRenameDialog from './TagRenameDialog.vue' +import FandomSetDialog from './FandomSetDialog.vue' const modal = useModalStore() const store = useTagStore() @@ -107,6 +120,18 @@ async function onRenamed() { // Reflect the new name in the modal's current tag list without a full reload. await modal.reloadTags() } + +const fandomDialog = ref(false) +const fandomTarget = ref(null) +function openSetFandom(tag) { + fandomTarget.value = tag + fandomDialog.value = true +} +async function onFandomUpdated() { + fandomDialog.value = false + // A fandom change can merge the tag away; reload to reflect the new state. + await modal.reloadTags() +}