active_admin_multi_upload 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +56 -0
  4. data/Rakefile +32 -0
  5. data/app/assets/stylesheets/active_admin_multi_upload/jquery_upload.scss +1105 -0
  6. data/app/models/concerns/active_admin_multi_upload/uploadable.rb +26 -0
  7. data/app/views/active_admin_multi_upload/_upload_form.html.erb +158 -0
  8. data/config/routes.rb +2 -0
  9. data/lib/active_admin_multi_upload.rb +7 -0
  10. data/lib/active_admin_multi_upload/dsl.rb +49 -0
  11. data/lib/active_admin_multi_upload/engine.rb +5 -0
  12. data/lib/active_admin_multi_upload/version.rb +3 -0
  13. data/lib/generators/active_admin_multi_upload/resource/USAGE +5 -0
  14. data/lib/generators/active_admin_multi_upload/resource/resource_generator.rb +16 -0
  15. data/lib/tasks/active_admin_multi_upload_tasks.rake +4 -0
  16. data/test/active_admin_multi_upload_test.rb +7 -0
  17. data/test/dummy/README.rdoc +28 -0
  18. data/test/dummy/Rakefile +6 -0
  19. data/test/dummy/app/assets/javascripts/application.js +13 -0
  20. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  21. data/test/dummy/app/controllers/application_controller.rb +5 -0
  22. data/test/dummy/app/helpers/application_helper.rb +2 -0
  23. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  24. data/test/dummy/bin/bundle +3 -0
  25. data/test/dummy/bin/rails +4 -0
  26. data/test/dummy/bin/rake +4 -0
  27. data/test/dummy/config.ru +4 -0
  28. data/test/dummy/config/application.rb +28 -0
  29. data/test/dummy/config/boot.rb +5 -0
  30. data/test/dummy/config/environment.rb +5 -0
  31. data/test/dummy/config/environments/development.rb +27 -0
  32. data/test/dummy/config/environments/production.rb +80 -0
  33. data/test/dummy/config/environments/test.rb +36 -0
  34. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  35. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  36. data/test/dummy/config/initializers/inflections.rb +16 -0
  37. data/test/dummy/config/initializers/mime_types.rb +5 -0
  38. data/test/dummy/config/initializers/secret_token.rb +12 -0
  39. data/test/dummy/config/initializers/session_store.rb +3 -0
  40. data/test/dummy/config/initializers/wrap_parameters.rb +9 -0
  41. data/test/dummy/config/locales/en.yml +23 -0
  42. data/test/dummy/config/routes.rb +56 -0
  43. data/test/dummy/public/404.html +58 -0
  44. data/test/dummy/public/422.html +58 -0
  45. data/test/dummy/public/500.html +57 -0
  46. data/test/dummy/public/favicon.ico +0 -0
  47. data/test/integration/navigation_test.rb +9 -0
  48. data/test/test_helper.rb +15 -0
  49. metadata +151 -0
