diff --git a/Gemfile b/Gemfile index 678845e36..a1a0ecf7a 100644 --- a/Gemfile +++ b/Gemfile @@ -33,6 +33,7 @@ gem 'omniauth-facebook', '~> 4.0.0' gem 'omniauth-google-oauth2', '~> 0.4.0' gem 'omniauth-twitter', '~> 1.4.0' gem 'paperclip', '~> 5.1.0' +gem 'jquery-fileupload-rails' gem 'paranoia', '~> 2.3.1' gem 'pg', '~> 0.20.0' gem 'pg_search', '~> 2.0.1' diff --git a/Gemfile.lock b/Gemfile.lock index f2a314780..62428113d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -200,6 +200,10 @@ GEM railties (>= 3.1, < 6.0) invisible_captcha (0.9.2) rails (>= 3.2.0) + jquery-fileupload-rails (0.4.7) + actionpack (>= 3.1) + railties (>= 3.1) + sass (>= 3.2) jquery-rails (4.3.1) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) @@ -515,6 +519,7 @@ DEPENDENCIES i18n-tasks (~> 0.9.15) initialjs-rails (~> 0.2.0.5) invisible_captcha (~> 0.9.2) + jquery-fileupload-rails jquery-rails (~> 4.3.1) jquery-ui-rails (~> 6.0.1) kaminari (~> 1.0.1) @@ -559,4 +564,4 @@ DEPENDENCIES whenever (~> 0.9.7) BUNDLED WITH - 1.15.1 + 1.15.3 diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index cf2758b78..2ff87100a 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -14,6 +14,7 @@ //= require jquery_ujs //= require jquery-ui/widgets/datepicker //= require jquery-ui/i18n/datepicker-es +//= require jquery-fileupload/basic //= require foundation //= require turbolinks //= require ckeditor/loader @@ -59,6 +60,7 @@ //= require legislation_annotatable //= require watch_form_changes //= require followable +//= require documentable //= require tree_navigator //= require custom @@ -94,6 +96,7 @@ var initialize_modules = function() { App.LegislationAnnotatable.initialize(); App.WatchFormChanges.initialize(); App.TreeNavigator.initialize(); + App.Documentable.initialize(); }; $(function(){ diff --git a/app/assets/javascripts/documentable.js.coffee b/app/assets/javascripts/documentable.js.coffee new file mode 100644 index 000000000..e97754609 --- /dev/null +++ b/app/assets/javascripts/documentable.js.coffee @@ -0,0 +1,64 @@ +App.Documentable = + + initialize: -> + $('input#document_attachment[type=file]').fileupload + + add: (e, data) -> + data.progressBar = $('
').insertAfter('#progress-bar') + options = + extension: data.files[0].name.match(/(\.\w+)?$/)[0] + _: Date.now() + direct_upload_url = $(this).closest('form').data('direct-upload-url') + console.log direct_upload_url + + fileData = new FormData(); + fileData.append('file', data.fileInput[0].files[0]); + + console.log direct_upload_url + + $.getJSON direct_upload_url, options, (result) -> + data.formData = result['fields'] + data.url = result['url'] + data.paramName = 'file' + data.submit() + return + + # $.ajax + # url: direct_upload_url + # type: 'POST' + # data: fileData + # cache: false + # contentType: false + # processData: false + # xhr: -> + # console.log 'Progress init' + # myXhr = $.ajaxSettings.xhr() + # if myXhr.upload + # # For handling the progress of the upload + # myXhr.upload.addEventListener 'progress', ((e) -> + # console.log 'progress listener called' + # ), false + # + # myXhr.upload.addEventListener 'complete', ((e) -> + # console.log 'complete listener called' + # return + # ), false + # myXhr + + progress: (e, data) -> + progress = parseInt(data.loaded / data.total * 100, 10) + $('.loading-bar').css 'width', progress + '%' + return + + done: (e, data) -> + $('.loading-bar').removeClass 'uploading' + $('.loading-bar').addClass 'complete' + image = + id: data.formData.key + storage: 'cache' + metadata: + size: data.files[0].size + filename: data.files[0].name.match(/[^\/\\]*$/)[0] + mime_type: data.files[0].type + $('#cached_attachment_data').val JSON.stringify(image) + return \ No newline at end of file diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index a14cf3383..6db475365 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -15,3 +15,4 @@ @import 'annotator_overrides'; @import 'jquery-ui/datepicker'; @import 'datepicker_overrides'; +@import 'documentable'; diff --git a/app/assets/stylesheets/documentable.scss b/app/assets/stylesheets/documentable.scss new file mode 100644 index 000000000..5c26f9a43 --- /dev/null +++ b/app/assets/stylesheets/documentable.scss @@ -0,0 +1,29 @@ +.progress-bar { + background-color: transparent; + height: 5px; + width: 100%; + z-index: 666000555; +} + +.loading-bar { + height: 5px; + min-width: 10px; + z-index: 666000666; + -webkit-transition:width 500ms ease-out, height 500ms ease-out; + -moz-transition:width 500ms ease-out, height 500ms ease-out; + -o-transition:width 500ms ease-out, height 500ms ease-out; + transition:width 500ms ease-out, height 500ms ease-out; + &.uploading{ + background-color: #f00; + } + &.complete{ + background-color: #0f0; + } +} + +.loading-bar.no-transition { + -webkit-transition:none; + -moz-transition:none; + -o-transition:none; + transition:none; +} diff --git a/app/controllers/documents_controller.rb b/app/controllers/documents_controller.rb index cea6cca16..cc482c695 100644 --- a/app/controllers/documents_controller.rb +++ b/app/controllers/documents_controller.rb @@ -3,7 +3,13 @@ class DocumentsController < ApplicationController before_filter :find_documentable, except: :destroy before_filter :prepare_new_document, only: :new before_filter :prepare_document_for_creation, only: :create - load_and_authorize_resource + + before_filter :validate_upload, only: :upload + load_and_authorize_resource :except => [:upload] + skip_authorization_check :only => [:upload] + + def preload + end def new end @@ -27,6 +33,19 @@ class DocumentsController < ApplicationController redirect_to params[:from] end + def upload + document = Document.new(documentable: @documentable, attachment: params[:file].tempfile, title: "faketitle", user: current_user ) + debugger + # We only are intested in attachment validators. We set some fake data to get attachment errors only + if document.valid? + # TODO: Store file on tmp cache + msg = { status: 200, msg: "OK" } + else + msg = { status: 422, msg: document.errors[:attachment].join(', ') } + end + render :json => msg + end + private def find_documentable @@ -47,4 +66,8 @@ class DocumentsController < ApplicationController params.require(:document).permit(:title, :documentable_type, :documentable_id, :attachment) end + def validate_upload + if @documentable.present? + end + end end diff --git a/app/views/documents/_form.html.erb b/app/views/documents/_form.html.erb index 11abe37f5..a4fefa694 100644 --- a/app/views/documents/_form.html.erb +++ b/app/views/documents/_form.html.erb @@ -4,7 +4,8 @@ documentable_id: @document.documentable_id, from: params[:from] ), - html: { multipart: true } do |f| %> + html: { multipart: true, class: "documentable"}, + data: { direct_upload_url: upload_documents_url(documentable_type: @document.documentable_type, documentable_id: @document.documentable_id) } do |f| %> <%= render 'shared/errors', resource: @document %> @@ -15,13 +16,12 @@
-
- <%= f.file_field :attachment, - accept: accepted_content_types_extensions(@document.documentable), - label: false, class: 'show-for-sr' %> - <%= f.label :attachment, t("documents.form.attachment_label"), class: 'button hollow' %> -

