Tag merging UI
This commit is contained in:
@@ -66,6 +66,10 @@ module Adamantium
|
|||||||
post "/tags/auto_tagging", to: "auto_tagging.create"
|
post "/tags/auto_tagging", to: "auto_tagging.create"
|
||||||
delete "/tags/auto_taggings/:id", to: "auto_tagging.delete"
|
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"
|
get "/bookmarks", to: "bookmarks.index"
|
||||||
delete "/bookmarks/:id", to: "bookmarks.delete"
|
delete "/bookmarks/:id", to: "bookmarks.delete"
|
||||||
post "/bookmarks/cache/:id", to: "bookmarks.cache"
|
post "/bookmarks/cache/:id", to: "bookmarks.cache"
|
||||||
|
14
slices/admin/actions/merge_tags/index.rb
Normal file
14
slices/admin/actions/merge_tags/index.rb
Normal file
@@ -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
|
24
slices/admin/actions/merge_tags/merge.rb
Normal file
24
slices/admin/actions/merge_tags/merge.rb
Normal file
@@ -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
|
14
slices/admin/actions/merge_tags/new.rb
Normal file
14
slices/admin/actions/merge_tags/new.rb
Normal file
@@ -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
|
17
slices/admin/commands/merge_tags/merge.rb
Normal file
17
slices/admin/commands/merge_tags/merge.rb
Normal file
@@ -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
|
@@ -1,7 +1,13 @@
|
|||||||
|
require 'pry'
|
||||||
|
|
||||||
module Admin
|
module Admin
|
||||||
module Repos
|
module Repos
|
||||||
class PostTagRepo < Adamantium::Repo[:post_tags]
|
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:)
|
def delete(tag_id:)
|
||||||
post_tags.where(tag_id: tag_id).delete
|
post_tags.where(tag_id: tag_id).delete
|
||||||
end
|
end
|
||||||
|
@@ -16,6 +16,10 @@ module Admin
|
|||||||
def delete(tag_id:)
|
def delete(tag_id:)
|
||||||
tags.by_pk(tag_id).delete
|
tags.by_pk(tag_id).delete
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def fetch(id)
|
||||||
|
tags.by_pk(id).one
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@@ -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"
|
div id="auto-tag-#{auto_tagging.id}" class="mb-2"
|
||||||
== "Tag post with <strong>#{auto_tagging.tag.label}</strong> when <strong>#{auto_tagging.title_only? ? "title" : "content"}</strong> contains <strong>#{auto_tagging.term}</strong>"
|
== "Tag post with <strong>#{auto_tagging.tag.label}</strong> when <strong>#{auto_tagging.title_only? ? "title" : "content"}</strong> contains <strong>#{auto_tagging.term}</strong>"
|
||||||
= " — "
|
= " — "
|
||||||
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
|
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"
|
div class="max-w-screen-md mx-auto border-t-4 border-solid border-gray-400 dark:border-gray-600"
|
||||||
|
@@ -10,19 +10,22 @@ div class="max-w-prose mx-auto"
|
|||||||
|
|
||||||
form method="POST" action="/admin/tags/auto_tagging"
|
form method="POST" action="/admin/tags/auto_tagging"
|
||||||
div class="mb-4"
|
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"
|
input class="text-gray-800 p-1 border border-gray-400" type="text" id="title_contains" name="title_contains"
|
||||||
|
|
||||||
div class="mb-4"
|
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"
|
input class="text-gray-800 p-1 border border-gray-400" type="text" id="body_contains" name="body_contains"
|
||||||
|
|
||||||
div class="mb-4"
|
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"
|
select class="text-gray-800" id="tags" name="tag_id"
|
||||||
- tags.each do |tag|
|
- tags.each do |tag|
|
||||||
option value=tag.id
|
option value=tag.id
|
||||||
= tag.label
|
= 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"
|
div class="mb-4"
|
||||||
button class="rounded bg-blue-100 hover:bg-blue-200 text-blue-600 px-2 hover:cursor-pointer" type="submit"
|
button class="rounded bg-blue-100 hover:bg-blue-200 text-blue-600 px-2 hover:cursor-pointer" type="submit"
|
||||||
= "Create"
|
= "Create"
|
||||||
|
@@ -11,6 +11,8 @@ div class="max-w-prose mx-auto prose dark:prose-invert"
|
|||||||
a href="/admin/tags" Tags
|
a href="/admin/tags" Tags
|
||||||
li
|
li
|
||||||
a href="/admin/tags/auto_tagging" Auto tagging
|
a href="/admin/tags/auto_tagging" Auto tagging
|
||||||
|
li
|
||||||
|
a href="/admin/tags/merge" Merge tags
|
||||||
li
|
li
|
||||||
a href="/admin/bookmarks" Bookmarks
|
a href="/admin/bookmarks" Bookmarks
|
||||||
|
|
||||||
|
11
slices/admin/templates/merge_tags/index.html.slim
Normal file
11
slices/admin/templates/merge_tags/index.html.slim
Normal file
@@ -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"
|
19
slices/admin/templates/merge_tags/new.html.slim
Normal file
19
slices/admin/templates/merge_tags/new.html.slim
Normal file
@@ -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"
|
14
slices/admin/views/merge_tags/index.rb
Normal file
14
slices/admin/views/merge_tags/index.rb
Normal file
@@ -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
|
18
slices/admin/views/merge_tags/new.rb
Normal file
18
slices/admin/views/merge_tags/new.rb
Normal file
@@ -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
|
Reference in New Issue
Block a user