mirror of
https://github.com/danbee/my-images
synced 2025-03-04 08:49:05 +00:00
Remove tags with JS
This commit is contained in:
parent
b42a80f806
commit
1ce11c4781
18
.babelrc
Normal file
18
.babelrc
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"presets": [
|
||||
["env", {
|
||||
"modules": false,
|
||||
"targets": {
|
||||
"browsers": "> 1%",
|
||||
"uglify": true
|
||||
},
|
||||
"useBuiltIns": true
|
||||
}]
|
||||
],
|
||||
|
||||
"plugins": [
|
||||
"syntax-dynamic-import",
|
||||
"transform-object-rest-spread",
|
||||
["transform-class-properties", { "spec": true }]
|
||||
]
|
||||
}
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@ -20,3 +20,8 @@
|
||||
|
||||
# Ignore dragonfly uploads
|
||||
/public/system
|
||||
/public/packs
|
||||
/public/packs-test
|
||||
/node_modules
|
||||
yarn-debug.log*
|
||||
.yarn-integrity
|
||||
|
||||
3
.postcssrc.yml
Normal file
3
.postcssrc.yml
Normal file
@ -0,0 +1,3 @@
|
||||
plugins:
|
||||
postcss-import: {}
|
||||
postcss-cssnext: {}
|
||||
2
Gemfile
2
Gemfile
@ -16,6 +16,7 @@ gem "puma"
|
||||
gem "sass-rails"
|
||||
gem "simple_form"
|
||||
gem "uglifier"
|
||||
gem "webpacker"
|
||||
|
||||
group :doc do
|
||||
gem "sdoc", require: false
|
||||
@ -30,6 +31,7 @@ end
|
||||
group :test do
|
||||
gem "capybara"
|
||||
gem "launchy"
|
||||
gem "poltergeist"
|
||||
gem "rspec-rails"
|
||||
gem "shoulda-matchers"
|
||||
gem "webmock"
|
||||
|
||||
13
Gemfile.lock
13
Gemfile.lock
@ -59,6 +59,7 @@ GEM
|
||||
rack (>= 1.6.0)
|
||||
rack-test (>= 0.6.3)
|
||||
xpath (~> 3.1)
|
||||
cliver (0.3.2)
|
||||
coderay (1.1.2)
|
||||
concurrent-ruby (1.0.5)
|
||||
crack (0.4.3)
|
||||
@ -142,12 +143,18 @@ GEM
|
||||
oauth2 (~> 1.1)
|
||||
omniauth (~> 1.2)
|
||||
pg (1.1.3)
|
||||
poltergeist (1.18.1)
|
||||
capybara (>= 2.1, < 4)
|
||||
cliver (~> 0.3.1)
|
||||
websocket-driver (>= 0.2.0)
|
||||
pry (0.11.3)
|
||||
coderay (~> 1.1.0)
|
||||
method_source (~> 0.9.0)
|
||||
public_suffix (3.0.3)
|
||||
puma (3.12.0)
|
||||
rack (2.0.5)
|
||||
rack-proxy (0.6.4)
|
||||
rack
|
||||
rack-test (1.1.0)
|
||||
rack (>= 1.0, < 3)
|
||||
rails (5.2.1)
|
||||
@ -236,6 +243,10 @@ GEM
|
||||
addressable (>= 2.3.6)
|
||||
crack (>= 0.3.2)
|
||||
hashdiff
|
||||
webpacker (3.5.5)
|
||||
activesupport (>= 4.2)
|
||||
rack-proxy (>= 0.6.1)
|
||||
railties (>= 4.2)
|
||||
websocket-driver (0.7.0)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.3)
|
||||
@ -257,6 +268,7 @@ DEPENDENCIES
|
||||
launchy
|
||||
omniauth-github
|
||||
pg
|
||||
poltergeist
|
||||
pry
|
||||
puma
|
||||
rails (= 5.2.1)
|
||||
@ -267,6 +279,7 @@ DEPENDENCIES
|
||||
simple_form
|
||||
uglifier
|
||||
webmock
|
||||
webpacker
|
||||
|
||||
RUBY VERSION
|
||||
ruby 2.5.1p57
|
||||
|
||||
@ -1,15 +0,0 @@
|
||||
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
||||
// listed below.
|
||||
//
|
||||
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
||||
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
||||
//
|
||||
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
||||
// compiled file.
|
||||
//
|
||||
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
|
||||
// about supported directives.
|
||||
//
|
||||
//= require jquery
|
||||
//= require jquery_ujs
|
||||
//= require_tree .
|
||||
@ -1,3 +0,0 @@
|
||||
// Place all the behaviors and hooks related to the matching controller here.
|
||||
// All this logic will automatically be available in application.js.
|
||||
// You can use CoffeeScript in this file: http://coffeescript.org/
|
||||
@ -1,3 +0,0 @@
|
||||
// Place all the behaviors and hooks related to the matching controller here.
|
||||
// All this logic will automatically be available in application.js.
|
||||
// You can use CoffeeScript in this file: http://coffeescript.org/
|
||||
@ -1,3 +0,0 @@
|
||||
// Place all the behaviors and hooks related to the matching controller here.
|
||||
// All this logic will automatically be available in application.js.
|
||||
// You can use CoffeeScript in this file: http://coffeescript.org/
|
||||
@ -14,7 +14,7 @@
|
||||
grid-area: image-info;
|
||||
}
|
||||
|
||||
.image-tags {
|
||||
.image-tags-list {
|
||||
list-style: none;
|
||||
padding-left: 0;
|
||||
}
|
||||
@ -27,6 +27,10 @@
|
||||
color: #333;
|
||||
margin: 0.25rem 0.125rem;
|
||||
padding: 0.125rem 0.5rem;
|
||||
|
||||
&.hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
|
||||
@ -4,7 +4,7 @@ class TagsController < ApplicationController
|
||||
def create
|
||||
image = @current_user.images.find(params[:image_id])
|
||||
tag = params[:tag]
|
||||
image.tags << tag unless image.tags.include? tag
|
||||
image.tags << tag unless image.tags.include?(tag)
|
||||
image.save
|
||||
|
||||
respond_to do |format|
|
||||
|
||||
31
app/javascript/controllers/tag_controller.js
Normal file
31
app/javascript/controllers/tag_controller.js
Normal file
@ -0,0 +1,31 @@
|
||||
import { Controller } from "stimulus";
|
||||
import ajaxService from "../services/ajax_service";
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = [ "name" ];
|
||||
|
||||
connect() {
|
||||
console.log("Connected to our tags");
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
console.log("Bye bye tag!");
|
||||
}
|
||||
|
||||
delete(event) {
|
||||
const imageId = this.element.dataset.imageId;
|
||||
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")
|
||||
});
|
||||
}
|
||||
}
|
||||
15
app/javascript/packs/application.js
Normal file
15
app/javascript/packs/application.js
Normal file
@ -0,0 +1,15 @@
|
||||
/* 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 { Application } from "stimulus";
|
||||
import { definitionsFromContext } from "stimulus/webpack-helpers";
|
||||
|
||||
const application = Application.start();
|
||||
const context = require.context("controllers", true, /.js$/);
|
||||
application.load(definitionsFromContext(context));
|
||||
29
app/javascript/services/ajax_service.js
Normal file
29
app/javascript/services/ajax_service.js
Normal file
@ -0,0 +1,29 @@
|
||||
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) => {
|
||||
},
|
||||
|
||||
deleteTag: (tag) => {
|
||||
return axios.delete(`/user/images/${imageId()}/tags/${tag}.json`, config());
|
||||
}
|
||||
}
|
||||
10
app/views/images/_tag.html.erb
Normal file
10
app/views/images/_tag.html.erb
Normal file
@ -0,0 +1,10 @@
|
||||
<li class="image-tag"
|
||||
id="tag-<%= tag %>"
|
||||
data-controller="tag">
|
||||
<span data-target="tag.name"><%= tag %></span>
|
||||
<%= link_to "×".html_safe,
|
||||
user_image_tag_path(@image, tag),
|
||||
method: :delete,
|
||||
data: { action: "click->tag#delete" },
|
||||
class: "delete-tag" %>
|
||||
</li>
|
||||
@ -4,19 +4,23 @@
|
||||
<%= @image.image.name %>
|
||||
<% end %>
|
||||
|
||||
<div class="show-image">
|
||||
<div class="show-image" data-image-id="<%= @image.id %>">
|
||||
<div class="image-container">
|
||||
<%= render "image", image: @image %>
|
||||
</div>
|
||||
|
||||
<div class="image-info">
|
||||
<%= render "tags/tags", image: @image, tags: @image.tags %>
|
||||
<div class="image-tags">
|
||||
<%= render "tags/tags", image: @image, tags: @image.tags %>
|
||||
|
||||
<div class="new-tag-form">
|
||||
<%= form_tag user_image_tags_path(@image), remote: true, method: :post do %>
|
||||
<%= text_field_tag :tag %>
|
||||
<%= submit_tag "Add Tag" %>
|
||||
<% end %>
|
||||
<div class="new-tag-form">
|
||||
<%= form_tag user_image_tags_path(@image),
|
||||
remote: true,
|
||||
method: :post do %>
|
||||
<%= text_field_tag :tag %>
|
||||
<%= submit_tag "Add Tag" %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
<head>
|
||||
<title>My Images</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
|
||||
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
|
||||
<%= stylesheet_link_tag "application", media: "all" %>
|
||||
<%= javascript_pack_tag "application" %>
|
||||
<%= csrf_meta_tags %>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<ul class="image-tags" id="image-tags">
|
||||
<ul class="image-tags-list" id="image-tags">
|
||||
<% tags.each do |tag| %>
|
||||
<%= render "tags/tag", image: image, tag: tag %>
|
||||
<% end %>
|
||||
|
||||
15
bin/webpack
Executable file
15
bin/webpack
Executable file
@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
|
||||
ENV["NODE_ENV"] ||= "development"
|
||||
|
||||
require "pathname"
|
||||
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
||||
Pathname.new(__FILE__).realpath)
|
||||
|
||||
require "rubygems"
|
||||
require "bundler/setup"
|
||||
|
||||
require "webpacker"
|
||||
require "webpacker/webpack_runner"
|
||||
Webpacker::WebpackRunner.run(ARGV)
|
||||
15
bin/webpack-dev-server
Executable file
15
bin/webpack-dev-server
Executable file
@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
|
||||
ENV["NODE_ENV"] ||= "development"
|
||||
|
||||
require "pathname"
|
||||
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
||||
Pathname.new(__FILE__).realpath)
|
||||
|
||||
require "rubygems"
|
||||
require "bundler/setup"
|
||||
|
||||
require "webpacker"
|
||||
require "webpacker/dev_server_runner"
|
||||
Webpacker::DevServerRunner.run(ARGV)
|
||||
5
config/webpack/development.js
Normal file
5
config/webpack/development.js
Normal file
@ -0,0 +1,5 @@
|
||||
process.env.NODE_ENV = process.env.NODE_ENV || 'development'
|
||||
|
||||
const environment = require('./environment')
|
||||
|
||||
module.exports = environment.toWebpackConfig()
|
||||
3
config/webpack/environment.js
Normal file
3
config/webpack/environment.js
Normal file
@ -0,0 +1,3 @@
|
||||
const { environment } = require('@rails/webpacker')
|
||||
|
||||
module.exports = environment
|
||||
5
config/webpack/production.js
Normal file
5
config/webpack/production.js
Normal file
@ -0,0 +1,5 @@
|
||||
process.env.NODE_ENV = process.env.NODE_ENV || 'production'
|
||||
|
||||
const environment = require('./environment')
|
||||
|
||||
module.exports = environment.toWebpackConfig()
|
||||
5
config/webpack/test.js
Normal file
5
config/webpack/test.js
Normal file
@ -0,0 +1,5 @@
|
||||
process.env.NODE_ENV = process.env.NODE_ENV || 'development'
|
||||
|
||||
const environment = require('./environment')
|
||||
|
||||
module.exports = environment.toWebpackConfig()
|
||||
68
config/webpacker.yml
Normal file
68
config/webpacker.yml
Normal file
@ -0,0 +1,68 @@
|
||||
# Note: You must restart bin/webpack-dev-server for changes to take effect
|
||||
|
||||
default: &default
|
||||
source_path: app/javascript
|
||||
source_entry_path: packs
|
||||
public_output_path: packs
|
||||
cache_path: tmp/cache/webpacker
|
||||
|
||||
# Additional paths webpack should lookup modules
|
||||
# ['app/assets', 'engine/foo/app/assets']
|
||||
resolved_paths: []
|
||||
|
||||
# Reload manifest.json on all requests so we reload latest compiled packs
|
||||
cache_manifest: false
|
||||
|
||||
extensions:
|
||||
- .js
|
||||
- .sass
|
||||
- .scss
|
||||
- .css
|
||||
- .module.sass
|
||||
- .module.scss
|
||||
- .module.css
|
||||
- .png
|
||||
- .svg
|
||||
- .gif
|
||||
- .jpeg
|
||||
- .jpg
|
||||
|
||||
development:
|
||||
<<: *default
|
||||
compile: true
|
||||
|
||||
# Reference: https://webpack.js.org/configuration/dev-server/
|
||||
dev_server:
|
||||
https: false
|
||||
host: localhost
|
||||
port: 3035
|
||||
public: localhost:3035
|
||||
hmr: false
|
||||
# Inline should be set to true if using HMR
|
||||
inline: true
|
||||
overlay: true
|
||||
compress: true
|
||||
disable_host_check: true
|
||||
use_local_ip: false
|
||||
quiet: false
|
||||
headers:
|
||||
'Access-Control-Allow-Origin': '*'
|
||||
watch_options:
|
||||
ignored: /node_modules/
|
||||
|
||||
|
||||
test:
|
||||
<<: *default
|
||||
compile: true
|
||||
|
||||
# Compile test packs to a separate directory
|
||||
public_output_path: packs-test
|
||||
|
||||
production:
|
||||
<<: *default
|
||||
|
||||
# Production depends on precompilation of packs prior to booting for performance.
|
||||
compile: false
|
||||
|
||||
# Cache manifest.json for performance
|
||||
cache_manifest: true
|
||||
10
package.json
Normal file
10
package.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@rails/webpacker": "3.5",
|
||||
"axios": "^0.18.0",
|
||||
"stimulus": "^1.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"webpack-dev-server": "2.11.2"
|
||||
}
|
||||
}
|
||||
@ -9,6 +9,7 @@ end
|
||||
require "rspec/rails"
|
||||
require "shoulda/matchers"
|
||||
require "capybara/rspec"
|
||||
require "capybara/poltergeist"
|
||||
|
||||
Dir[Rails.root.join("spec", "support", "**", "*.rb")].each { |f| require f }
|
||||
|
||||
@ -19,6 +20,8 @@ rescue ActiveRecord::PendingMigrationError => e
|
||||
exit 1
|
||||
end
|
||||
|
||||
Capybara.javascript_driver = :poltergeist
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.fixture_path = "#{::Rails.root}/spec/fixtures"
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
require "webmock/rspec"
|
||||
WebMock.disable_net_connect!
|
||||
WebMock.allow_net_connect!
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.expect_with :rspec do |expectations|
|
||||
|
||||
Loading…
Reference in New Issue
Block a user