From 8038da9107098251811330783300388e2cc6c2de Mon Sep 17 00:00:00 2001 From: Daniel Nitsikopoulos Date: Sun, 7 May 2023 22:15:37 +1000 Subject: [PATCH] Tag merging UI --- config/routes.rb | 4 ++++ slices/admin/actions/merge_tags/index.rb | 14 +++++++++++ slices/admin/actions/merge_tags/merge.rb | 24 +++++++++++++++++++ slices/admin/actions/merge_tags/new.rb | 14 +++++++++++ slices/admin/commands/merge_tags/merge.rb | 17 +++++++++++++ slices/admin/repos/post_tag_repo.rb | 6 +++++ slices/admin/repos/tag_repo.rb | 4 ++++ .../templates/auto_tagging/index.html.slim | 2 +- .../templates/auto_tagging/new.html.slim | 9 ++++--- slices/admin/templates/index.html.slim | 2 ++ .../templates/merge_tags/index.html.slim | 11 +++++++++ .../admin/templates/merge_tags/new.html.slim | 19 +++++++++++++++ slices/admin/views/merge_tags/index.rb | 14 +++++++++++ slices/admin/views/merge_tags/new.rb | 18 ++++++++++++++ 14 files changed, 154 insertions(+), 4 deletions(-) create mode 100644 slices/admin/actions/merge_tags/index.rb create mode 100644 slices/admin/actions/merge_tags/merge.rb create mode 100644 slices/admin/actions/merge_tags/new.rb create mode 100644 slices/admin/commands/merge_tags/merge.rb create mode 100644 slices/admin/templates/merge_tags/index.html.slim create mode 100644 slices/admin/templates/merge_tags/new.html.slim create mode 100644 slices/admin/views/merge_tags/index.rb create mode 100644 slices/admin/views/merge_tags/new.rb diff --git a/config/routes.rb b/config/routes.rb index 8d16a16..eae9be4 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -66,6 +66,10 @@ module Adamantium post "/tags/auto_tagging", to: "auto_tagging.create" delete "/tags/auto_taggings/:id", to: "auto_tagging.delete" + get "/tags/merge", to: "merge_tags.index" + get "/tags/merge/:id", to: "merge_tags.new" + post "/tags/merge", to: "merge_tags.merge" + get "/bookmarks", to: "bookmarks.index" delete "/bookmarks/:id", to: "bookmarks.delete" post "/bookmarks/cache/:id", to: "bookmarks.cache" diff --git a/slices/admin/actions/merge_tags/index.rb b/slices/admin/actions/merge_tags/index.rb new file mode 100644 index 0000000..7f0b014 --- /dev/null +++ b/slices/admin/actions/merge_tags/index.rb @@ -0,0 +1,14 @@ +module Admin + module Actions + module MergeTags + class Index < Action + + include Deps["views.merge_tags.index"] + + def handle(req, res) + res.render index + end + end + end + end +end \ No newline at end of file diff --git a/slices/admin/actions/merge_tags/merge.rb b/slices/admin/actions/merge_tags/merge.rb new file mode 100644 index 0000000..3549724 --- /dev/null +++ b/slices/admin/actions/merge_tags/merge.rb @@ -0,0 +1,24 @@ +module Admin + module Actions + module MergeTags + class Merge < Action + + include Deps["commands.merge_tags.merge"] + + def handle(req, res) + target_id = req.params[:target_id] + source_id = req.params[:source_id] + + result = merge.(target_id: target_id, source_id: source_id) + + if result.success? + res.redirect_to "/admin/tags/merge" + res.status 200 + else + res.status 500 + end + end + end + end + end +end \ No newline at end of file diff --git a/slices/admin/actions/merge_tags/new.rb b/slices/admin/actions/merge_tags/new.rb new file mode 100644 index 0000000..5e0bcdc --- /dev/null +++ b/slices/admin/actions/merge_tags/new.rb @@ -0,0 +1,14 @@ +module Admin + module Actions + module MergeTags + class New < Action + + include Deps[new_view: "views.merge_tags.new"] + + def handle(req, res) + res.render new_view, id: req.params[:id] + end + end + end + end +end \ No newline at end of file diff --git a/slices/admin/commands/merge_tags/merge.rb b/slices/admin/commands/merge_tags/merge.rb new file mode 100644 index 0000000..b3afcb5 --- /dev/null +++ b/slices/admin/commands/merge_tags/merge.rb @@ -0,0 +1,17 @@ +module Admin + module Commands + module MergeTags + class Merge + include Dry::Monads[:result] + include Deps["repos.post_tag_repo", "repos.tag_repo"] + + def call(target_id:, source_id:) + post_tag_repo.merge_tags(target_id: target_id, source_id: source_id) + tag_repo.delete(tag_id: source_id) + + Success() + end + end + end + end +end diff --git a/slices/admin/repos/post_tag_repo.rb b/slices/admin/repos/post_tag_repo.rb index 39f687d..1432a56 100644 --- a/slices/admin/repos/post_tag_repo.rb +++ b/slices/admin/repos/post_tag_repo.rb @@ -1,7 +1,13 @@ +require 'pry' + module Admin module Repos class PostTagRepo < Adamantium::Repo[:post_tags] + def merge_tags(target_id:, source_id:) + post_tags.where(tag_id: source_id).update(tag_id: target_id) + end + def delete(tag_id:) post_tags.where(tag_id: tag_id).delete end diff --git a/slices/admin/repos/tag_repo.rb b/slices/admin/repos/tag_repo.rb index 86d6c0f..56b39a0 100644 --- a/slices/admin/repos/tag_repo.rb +++ b/slices/admin/repos/tag_repo.rb @@ -16,6 +16,10 @@ module Admin def delete(tag_id:) tags.by_pk(tag_id).delete end + + def fetch(id) + tags.by_pk(id).one + end end end end diff --git a/slices/admin/templates/auto_tagging/index.html.slim b/slices/admin/templates/auto_tagging/index.html.slim index 0e3c5a2..6d2443b 100644 --- a/slices/admin/templates/auto_tagging/index.html.slim +++ b/slices/admin/templates/auto_tagging/index.html.slim @@ -6,6 +6,6 @@ div class="prose dark:prose-invert max-w-prose mx-auto mb-12" div id="auto-tag-#{auto_tagging.id}" class="mb-2" == "Tag post with #{auto_tagging.tag.label} when #{auto_tagging.title_only? ? "title" : "content"} contains #{auto_tagging.term}" = " — " - button hx-delete="/admin/tags/auto_taggings/#{auto_tagging.id}" hx-target="#auto-tag-#{auto_tagging.id}" delete + button class="text-red-600 hover:text-red-400" hx-delete="/admin/tags/auto_taggings/#{auto_tagging.id}" hx-target="#auto-tag-#{auto_tagging.id}" delete a class="bg-blue-100 text-blue-600 p-1 rounded no-underline" href="/admin/tags/auto_tagging/new" New div class="max-w-screen-md mx-auto border-t-4 border-solid border-gray-400 dark:border-gray-600" diff --git a/slices/admin/templates/auto_tagging/new.html.slim b/slices/admin/templates/auto_tagging/new.html.slim index 3b3b0a9..71e2df5 100644 --- a/slices/admin/templates/auto_tagging/new.html.slim +++ b/slices/admin/templates/auto_tagging/new.html.slim @@ -10,19 +10,22 @@ div class="max-w-prose mx-auto" form method="POST" action="/admin/tags/auto_tagging" div class="mb-4" - label class="text-gray-800 dark:text-gray-200" for="title_contains" Title contains:  + label class="text-gray-800 dark:text-gray-200 mr-2" for="title_contains" Title contains: input class="text-gray-800 p-1 border border-gray-400" type="text" id="title_contains" name="title_contains" div class="mb-4" - label class="text-gray-800 dark:text-gray-200" for="body_contains" ... or body contains:  + label class="text-gray-800 dark:text-gray-200 mr-2" for="body_contains" ... or body contains: input class="text-gray-800 p-1 border border-gray-400" type="text" id="body_contains" name="body_contains" div class="mb-4" - label class="text-gray-800 dark:text-gray-200" for="tags" Tag with:  + label class="text-gray-800 dark:text-gray-200 mr-2" for="tags" Tag with: select class="text-gray-800" id="tags" name="tag_id" - tags.each do |tag| option value=tag.id = tag.label + div class="mb-4" + label class="text-gray-800 dark:text-gray-200 mr-2" for="tag_now" Tag all now? + input type="checkbox" name="tag_now" id="tag_now" div class="mb-4" button class="rounded bg-blue-100 hover:bg-blue-200 text-blue-600 px-2 hover:cursor-pointer" type="submit" = "Create" diff --git a/slices/admin/templates/index.html.slim b/slices/admin/templates/index.html.slim index 4c6ca81..0b70e55 100644 --- a/slices/admin/templates/index.html.slim +++ b/slices/admin/templates/index.html.slim @@ -11,6 +11,8 @@ div class="max-w-prose mx-auto prose dark:prose-invert" a href="/admin/tags" Tags li a href="/admin/tags/auto_tagging" Auto tagging + li + a href="/admin/tags/merge" Merge tags li a href="/admin/bookmarks" Bookmarks diff --git a/slices/admin/templates/merge_tags/index.html.slim b/slices/admin/templates/merge_tags/index.html.slim new file mode 100644 index 0000000..ac75905 --- /dev/null +++ b/slices/admin/templates/merge_tags/index.html.slim @@ -0,0 +1,11 @@ +div class="mb-12 prose dark:prose-invert max-w-prose mx-auto text-gray-800 dark:text-gray-200" + h1 Admin // Merge Tags + +div class="max-w-prose mx-auto" + ul + - tags.each do |tag| + li id="tag-#{tag.id}" class="text-gray-800 dark:text-gray-200" + a href="/admin/tags/merge/#{tag.id}" + = "#{tag.label} (#{tag.posts.count})" + +div class="max-w-screen-md mx-auto border-t-4 border-solid border-gray-400 dark:border-gray-600" diff --git a/slices/admin/templates/merge_tags/new.html.slim b/slices/admin/templates/merge_tags/new.html.slim new file mode 100644 index 0000000..4b1484e --- /dev/null +++ b/slices/admin/templates/merge_tags/new.html.slim @@ -0,0 +1,19 @@ +div class="mb-12 prose dark:prose-invert max-w-prose mx-auto text-gray-800 dark:text-gray-200" + h1 Admin // Merge Tags + +div class="max-w-prose mx-auto prose dark:prose-invert" + h3 Pick a tag to merge in to #{tag.label} + + form action="/admin/tags/merge" method="POST" + input type="hidden" name="target_id" value=tag.id + + div class="mb-4" + select class="text-gray-800" name="source_id" + - tags.each do |source_tag| + option value=source_tag.id + = source_tag.label + div class="mb-4" + button class="rounded bg-blue-100 hover:bg-blue-200 text-blue-600 px-2 hover:cursor-pointer" + = "Merge" + +div class="max-w-screen-md mx-auto border-t-4 border-solid border-gray-400 dark:border-gray-600" diff --git a/slices/admin/views/merge_tags/index.rb b/slices/admin/views/merge_tags/index.rb new file mode 100644 index 0000000..0537824 --- /dev/null +++ b/slices/admin/views/merge_tags/index.rb @@ -0,0 +1,14 @@ +module Admin + module Views + module MergeTags + class Index < Admin::View + + include Deps["repos.tag_repo"] + + expose :tags do + tag_repo.list_with_posts + end + end + end + end +end \ No newline at end of file diff --git a/slices/admin/views/merge_tags/new.rb b/slices/admin/views/merge_tags/new.rb new file mode 100644 index 0000000..b09c03b --- /dev/null +++ b/slices/admin/views/merge_tags/new.rb @@ -0,0 +1,18 @@ +module Admin + module Views + module MergeTags + class New < Admin::View + + include Deps["repos.tag_repo"] + + expose :tag do |id:| + tag_repo.fetch(id) + end + + expose :tags do |id:| + tag_repo.list.reject { |t| t.id.to_s == id.to_s } + end + end + end + end +end \ No newline at end of file