<%= document_attachment_file_name(@document) %>

-
+ <%= f.file_field :attachment, + accept: accepted_content_types_extensions(@document.documentable), + label: false, class: 'show-for-sr' %> + <%= f.label :attachment, t("documents.form.attachment_label"), class: 'button hollow' %> +
+

<%= document_attachment_file_name(@document) %>

<% if @document.errors.has_key?(:attachment) %> diff --git a/config/routes.rb b/config/routes.rb index 297c8e0d4..fe8a895ce 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -95,7 +95,10 @@ Rails.application.routes.draw do resources :follows, only: [:create, :destroy] - resources :documents, only: [:new, :create, :destroy] + resources :documents, only: [:new, :create, :destroy] do + collection { post :upload, format: :json} + collection { post :progress, format: :json} + end resources :stats, only: [:index] diff --git a/db/schema.rb b/db/schema.rb index ed830c7d6..30477462e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -936,7 +936,7 @@ ActiveRecord::Schema.define(version: 20170720092638) do t.boolean "email_digest", default: true t.boolean "email_on_direct_message", default: true t.boolean "official_position_badge", default: false - t.datetime "password_changed_at", default: '2017-07-27 22:09:12', null: false + t.datetime "password_changed_at", default: '2017-07-31 15:04:53', null: false t.boolean "created_from_signature", default: false t.integer "failed_email_digests_count", default: 0 t.text "former_users_data_log", default: ""