@@ -0,0 +1,26 @@
1
+ module ActiveAdminMultiUpload::Uploadable
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ include Rails.application.routes.url_helpers
6
+ end
7
+
8
+ module ClassMethods
9
+ def allows_upload(name)
10
+ code = <<-eoruby
11
+ def to_jq_upload
12
+ {
13
+ "name" => read_attribute(#{name}),
14
+ "size" => image.size,
15
+ "url" => image.url,
16
+ "thumbnail_url" => image.thumb.url,
17
+ "delete_url" => destroy_upload_admin_#{self.name.downcase}_url(self, only_path: true),
18
+ "id" => id,
19
+ "delete_type" => "DELETE"
20
+ }
21
+ end
22
+ eoruby
23
+ class_eval(code)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,158 @@
1
+ <%= stylesheet_link_tag "active_admin_multi_upload/jquery_upload" %>
2
+
3
+
4
+ <% options = options ||= {}
5
+ uploaded_ids_form_input_name = options[:uploaded_ids_form_input_name] ||= "#{resource.class.name.downcase}[#{association.singularize}_ids][]"
6
+ existing_uploads = options[:existing_uploads] ||= resource.send(association.to_sym)
7
+ input_id_prefix = options[:input_id_prefix] ||= "#{resource.class.name.downcase}_#{association.singularize}_ids_"
8
+ post_url = options[:post_url] ||= "/admin/#{association}/create_upload"
9
+ input_name = options[:input_name] ||= "#{association.singularize}[#{attribute}]"
10
+
11
+ %>
12
+
13
+ <div id="uploader">
14
+ <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->
15
+ <div class="row fileupload-buttonbar">
16
+ <div class="span7">
17
+ <!-- The fileinput-button span is used to style the file input field as button -->
18
+ <span class="btn btn-success fileinput-button">
19
+ <i class="icon-plus icon-white"></i>
20
+ <span>Add files...</span>
21
+ <input id="fileupload" type="file" name="<%= input_name %>" multiple>
22
+ </span>
23
+ <button type="reset" class="btn btn-warning cancel">
24
+ <i class="icon-ban-circle icon-white"></i>
25
+ <span>Cancel upload</span>
26
+ </button>
27
+ <button type="button" class="btn btn-danger delete">
28
+ <i class="icon-trash icon-white"></i>
29
+ <span>Delete</span>
30
+ </button>
31
+ <input type="checkbox" class="toggle">
32
+ </div>
33
+ </div>
34
+ <!-- The loading indicator is shown during image processing -->
35
+ <div class="fileupload-process"></div>
36
+ <br>
37
+ <!-- The table listing the files available for upload/download -->
38
+ <table class="table table-striped"><tbody class="files" id="files-container" data-toggle="modal-gallery" data-target="#modal-gallery"></tbody></table>
39
+ </div>
40
+
41
+
42
+ <script>
43
+ var fileUploadErrors = {
44
+ maxFileSize: 'File is too big',
45
+ minFileSize: 'File is too small',
46
+ acceptFileTypes: 'Filetype not allowed',
47
+ maxNumberOfFiles: 'Max number of files exceeded',
48
+ uploadedBytes: 'Uploaded bytes exceed file size',
49
+ emptyResult: 'Empty file upload result'
50
+ };
51
+ </script>
52
+
53
+ <!-- The template to display files available for upload -->
54
+ <script id="template-upload" type="text/x-tmpl">
55
+ {% for (var i=0, file; file=o.files[i]; i++) { %}
56
+ <tr class="template-upload fade">
57
+ <td class="preview"><span class="fade"></span></td>
58
+ <td class="name"><span>{%=file.name%}</span></td>
59
+ <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
60
+ {% if (file.error) { %}
61
+ <td class="error" colspan="2"><span class="label label-important">{%=locale.fileupload.error%}</span> {%=locale.fileupload.errors[file.error] || file.error%}</td>
62
+ {% } else if (o.files.valid && !i) { %}
63
+ <td>
64
+ <div class="progress progress-striped active" role="progressbar" ><div class="progress-bar bar progress-bar-success" style="width:0%;"></div></div>
65
+ </td>
66
+ <td class="start">{% if (!o.options.autoUpload) { %}
67
+ <button class="btn btn-primary">
68
+ <i class="icon-upload icon-white"></i>
69
+ <span>{%=locale.fileupload.start%}</span>
70
+ </button>
71
+ {% } %}</td>
72
+ {% } else { %}
73
+ <td colspan="2"></td>
74
+ {% } %}
75
+ <td class="cancel">{% if (!i) { %}
76
+ <button class="btn btn-warning">
77
+ <i class="icon-ban-circle icon-white"></i>
78
+ <span>{%=locale.fileupload.cancel%}</span>
79
+ </button>
80
+ {% } %}</td>
81
+ </tr>
82
+ {% } %}
83
+ </script>
84
+
85
+ <!-- The template to display files available for download -->
86
+ <script id="template-download" type="text/x-tmpl">
87
+ {% for (var i=0, file; file=o.files[i]; i++) { %}
88
+ <tr class="template-download fade">
89
+ {% if (file.error) { %}
90
+ <td></td>
91
+ <td class="name"><span>{%=file.name%}</span></td>
92
+ <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
93
+ <td class="error" colspan="2"><span class="label label-important">{%=locale.fileupload.error%}</span> {%=locale.fileupload.errors[file.error] || file.error%}</td>
94
+ {% } else { %}
95
+ <td class="preview">{% if (file.thumbnail_url) { %}
96
+ <a href="{%=file.url%}" title="{%=file.name%}" rel="gallery" download="{%=file.name%}"><img src="{%=file.thumbnail_url%}"></a>
97
+ {% } %}</td>
98
+ <td class="name" id="upload_{%=file.id%}">
99
+ <a href="{%=file.url%}" title="{%=file.name%}" rel="{%=file.thumbnail_url&&'gallery'%}" download="{%=file.name%}">{%=file.name%}</a>
100
+ </td>
101
+ <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
102
+ <td colspan="2"></td>
103
+ {% } %}
104
+ <td class="delete">
105
+ <button class="btn btn-danger" data-type="{%=file.delete_type%}" data-url="{%=file.delete_url%}">
106
+ <i class="icon-trash icon-white"></i>
107
+ <span>{%=locale.fileupload.destroy%}</span>
108
+ </button>
109
+ <input type="checkbox" name="delete" value="1">
110
+ </td>
111
+ </tr>
112
+ {% } %}
113
+ </script>
114
+
115
+
116
+ <script type="text/javascript" charset="utf-8">
117
+ $(function () {
118
+ // Initialize the jQuery File Upload widget:
119
+ $('#uploader').fileupload({
120
+ url: "<%= post_url %>",
121
+ autoUpload: true,
122
+ formData: {},
123
+ sequentialUploads: true,
124
+ fileInput: $("#fileupload"),
125
+ filesContainer: "#files-container"
126
+ }).on('fileuploadcompleted', function(e, data) {
127
+ insertUploadInputs(data.result.files);
128
+ }).bind('fileuploaddestroy', function(e, data) {
129
+ removeUploadInputs([data]);
130
+ });
131
+ });
132
+ </script>
133
+
134
+
135
+ <script type="text/javascript">
136
+ var insertUploadInputs = function(files) {
137
+ $.each(files, function(index, file) {
138
+ var input = $("<input type='hidden' class='file-upload' name='<%= uploaded_ids_form_input_name %>' id='<%= input_id_prefix %>" + file.id + "' value='" + file.id + "' />");
139
+ input.insertAfter($("#upload_" + file.id));
140
+ });
141
+ };
142
+
143
+ var removeUploadInputs = function(files) {
144
+ $.each(files, function(index, file) {
145
+ var id = file.url.split("/").pop();
146
+ $("#<%= input_id_prefix %>" + id).remove();
147
+ });
148
+ };
149
+
150
+ $(function () {
151
+ var files = <%= existing_uploads.map(&:to_jq_upload).to_json.html_safe %>;
152
+ var uploader = $("#uploader").data("blueimpFileupload");
153
+ var template = uploader._renderDownload(files)['appendTo'](uploader.options.filesContainer);
154
+ uploader._transition(template);
155
+ insertUploadInputs(files);
156
+ });
157
+
158
+ </script>
data/config/routes.rb ADDED
@@ -0,0 +1,2 @@
1
+ Rails.application.routes.draw do
2
+ end
@@ -0,0 +1,7 @@
1
+ require "active_admin_multi_upload/engine"
2
+ require "active_admin_multi_upload/dsl"
3
+
4
+ module ActiveAdminMultiUpload
5
+ end
6
+
7
+ ::ActiveAdmin::DSL.send(:include, ActiveAdminMultiUpload::DSL)
@@ -0,0 +1,49 @@
1
+ module ActiveAdminMultiUpload
2
+ module DSL
3
+
4
+ def allows_multi_upload(options={})
5
+
6
+ config.resource_class.send(:include, ::ActiveAdminMultiUpload::Uploadable)
7
+ uploader = options[:mounted_uploader] ||= :image
8
+ config.resource_class.send(:allows_upload, uploader)
9
+
10
+ collection_action :create_upload, method: :post do
11
+ @upload_model = options[:model] ||= active_admin_config.resource_class
12
+ @model = @upload_model.new(upload_resource_params)
13
+ if @model.save
14
+ respond_to do |format|
15
+ format.html {
16
+ render :json => [@model.to_jq_upload].to_json,
17
+ :content_type => 'text/html',
18
+ :layout => false
19
+ }
20
+ format.json {
21
+ render :json => { files: [@model.to_jq_upload] }, status: :created
22
+ }
23
+ end
24
+ else
25
+ render :json => [{:error => "custom_failure"}], :status => 304
26
+ end
27
+ end
28
+
29
+ member_action :destroy_upload, method: :delete do
30
+ @upload_model = options[:model] ||= active_admin_config.resource_class
31
+ @model = @upload_model.find(params[:id])
32
+ @model.destroy
33
+ render :json => true
34
+ end
35
+
36
+ controller do
37
+ # Rails 4 Strong Parameters compatibility and backwards compatibility.
38
+ def upload_resource_params
39
+ # I don't think this will work any more.
40
+ if respond_to?(:permitted_params)
41
+ permitted_params[active_admin_config.resource_class.name.underscore]
42
+ else
43
+ params[active_admin_config.resource_class.name.underscore]
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,5 @@
1
+ module ActiveAdminMultiUpload
2
+ class Engine < ::Rails::Engine
3
+ require 'jquery-fileupload-rails'
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module ActiveAdminMultiUpload
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,5 @@
1
+ Description:
2
+ Adds the ability to upload multiple files to a Model that has a Carrierwave uploader mounted to it within Active Admin
3
+
4
+ Example:
5
+ rails g active_admin_multi_upload:resource YourModel
@@ -0,0 +1,16 @@
1
+ module ActiveAdminMultiUpload
2
+ class ResourceGenerator < Rails::Generators::NamedBase
3
+ source_root File.expand_path('../templates', __FILE__)
4
+
5
+ def add_js_assets
6
+ append_file "app/assets/javascripts/active_admin.js.coffee", "#= require jquery-fileupload\n"
7
+ append_file "app/assets/javascripts/active_admin.js.coffee", "#= require jquery-fileupload/vendor/tmpl\n"
8
+ end
9
+
10
+ def add_css_assets
11
+ append_file "app/assets/stylesheets/active_admin.css.scss", '@import "jquery.fileupload-ui";'
12
+ end
13
+
14
+ private
15
+ end
16
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :active_admin_multi_upload do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class ActiveAdminMultiUploadTest < ActiveSupport::TestCase
4
+ test "truth" do
5
+ assert_kind_of Module, ActiveAdminMultiUpload
6
+ end
7
+ end
@@ -0,0 +1,28 @@
1
+ == README
2
+
3
+ This README would normally document whatever steps are necessary to get the
4
+ application up and running.
5
+
6
+ Things you may want to cover:
7
+
8
+ * Ruby version
9
+
10
+ * System dependencies
11
+
12
+ * Configuration
13
+
14
+ * Database creation
15
+
16
+ * Database initialization
17
+
18
+ * How to run the test suite
19
+
20
+ * Services (job queues, cache servers, search engines, etc.)
21
+
22
+ * Deployment instructions
23
+
24
+ * ...
25
+
26
+
27
+ Please feel free to use a different markup language if you do not plan to run
28
+ <tt>rake doc:app</tt>.
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ Dummy::Application.load_tasks
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,13 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require_tree .
13
+ */
@@ -0,0 +1,5 @@
1
+ class ApplicationController < ActionController::Base
2
+ # Prevent CSRF attacks by raising an exception.
3
+ # For APIs, you may want to use :null_session instead.
4
+ protect_from_forgery with: :exception
5
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Dummy</title>
5
+ <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
6
+ <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
3
+ load Gem.bin_path('bundler', 'bundle')
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
3
+ require_relative '../config/boot'
4
+ require 'rails/commands'
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../config/boot'
3
+ require 'rake'
4
+ Rake.application.run
@@ -0,0 +1,4 @@
1
+ # This file is used by Rack-based servers to start the application.
2
+
3
+ require ::File.expand_path('../config/environment', __FILE__)
4
+ run Rails.application
@@ -0,0 +1,28 @@
1
+ require File.expand_path('../boot', __FILE__)
2
+
3
+ # Pick the frameworks you want:
4
+ # require "active_record/railtie"
5
+ require "action_controller/railtie"
6
+ require "action_mailer/railtie"
7
+ require "sprockets/railtie"
8
+ require "rails/test_unit/railtie"
9
+
10
+ Bundler.require(*Rails.groups)
11
+ require "active_admin_multi_upload"
12
+
13
+ module Dummy
14
+ class Application < Rails::Application
15
+ # Settings in config/environments/* take precedence over those specified here.
16
+ # Application configuration should go into files in config/initializers
17
+ # -- all .rb files in that directory are automatically loaded.
18
+
19
+ # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
20
+ # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
21
+ # config.time_zone = 'Central Time (US & Canada)'
22
+
23
+ # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
24
+ # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
25
+ # config.i18n.default_locale = :de
26
+ end
27
+ end
28
+