1
0
mirror of https://github.com/danbee/my-images synced 2025-03-04 08:49:05 +00:00

Move tag handling over to turbo frames

This commit is contained in:
Daniel Barber 2024-03-25 21:09:13 -05:00
parent 6bbf9fcd73
commit 71c7ba2acf
15 changed files with 46 additions and 110 deletions

View File

@ -1,2 +1,4 @@
//= link_tree ../images
//= link_directory ../stylesheets .css
//= link_tree ../../javascript .js
//= link_tree ../../../vendor/javascript .js

View File

@ -8,6 +8,13 @@ class ImagesController < ApplicationController
def show
@image = @current_user.images.find(params[:id])
if turbo_frame_request?
render partial: "tags/tags", locals: {
image: @image,
tags: @image.tags
}
end
end
def create

View File

@ -8,7 +8,7 @@ class TagsController < ApplicationController
if !image.tags.include?(tag)
image.tags << tag
image.save
render partial: "tags/tag", locals: { image: image, tag: tag }
redirect_to image, turbo_frame: "tags"
else
head :no_content, content_type: "text/html"
end
@ -20,6 +20,6 @@ class TagsController < ApplicationController
image.tags.delete(tag)
image.save
head :no_content
redirect_to image, turbo_frame: "tags"
end
end

View File

@ -0,0 +1,7 @@
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import "@hotwired/turbo-rails"
import Rails from "@rails/ujs";
import { Application } from "@hotwired/stimulus";
Rails.start();

View File

@ -1,22 +0,0 @@
import { Controller } from "stimulus";
import ajaxService from "../services/ajax_service";
export default class extends Controller {
static targets = ["name"];
delete(event) {
const tag = this.nameTarget.innerText;
event.preventDefault();
this.element.classList.add("hidden");
ajaxService.deleteTag(tag)
.then(response => {
this.element.parentElement.removeChild(this.element);
})
.catch(error => {
this.element.classList.remove("hidden")
});
}
}

View File

@ -1,20 +0,0 @@
import { Controller } from "stimulus";
import ajaxService from "../services/ajax_service";
export default class extends Controller {
static targets = ["tag", "tagList"]
create(event) {
const tag = this.tagTarget.value;
event.preventDefault();
ajaxService.createTag(tag)
.then(response => {
if (response.status == 200) {
this.tagListTarget.innerHTML += response.data;
this.tagTarget.value = "";
};
})
}
}

View File

@ -1,18 +0,0 @@
/* eslint no-console:0 */
// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.
//
// To reference this file, add <%= javascript_pack_tag 'application' %> to the appropriate
// layout file, like app/views/layouts/application.html.erb
import Rails from "rails-ujs";
import { Application } from "stimulus";
import { definitionsFromContext } from "stimulus/webpack-helpers";
Rails.start();
const application = Application.start();
const context = require.context("controllers", true, /.js$/);
application.load(definitionsFromContext(context));

View File

@ -1,32 +0,0 @@
import axios from "axios";
const csrfToken = () => {
return document
.getElementsByName("csrf-token")[0]
.attributes["content"]
.value;
}
const imageId = () => {
return document
.getElementsByClassName("show-image")[0]
.attributes["data-image-id"]
.value;
}
const config = () => ({
headers: { "X-CSRF-Token": csrfToken() }
});
export default {
createTag: (tag) => {
return axios.post(`/images/${imageId()}/tags`, { tag }, config());
},
deleteTag: (tag) => {
return axios.delete(
`/images/${imageId()}/tags/${encodeURIComponent(tag)}`,
config()
);
}
}

View File

@ -3,11 +3,13 @@
<%= render "tags/tags", image: image, tags: image.tags %>
<div class="new-tag-form">
<%= form_tag image_tags_path(image),
<%= form_tag(
image_tags_path(image),
method: :post,
data: { action: "tags#create" } do %>
<%= text_field_tag :tag, nil, data: { target: "tags.tag" } %>
<%= submit_tag "Add Tag", data: { disable_with: false } %>
data: {"turbo-frame": "tags"}
) do %>
<%= text_field_tag :tag, nil %>
<%= submit_tag "Add Tag" %>
<% end %>
</div>
</div>

View File

@ -4,8 +4,8 @@
<title>My Images</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<%= stylesheet_link_tag "application", media: "all" %>
<%= javascript_pack_tag "application" %>
<%= csrf_meta_tags %>
<%= javascript_importmap_tags %>
</head>
<body>

View File

@ -3,7 +3,7 @@
data-controller="tag">
<span data-target="tag.name"><%= tag %></span>
<%= link_to "&times;".html_safe,
image_tag_path(image, tag),
data: { action: "click->tag#delete" },
image_tag_path(image, id: tag),
data: {method: "delete", "turbo-frame": "tags"},
class: "delete-tag" %>
</li>

View File

@ -1,5 +1,7 @@
<ul class="image-tags-list" id="image-tags" data-target="tags.tagList">
<% tags.each do |tag| %>
<%= render "tags/tag", image: image, tag: tag %>
<% end %>
</ul>
<%= turbo_frame_tag "tags" do %>
<ul class="image-tags-list" id="image-tags" data-target="tags.tagList">
<% tags.each do |tag| %>
<%= render "tags/tag", image: image, tag: tag %>
<% end %>
</ul>
<% end %>

View File

@ -1,4 +0,0 @@
document.getElementById("tag").value = "";
document.getElementById("image-tags")
.outerHTML = `<%= render "tags", image: image, tags: tags %>`;

4
bin/importmap Executable file
View File

@ -0,0 +1,4 @@
#!/usr/bin/env ruby
require_relative "../config/application"
require "importmap/commands"

8
config/importmap.rb Normal file
View File

@ -0,0 +1,8 @@
# Pin npm packages by running ./bin/importmap
pin "application"
pin "@rails/ujs", to: "@rails--ujs.js" # @7.1.3
pin "@hotwired/stimulus", to: "@hotwired--stimulus.js" # @3.2.2
pin "@hotwired/turbo-rails", to: "@hotwired--turbo-rails.js" # @8.0.4
pin "@hotwired/turbo", to: "@hotwired--turbo.js" # @8.0.4
pin "@rails/actioncable/src", to: "@rails--actioncable--src.js" # @7.1.3