From 5a1c0ec2d23ed441bee0c4c342740a1980f52890 Mon Sep 17 00:00:00 2001 From: Karel Picman Date: Thu, 3 Aug 2017 12:55:37 +0200 Subject: [PATCH] #48 look and feel --- app/controllers/dmsf_links_controller.rb | 2 +- app/controllers/dmsf_upload_controller.rb | 19 ++- app/views/dmsf/show.html.erb | 2 +- .../_approval_workflow_button.html.erb | 14 +-- .../dmsf_files/_file_new_revision.html.erb | 3 +- app/views/dmsf_files/_thumbnails.html.erb | 12 +- app/views/dmsf_links/create.js.erb | 4 +- app/views/dmsf_upload/_form.html.erb | 114 ++++++++--------- app/views/dmsf_upload/_multi_upload.html.erb | 3 +- .../delete_dmsf_link_attachment.js.erb | 1 + app/views/dmsf_upload/upload.js.erb | 2 +- assets/javascripts/attachments_dmsf.js | 115 +++++++++++------- assets/stylesheets/redmine_dmsf.css | 23 +++- config/locales/cs.yml | 5 +- config/locales/de.yml | 5 +- config/locales/en.yml | 3 + config/locales/es.yml | 5 +- config/locales/fr.yml | 5 +- config/locales/hu.yml | 5 +- config/locales/it.yml | 5 +- config/locales/ja.yml | 5 +- config/locales/pl.yml | 5 +- config/locales/pt-BR.yml | 5 +- config/locales/ru.yml | 5 +- config/locales/sl.yml | 5 +- config/locales/zh-TW.yml | 5 +- config/locales/zh.yml | 5 +- config/routes.rb | 1 + init.rb | 3 +- .../controllers/issues_controller_hooks.rb | 1 + .../hooks/views/issue_view_hooks.rb | 93 ++++++++++---- .../patches/user_preference_patch.rb | 43 +++++-- ...dmsf_folder_permissions_controller_test.rb | 3 +- 33 files changed, 348 insertions(+), 178 deletions(-) create mode 100644 app/views/dmsf_upload/delete_dmsf_link_attachment.js.erb diff --git a/app/controllers/dmsf_links_controller.rb b/app/controllers/dmsf_links_controller.rb index fcc1434c..a6162211 100644 --- a/app/controllers/dmsf_links_controller.rb +++ b/app/controllers/dmsf_links_controller.rb @@ -87,7 +87,7 @@ class DmsfLinksController < ApplicationController @dmsf_link.project_id = params[:dmsf_link][:project_id] @dmsf_link.dmsf_folder_id = params[:dmsf_link][:dmsf_folder_id] else - # An issue link + # A container link @dmsf_link.project_id = -1 @dmsf_link.dmsf_folder_id = nil end diff --git a/app/controllers/dmsf_upload_controller.rb b/app/controllers/dmsf_upload_controller.rb index b0b57189..f7cd5065 100644 --- a/app/controllers/dmsf_upload_controller.rb +++ b/app/controllers/dmsf_upload_controller.rb @@ -24,11 +24,11 @@ class DmsfUploadController < ApplicationController menu_item :dmsf - before_action :find_project, :except => [:upload, :delete_dmsf_attachment] - before_action :authorize, :except => [:upload, :delete_dmsf_attachment] - before_action :authorize_global, :only => [:upload, :delete_dmsf_attachment] - before_action :find_folder, :except => [:upload_file, :upload, :commit, :delete_dmsf_attachment] - before_action :permissions, :except => [:upload_file, :upload, :commit, :delete_dmsf_attachment] + before_action :find_project, :except => [:upload, :delete_dmsf_attachment, :delete_dmsf_link_attachment] + before_action :authorize, :except => [:upload, :delete_dmsf_attachment, :delete_dmsf_link_attachment] + before_action :authorize_global, :only => [:upload, :delete_dmsf_attachment, :delete_dmsf_link_attachment] + before_action :find_folder, :except => [:upload_file, :upload, :commit, :delete_dmsf_attachment, :delete_dmsf_link_attachment] + before_action :permissions, :except => [:upload_file, :upload, :commit, :delete_dmsf_attachment, :delete_dmsf_link_attachment] helper :all helper :dmsf_workflows @@ -75,7 +75,7 @@ class DmsfUploadController < ApplicationController end end - # REST API document upload + # REST API and Redmine attachment form def upload unless request.content_type == 'application/octet-stream' render :nothing => true, :status => 406 @@ -130,6 +130,13 @@ class DmsfUploadController < ApplicationController render_404 end + def delete_dmsf_link_attachment + link = DmsfLink.find(params[:id]) + link.destroy + rescue ActiveRecord::RecordNotFound + render_404 + end + private def commit_files_internal(commited_files) diff --git a/app/views/dmsf/show.html.erb b/app/views/dmsf/show.html.erb index 7539f9ff..e7c5096c 100644 --- a/app/views/dmsf/show.html.erb +++ b/app/views/dmsf/show.html.erb @@ -215,7 +215,7 @@ <% end %> <% if (@file_manipulation_allowed && !@locked_for_user && !@system_folder) %> - <%= render(:partial => 'dmsf_upload/multi_upload') %> + <%= render(:partial => 'dmsf_upload/multi_upload', :local => { :lbl => true }) %> <% end %> <% unless @system_folder %> diff --git a/app/views/dmsf_files/_approval_workflow_button.html.erb b/app/views/dmsf_files/_approval_workflow_button.html.erb index 66b8f68e..08536151 100644 --- a/app/views/dmsf_files/_approval_workflow_button.html.erb +++ b/app/views/dmsf_files/_approval_workflow_button.html.erb @@ -35,12 +35,12 @@ :dmsf_file_revision_id => file.last_revision.id), :title => l(:title_waiting_for_approval), :remote => true, - :class => 'icon icon-wf-waiting') %> + :class => "icon-only icon-wf-waiting") %> <% else %> - + <% end %> <% else %> - + <% end %> <% when DmsfWorkflow::STATE_ASSIGNED %> <% if User.current && (file.last_revision.dmsf_workflow_assigned_by == User.current.id) && wf %> @@ -49,12 +49,12 @@ :id => file.last_revision.dmsf_workflow_id, :dmsf_file_revision_id => file.last_revision.id), :title => l(:label_dmsf_wokflow_action_start), - :class => 'icon icon-wf-assigned') %> + :class => 'icon-only icon-wf-assigned') %> <% else %> <% end %> <% when DmsfWorkflow::STATE_APPROVED, DmsfWorkflow::STATE_REJECTED %> - + <% else %> <% if workflows_available %> <%= link_to('', @@ -69,9 +69,9 @@ :dmsf_file_revision_id => file.last_revision.id), :title => l(:label_dmsf_wokflow_action_assign), :remote => true, - :class => 'icon icon-wf-none') %> + :class => 'icon-only icon-wf-none') %> <% else %> - + <% end %> <% end %> <% end %> diff --git a/app/views/dmsf_files/_file_new_revision.html.erb b/app/views/dmsf_files/_file_new_revision.html.erb index b80e0cdf..b1a44be8 100644 --- a/app/views/dmsf_files/_file_new_revision.html.erb +++ b/app/views/dmsf_files/_file_new_revision.html.erb @@ -78,7 +78,8 @@

<%= label_tag('file_upload', l(:label_new_content)) %> - <%= render :partial => 'dmsf_upload/form', :locals => { :multiple => false, :container => nil } %> + <%= render :partial => 'dmsf_upload/form', + :locals => { :multiple => false, :container => nil, :description => false, :awf => false } %>

diff --git a/app/views/dmsf_files/_thumbnails.html.erb b/app/views/dmsf_files/_thumbnails.html.erb index 3e545d58..2812061d 100644 --- a/app/views/dmsf_files/_thumbnails.html.erb +++ b/app/views/dmsf_files/_thumbnails.html.erb @@ -24,17 +24,21 @@ <% if defined?(thumbnails) && thumbnails %> <% images = links.map{ |x| x[0] }.select(&:image?) %> <% if images.any? %> -

+ <% if link_to # Redmine classic %> +
+ <% end %> <% images.each do |file| %>
<% if link_to # Redmine classic %> <%= link_to image_tag(dmsf_thumbnail_path(file)), view_dmsf_file_path(file), :alt => file.title %> <% else # jQuery gallery %> - <%= image_tag(dmsf_thumbnail_path(file), - { :'data-fullsrc' => view_dmsf_file_path(file), :alt => file.title }) %> + <%= image_tag(dmsf_thumbnail_path(file), + { :'data-fullsrc' => view_dmsf_file_path(file), :alt => file.title }) %> <% end %>
<% end %> -
+ <% if link_to # Redmine classic %> +
+ <% end %> <% end %> <% end %> diff --git a/app/views/dmsf_links/create.js.erb b/app/views/dmsf_links/create.js.erb index 41b8ffa2..c3756116 100644 --- a/app/views/dmsf_links/create.js.erb +++ b/app/views/dmsf_links/create.js.erb @@ -20,7 +20,7 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. %> -var linksSpan = $("#dmsf_links_fields"); +var linksSpan = $("#dmsf_links_attachments_fields"); var linkId = "<%= @dmsf_link.id %>"; var linkName = "<%= @dmsf_link.name %>"; var title = "<%= l(:label_dmsf_wokflow_action_assign) %>"; @@ -35,4 +35,4 @@ var awf = false; <% end %> <% end %> -dmsfAddLink(linksSpan, linkId, linkName, title, project, awf); +dmsfAddLink(linksSpan, linkId, linkName, title, project, awf, <%= !defined?(EasyExtensions) %>); diff --git a/app/views/dmsf_upload/_form.html.erb b/app/views/dmsf_upload/_form.html.erb index 93c513da..820e4847 100644 --- a/app/views/dmsf_upload/_form.html.erb +++ b/app/views/dmsf_upload/_form.html.erb @@ -21,30 +21,56 @@ %> -<% if defined?(container) && container && container.saved_dmsf_attachments.present? %> - <% container.saved_dmsf_attachments.each_with_index do |attachment, i| %> - - <%= text_field_tag("dmsf_attachments[p#{i}][filename]", attachment.filename, :class => 'filename') + - text_field_tag("dmsf_attachments[p#{i}][description]", attachment.description, :maxlength => 255, - :placeholder => l(:label_optional_description), :class => 'description') + - link_to(' '.html_safe, dmsf_attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'), - :method => 'delete', :remote => true, :class => 'remove-upload icon icon-del') %> - <%= hidden_field_tag "dmsf_attachments[p#{i}][token]", "#{attachment.token}" %> - <% wf = container.saved_dmsf_attachments_wfs[attachment.id] %> - <% if wf %> - - <%= hidden_field_tag("dmsf_attachments_wfs[p#{i}]", wf.id) if wf %> - <% else %> - <%= link_to('', assign_dmsf_workflow_path(:id => container.project.id, :project_id => container.project.id, - :attachment_id => i + 1), :title => l(:label_dmsf_wokflow_action_assign), - :remote => true, :class => 'icon icon-wf-none') %> - <% end %> - + <% if defined?(container) && container && container.saved_dmsf_attachments.present? %> + <% container.saved_dmsf_attachments.each_with_index do |attachment, i| %> + + <%= hidden_field_tag "dmsf_attachments[p#{i}][token]", "#{attachment.token}" %> + <%= text_field_tag("dmsf_attachments[p#{i}][filename]", attachment.filename, :class => 'filename') %> + <%= text_field_tag("dmsf_attachments[p#{i}][description]", attachment.description, :maxlength => 255, + :placeholder => l(:label_optional_description), :class => 'description') if description %> + <%= link_to('', dmsf_attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'), + :method => 'delete', :remote => true, :class => 'remove-upload icon-only icon-del') %> + <% wf = container.saved_dmsf_attachments_wfs[attachment.id] %> + <% if wf %> + + <%= hidden_field_tag("dmsf_attachments_wfs[p#{i}]", wf.id) if wf %> + <% else %> + <%= link_to('', assign_dmsf_workflow_path(:id => container.project.id, :project_id => container.project.id, + :attachment_id => i + 1), :title => l(:label_dmsf_wokflow_action_assign), + :remote => true, :class => 'icon-only icon-wf-none') %> + <% end %> + + <% end %> <% end %> + + + +<% if defined?(container) && container && container.saved_dmsf_links.present? %> + <% container.saved_dmsf_links.each_with_index do |dmsf_link, index| %> + + + + <%= link_to('', dmsf_link_attachment_path(dmsf_link, :link_id => "#{index}", :format => 'js'), + :method => 'delete', :remote => true, :class => 'remove-upload icon-only icon-del') %> + <% wf = container.saved_dmsf_links_wfs[dmsf_link.id] %> + <% if wf %> + + <%= hidden_field_tag("dmsf_links_wfs[#{dmsf_link.id}]", wf.id) if wf %> + <% else %> + <%= render(:partial => 'dmsf_files/approval_workflow_button', + :locals => {:file => dmsf_link.target_file, + :file_approval_allowed => User.current.allowed_to?(:file_approval, dmsf_link.target_file.project), + :workflows_available => DmsfWorkflow.where( + ['project_id = ? OR project_id IS NULL', dmsf_link.target_file.project_id]).exists?, + :project => dmsf_link.target_file.project, :wf => wf, :dmsf_link_id => dmsf_link.id }) %> + <% end %> + + <% end %> <% end %> - -<%= file_field_tag 'dmsf_attachments[dummy][file]', + + + <%= file_field_tag 'dmsf_attachments[dummy][file]', :id => nil, :class => 'file_selector', :multiple => multiple, @@ -56,40 +82,18 @@ :max_concurrent_uploads => Redmine::Configuration['max_concurrent_ajax_uploads'].to_i, :upload_path => dmsf_uploads_path(:format => 'js'), :description_placeholder => l(:label_optional_description), - :project => "#{@project.identifier}" + :project => "#{@project.identifier}", + :description => description, + :awf => awf } %> - (<%= l(:label_max_size) %>: <%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>) -<% if container %> -
- - <% if container.saved_dmsf_links.present? %> - <% container.saved_dmsf_links.each_with_index do |dmsf_link, index| %> - - - -   - <% wf = container.saved_dmsf_links_wfs[dmsf_link.id] %> - <% if wf %> - - <%= hidden_field_tag("dmsf_links_wfs[#{dmsf_link.id}]", wf.id) if wf %> - <% else %> - <%= render(:partial => 'dmsf_files/approval_workflow_button', - :locals => {:file => dmsf_link.target_file, - :file_approval_allowed => User.current.allowed_to?(:file_approval, dmsf_link.target_file.project), - :workflows_available => DmsfWorkflow.where( - ['project_id = ? OR project_id IS NULL', dmsf_link.target_file.project]).exists?, - :project => dmsf_link.target_file.project, :wf => wf, :dmsf_link_id => dmsf_link.id }) %> - <% end %> -
-
- <% end %> - <% end %> -
- - <%= link_to l(:label_link_from), - new_dmsf_link_path(:project_id => container.project.id, :type => 'link_from', :container => 'issue'), - :title => l(:title_create_link), :class => 'icon icon-add', :remote => true %> - +<% if defined?(container) && container %> + + <%= link_to l(:label_link_from), + new_dmsf_link_path(:project_id => container.project.id, :type => 'link_from', :container => container.class.name), + :title => l(:title_create_link), :class => 'icon icon-add file_selector', :remote => true %> + <% end %> - + + (<%= l(:label_max_size) %>: <%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>) + diff --git a/app/views/dmsf_upload/_multi_upload.html.erb b/app/views/dmsf_upload/_multi_upload.html.erb index b38e7b50..f3bd3ddb 100644 --- a/app/views/dmsf_upload/_multi_upload.html.erb +++ b/app/views/dmsf_upload/_multi_upload.html.erb @@ -38,7 +38,8 @@ :id => 'uploadform', :method => :post, :multipart => true) do %>
- <%= render :partial => 'dmsf_upload/form', :locals => { :multiple => true, :container => nil } %> + <%= render :partial => 'dmsf_upload/form', + :locals => { :multiple => true, :container => nil, :description => true, :awf => false } %> <%= submit_tag l(:label_upload) %>
diff --git a/app/views/dmsf_upload/delete_dmsf_link_attachment.js.erb b/app/views/dmsf_upload/delete_dmsf_link_attachment.js.erb new file mode 100644 index 00000000..969b4e1c --- /dev/null +++ b/app/views/dmsf_upload/delete_dmsf_link_attachment.js.erb @@ -0,0 +1 @@ +$('#dmsf_links_attachments_<%= j params[:link_id] %>').remove(); diff --git a/app/views/dmsf_upload/upload.js.erb b/app/views/dmsf_upload/upload.js.erb index b0e1d76f..c6549cb4 100644 --- a/app/views/dmsf_upload/upload.js.erb +++ b/app/views/dmsf_upload/upload.js.erb @@ -26,7 +26,7 @@ var fileSpan = $('#dmsf_attachments_<%= j params[:attachment_id] %>'); alert("<%= escape_javascript @attachment.errors.full_messages.join(', ') %>"); <% else %> $('', { type: 'hidden', name: 'dmsf_attachments[<%= j params[:attachment_id] %>][token]' } ).val('<%= j @attachment.token %>').appendTo(fileSpan); -fileSpan.find('a.remove-upload') +fileSpan.find('a.dmsf-remove-upload') .attr({ "data-remote": true, "data-method": 'delete', diff --git a/assets/javascripts/attachments_dmsf.js b/assets/javascripts/attachments_dmsf.js index 912940ae..0723e80d 100644 --- a/assets/javascripts/attachments_dmsf.js +++ b/assets/javascripts/attachments_dmsf.js @@ -24,24 +24,24 @@ function dmsfAddLink(linksSpan, linkId, linkName, title, project, awf) { if (linksSpan.children().length < 10) { var nextLinkId = dmsfAddLink.nextLinkId++; - var linkSpan = $('', { id: 'dmsf_links_' + nextLinkId }); + var linkSpan = $('', { id: 'dmsf_links_attachments_' + nextLinkId, 'class': 'attachment' }); + var iconDel = $('').attr({href: '#', 'class': 'remove-upload icon-only icon-del'}); + var inputId = $('', {type: 'hidden', name: 'dmsf_links[' + nextLinkId + ']'}).val(linkId); + var inputName = $('', {type: 'text', class: 'filename readonly'}).val(linkName); - linkSpan.append( - "", - "", - $(' ').attr({href: "#", 'class': 'remove-upload icon icon-del'}).click(dmsfRemoveFile) - ); + linkSpan.append(inputId); + linkSpan.append(inputName); + linkSpan.append(iconDel.click(dmsfRemoveFileLbl)); if(awf) { - linkSpan.append($(' ').attr({ - href: "/dmsf_workflows/" + project + "/assign?dmsf_link_id=" + linkId, - 'class': 'icon icon-wf-none', 'data-remote': 'true', 'title': title - })); + var iconWf = $('').attr({href: "/dmsf_workflows/" + project + "/assign?dmsf_link_id=" + linkId, + 'class': 'icon-only icon-wf-none', 'data-remote': 'true', 'title': title}); + + linkSpan.append(iconWf); } - linkSpan.append("
"); - linkSpan.appendTo(linksSpan); + linksSpan.append(linkSpan); } } @@ -52,37 +52,41 @@ function dmsfAddFile(inputEl, file, eagerUpload) { if ($('#dmsf_attachments_fields').children().length < 10) { var attachmentId = dmsfAddFile.nextAttachmentId++; - var fileSpan = $('', { id: 'dmsf_attachments_' + attachmentId }); + var fileSpan = $('', { id: 'dmsf_attachments_' + attachmentId, 'class': 'attachment' }); + var iconDel = $('
').attr({href: '#', 'class': 'remove-upload icon-only icon-del'}).toggle(!eagerUpload); + var fileName = $('', {type: 'text', 'class': 'filename readonly', + name: 'dmsf_attachments[' + attachmentId + '][filename]', readonly: 'readonly'}).val(file.name); if($(inputEl).attr('multiple') == 'multiple') { - fileSpan.append( - $('', { - type: 'text', - 'class': 'filename readonly', - name: 'dmsf_attachments[' + attachmentId + '][filename]', - readonly: 'readonly' - }).val(file.name), - $('', { - type: 'text', - 'class': 'description', - name: 'dmsf_attachments[' + attachmentId + '][description]', - maxlength: 255, + + fileSpan.append(fileName); + + if($(inputEl).data('description')) { + + var description = $('', {type: 'text', 'class': 'description', + name: 'dmsf_attachments[' + attachmentId + '][description]', maxlength: 255, placeholder: $(inputEl).data('description-placeholder') - }).toggle(!eagerUpload), - $(' ').attr({href: "#", 'class': 'remove-upload icon icon-del'}).click(dmsfRemoveFile).toggle(!eagerUpload), - $(' ').attr({href: "/dmsf_workflows/" + $(inputEl).attr('data-project') + "/assign?attachment_id=" + attachmentId, - 'class': 'icon icon-wf-none', 'data-remote': 'true'}) - ).appendTo('#dmsf_attachments_fields'); + }).toggle(!eagerUpload); + + fileSpan.append(description); + } + + fileSpan.append(iconDel.click(dmsfRemoveFileLbl)); + + if($(inputEl).data('awf')) { + + var iconWf = $('').attr({href: '/dmsf_workflows/' + $(inputEl).attr( + 'data-project') + "/assign?attachment_id=" + attachmentId, 'class': 'icon-only icon-wf-none', + 'data-remote': 'true'}); + + fileSpan.append(iconWf); + } + + $('#dmsf_attachments_fields').append(fileSpan); } else{ - fileSpan.append( - $('', { - type: 'text', - 'class': 'filename readonly', - name: 'dmsf_attachments[' + attachmentId + '][filename]', - readonly: 'readonly' - }).val(file.name) - ).appendTo('#dmsf_attachments_fields'); + fileSpan.append(fileName); + $('#dmsf_attachments_fields').append(fileSpan); $('#dmsf_file_revision_name').val(file.name); } @@ -150,8 +154,17 @@ function dmsfAjaxUpload(file, attachmentId, fileSpan, inputEl) { dmsfAjaxUpload.uploading = 0; -function dmsfRemoveFile() { +function dmsfRemoveFileLbl() { + $(this).parent('span').remove(); + + return false; +} + +function dmsfRemoveFile() { + + $(this).parent('span').parent('span').remove(); + return false; } @@ -189,7 +202,9 @@ function dmsfUploadBlob(blob, uploadUrl, attachmentId, options) { } function dmsfAddInputFiles(inputEl) { + var clearedFileInput = $(inputEl).clone().val(''); + var addFileSpan = $('.dmsf_add_attachment'); if ($.ajaxSettings.xhr().upload && inputEl.files) { // upload files using ajax @@ -199,16 +214,22 @@ function dmsfAddInputFiles(inputEl) { // browser not supporting the file API, upload on form submission var attachmentId; var aFilename = inputEl.value.split(/\/|\\/); - attachmentId = dmsfAddFile(inputEl, { name: aFilename[ aFilename.length - 1 ] }, false); + attachmentId = dmsfAddFile(inputEl, {name: aFilename[aFilename.length - 1]}, false); if (attachmentId) { - $(inputEl).attr({ name: 'dmsf_attachments[' + attachmentId + '][file]', style: 'display:none;' }).appendTo('#dmsf_attachments_' + attachmentId); + $(inputEl).attr({name: 'dmsf_attachments[' + attachmentId + '][file]', style: 'display:none;'}).appendTo( + '#dmsf_attachments_' + attachmentId); } } - if($(inputEl).attr('multiple') == 'multiple') - clearedFileInput.insertAfter('#dmsf_attachments_fields'); - else - $('.dmsf_add_attachment').toggle(); + if ($(inputEl).attr('multiple') == 'multiple') { + + clearedFileInput.val(''); + addFileSpan.prepend(clearedFileInput); + } + else { + + addFileSpan.hide(); + } } function dmsfUploadAndAttachFiles(files, inputEl) { @@ -223,7 +244,9 @@ function dmsfUploadAndAttachFiles(files, inputEl) { if (sizeExceeded) { window.alert(maxFileSizeExceeded); } else { - $.each(files, function() {dmsfAddFile(inputEl, this, true);}); + $.each(files, function() { + dmsfAddFile(inputEl, this, true); + }); } } diff --git a/assets/stylesheets/redmine_dmsf.css b/assets/stylesheets/redmine_dmsf.css index b823fd6d..c5959ce3 100644 --- a/assets/stylesheets/redmine_dmsf.css +++ b/assets/stylesheets/redmine_dmsf.css @@ -302,8 +302,8 @@ div.dmsf_revision_inner_box .attribute .label { /* DMSF file upload */ .dmsf_uploader{ - padding:6px; - margin-bottom: 10px; + padding:10px; + margin-bottom: 20px; background-color:#f6f6f6; color:#505050; line-height:1.5em; @@ -312,6 +312,21 @@ div.dmsf_revision_inner_box .attribute .label { border-radius: 3px; min-height: 50px; display: block; + overflow: hidden; +} + +.dmsf_add_link{ + display: block; + float: right; + margin-top: 10px; + margin-bottom: 10px; +} + +.dmsf_add_file{ + display: block; + float: left; + margin-top: 10px; + margin-bottom: 10px; } #dmsf_attachments_fields input.description {margin-left:4px; width:340px;} @@ -321,5 +336,5 @@ div.dmsf_revision_inner_box .attribute .label { #dmsf_attachments_fields .ajax-loading input.filename {background:url(../../../images/loading.gif) no-repeat 0px 50%;} #dmsf_attachments_fields div.ui-progressbar { width: 100px; height:14px; margin: 2px 0 -5px 8px; display: inline-block; } -#dmsf_links_fields span {display:block; white-space:nowrap;} -#dmsf_links_fields input.filename {border:0; height:1.8em; width:250px; color:#555; background-color:inherit; background:url(../../../images/link.png) no-repeat 1px 50%; padding-left:18px;} +#dmsf_links_attachments_fields span {display:block; white-space:nowrap;} +#dmsf_links_attachments_fields input.filename {border:0; height:1.8em; width:250px; color:#555; background-color:inherit; background:url(../../../images/link.png) no-repeat 1px 50%; padding-left:18px;} diff --git a/config/locales/cs.yml b/config/locales/cs.yml index 13e2ecc2..5da7267b 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -365,4 +365,7 @@ cs: label_act_as_attachable: Jako příloha note_dmsf_act_as_attachable: Umožní přikládat dokumenty k objektům např. úkolům. - label_user_search_add: Vyhledej uživatele pro přidání \ No newline at end of file + label_user_search_add: Vyhledej uživatele pro přidání + + label_dmsf_attachments: DMS přílohy + label_basic_attachments: Souborové přílohy \ No newline at end of file diff --git a/config/locales/de.yml b/config/locales/de.yml index 62ebce59..68f3c08c 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -362,4 +362,7 @@ de: label_act_as_attachable: Act as attachable note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. - label_user_search_add: Search for user to add \ No newline at end of file + label_user_search_add: Search for user to add + + label_dmsf_attachments: DMS Anhänge + label_basic_attachments: Dateianhängen \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index 61d7c77a..5ee3a6b0 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -366,3 +366,6 @@ en: note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. label_user_search_add: Search for user to add + + label_dmsf_attachments: DMS Attachments + label_basic_attachments: Basic Attachments \ No newline at end of file diff --git a/config/locales/es.yml b/config/locales/es.yml index 966af994..7be2de11 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -365,4 +365,7 @@ es: label_act_as_attachable: Act as attachable note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. - label_user_search_add: Search for user to add \ No newline at end of file + label_user_search_add: Search for user to add + + label_dmsf_attachments: DMS Attachments + label_basic_attachments: Basic Attachments \ No newline at end of file diff --git a/config/locales/fr.yml b/config/locales/fr.yml index b649b033..625d5d79 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -365,4 +365,7 @@ fr: label_act_as_attachable: Act as attachable note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. - label_user_search_add: Search for user to add \ No newline at end of file + label_user_search_add: Search for user to add + + label_dmsf_attachments: DMS Attachments + label_basic_attachments: Basic Attachments \ No newline at end of file diff --git a/config/locales/hu.yml b/config/locales/hu.yml index 425d7dc6..aa0efafa 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -364,4 +364,7 @@ hu: label_act_as_attachable: Act as attachable note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. - label_user_search_add: Search for user to add \ No newline at end of file + label_user_search_add: Search for user to add + + label_dmsf_attachments: DMS Attachments + label_basic_attachments: Basic Attachments \ No newline at end of file diff --git a/config/locales/it.yml b/config/locales/it.yml index 124f2e38..40abfee0 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -365,4 +365,7 @@ it: # Italian strings thx 2 Matteo Arceci! label_act_as_attachable: Act as attachable note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. - label_user_search_add: Search for user to add \ No newline at end of file + label_user_search_add: Search for user to add + + label_dmsf_attachments: DMS Attachments + label_basic_attachments: Basic Attachments \ No newline at end of file diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 4ad48d79..7ff29b34 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -365,4 +365,7 @@ ja: label_act_as_attachable: Act as attachable note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. - label_user_search_add: Search for user to add \ No newline at end of file + label_user_search_add: Search for user to add + + label_dmsf_attachments: DMS Attachments + label_basic_attachments: Basic Attachments \ No newline at end of file diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 1555a409..22c1d4d8 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -365,4 +365,7 @@ pl: label_act_as_attachable: Act as attachable note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. - label_user_search_add: Search for user to add \ No newline at end of file + label_user_search_add: Search for user to add + + label_dmsf_attachments: DMS Attachments + label_basic_attachments: Basic Attachments \ No newline at end of file diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 9acabc79..9e19d45c 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -365,4 +365,7 @@ pt-BR: label_act_as_attachable: Act as attachable note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. - label_user_search_add: Search for user to add \ No newline at end of file + label_user_search_add: Search for user to add + + label_dmsf_attachments: DMS Attachments + label_basic_attachments: Basic Attachments \ No newline at end of file diff --git a/config/locales/ru.yml b/config/locales/ru.yml index c89e24d0..e0e296d8 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -365,4 +365,7 @@ ru: label_act_as_attachable: Act as attachable note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. - label_user_search_add: Search for user to add \ No newline at end of file + label_user_search_add: Search for user to add + + label_dmsf_attachments: DMS Attachments + label_basic_attachments: Basic Attachments \ No newline at end of file diff --git a/config/locales/sl.yml b/config/locales/sl.yml index 8b685b58..eb569b50 100644 --- a/config/locales/sl.yml +++ b/config/locales/sl.yml @@ -365,4 +365,7 @@ sl: label_act_as_attachable: Act as attachable note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. - label_user_search_add: Search for user to add \ No newline at end of file + label_user_search_add: Search for user to add + + label_dmsf_attachments: DMS Attachments + label_basic_attachments: Basic Attachments \ No newline at end of file diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index a471891c..77e4e9b2 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -365,4 +365,7 @@ zh-TW: label_act_as_attachable: Act as attachable note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. - label_user_search_add: Search for user to add \ No newline at end of file + label_user_search_add: Search for user to add + + label_dmsf_attachments: DMS Attachments + label_basic_attachments: Basic Attachments \ No newline at end of file diff --git a/config/locales/zh.yml b/config/locales/zh.yml index 7fd48c58..dcf61e0a 100644 --- a/config/locales/zh.yml +++ b/config/locales/zh.yml @@ -365,4 +365,7 @@ zh: label_act_as_attachable: Act as attachable note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. - label_user_search_add: Search for user to add \ No newline at end of file + label_user_search_add: Search for user to add + + label_dmsf_attachments: DMS Attachments + label_basic_attachments: Basic Attachments \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index a2bcc6a6..24f2fb25 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -68,6 +68,7 @@ if Redmine::Plugin.installed? :redmine_dmsf post '/projects/:id/dmsf/commit', :controller => 'dmsf_upload', :action => 'commit' match 'dmsf_uploads', :to => 'dmsf_upload#upload', :via => :post delete '/dmsf/attachments/:id/delete', :to => 'dmsf_upload#delete_dmsf_attachment', :as => 'dmsf_attachment' + delete '/dmsf/link_attachments/:id/delete', :to => 'dmsf_upload#delete_dmsf_link_attachment', :as => 'dmsf_link_attachment' # # dmsf_files controller diff --git a/init.rb b/init.rb index 048f7439..7f3cd423 100644 --- a/init.rb +++ b/init.rb @@ -87,7 +87,8 @@ Redmine::Plugin.register :redmine_dmsf do :dmsf_folder_permissions => [:new, :append, :autocomplete_for_user] } permission :file_manipulation, { :dmsf_files => [:create_revision, :lock, :unlock, :delete_revision, :notify_activate, :notify_deactivate, :restore], - :dmsf_upload => [:upload_files, :upload_file, :upload, :commit_files, :commit, :delete_dmsf_attachment], + :dmsf_upload => [:upload_files, :upload_file, :upload, :commit_files, :commit, :delete_dmsf_attachment, + :delete_dmsf_link_attachment], :dmsf_links => [:new, :create, :destroy, :restore, :autocomplete_for_project, :autocomplete_for_folder] } permission :file_delete, { :dmsf => [:trash, :delete_entries], diff --git a/lib/redmine_dmsf/hooks/controllers/issues_controller_hooks.rb b/lib/redmine_dmsf/hooks/controllers/issues_controller_hooks.rb index 6da09d72..8000f5bd 100644 --- a/lib/redmine_dmsf/hooks/controllers/issues_controller_hooks.rb +++ b/lib/redmine_dmsf/hooks/controllers/issues_controller_hooks.rb @@ -58,6 +58,7 @@ module RedmineDmsf if context.is_a?(Hash) issue = context[:issue] params = context[:params] + User.current.pref.update_attribute :dmsf_attachments_upload_choice, params[:dmsf_attachments_upload_choice] issue.save_dmsf_attachments(params[:dmsf_attachments]) issue.save_dmsf_links(params[:dmsf_links]) issue.save_dmsf_attachments_wfs(params[:dmsf_attachments_wfs], params[:dmsf_attachments]) diff --git a/lib/redmine_dmsf/hooks/views/issue_view_hooks.rb b/lib/redmine_dmsf/hooks/views/issue_view_hooks.rb index 07f94159..ef5ed52a 100644 --- a/lib/redmine_dmsf/hooks/views/issue_view_hooks.rb +++ b/lib/redmine_dmsf/hooks/views/issue_view_hooks.rb @@ -26,11 +26,32 @@ module RedmineDmsf def view_issues_form_details_bottom(context={}) return if defined?(EasyExtensions) + context[:container] = context[:issue] attach_documents_form(context) end def view_issues_edit_notes_bottom(context={}) - attach_documents_form(context) + html = '' + # Radio buttons + if allowed_to_attach_documents(context[:container]) + html << '

' + html << '' + html << '' + html << '

' + end + # Upload form + html.html_safe + attach_documents_form(context, false, + defined?(EasyExtensions) && EasySetting.value('attachment_description')) end def view_issues_show_description_bottom(context={}) @@ -40,23 +61,42 @@ module RedmineDmsf def view_issues_show_attachments_bottom(context={}) unless context[:options][:only_mails].present? - show_attached_documents(context[:container], context[:controller]) + show_attached_documents(context[:container], context[:controller], context[:attachments]) end end + def view_issues_dms_attachments(context={}) + 'yes' if get_links(context[:container]).any? + end + def view_issues_show_thumbnails(context={}) + show_thumbnails(context[:container], context[:controller]) + end + + def view_issues_dms_thumbnails(context={}) unless context[:options][:only_mails].present? - show_thumbnails(context[:container], context[:controller]) + links = get_links(context[:container]) + if links.present? && Setting.thumbnails_enabled? + images = links.map{ |x| x[0] }.select(&:image?) + return 'yes' if images.any? + end end end private + def allowed_to_attach_documents(container) + container && + User.current.allowed_to?(:file_manipulation, container.project) && + Setting.plugin_redmine_dmsf['dmsf_act_as_attachable'] && + (container.project.dmsf_act_as_attachable == Project::ATTACHABLE_DMS_AND_ATTACHMENTS) + end + def get_links(container) + links = [] if defined?(container.dmsf_files) && User.current.allowed_to?(:view_dmsf_files, container.project) && Setting.plugin_redmine_dmsf['dmsf_act_as_attachable'] && (container.project.dmsf_act_as_attachable == Project::ATTACHABLE_DMS_AND_ATTACHMENTS) - links = [] for dmsf_file in container.dmsf_files if dmsf_file.last_revision links << [dmsf_file, nil, dmsf_file.created_at] @@ -69,8 +109,9 @@ module RedmineDmsf end end # Sort by 'create_at' - links.sort{ |x, y| x[2] <=> y[2] } + links.sort!{ |x, y| x[2] <=> y[2] } end + links end def show_thumbnails(container, controller) @@ -83,18 +124,21 @@ module RedmineDmsf end end - def attach_documents_form(context) - if context.is_a?(Hash) && context[:issue] + def attach_documents_form(context, label=true, description=true) + if context.is_a?(Hash) && context[:container] # Add Dmsf upload form - issue = context[:issue] - if User.current.allowed_to?(:file_manipulation, issue.project) && - Setting.plugin_redmine_dmsf['dmsf_act_as_attachable'] && - (issue.project.dmsf_act_as_attachable == Project::ATTACHABLE_DMS_AND_ATTACHMENTS) - html = '

' + container = context[:container] + if allowed_to_attach_documents(container) + html = "

" + if label html << "" - html << "" + html << "" + else + html << "" + end html << context[:controller].send(:render_to_string, - { :partial => 'dmsf_upload/form', :locals => { :container => issue, :multiple => true }}) + { :partial => 'dmsf_upload/form', + :locals => { :container => container, :multiple => true, :description => description, :awf => true }}) html << '' html << '

' html.html_safe @@ -102,7 +146,7 @@ module RedmineDmsf end end - def show_attached_documents(container, controller) + def show_attached_documents(container, controller, attachments=nil) # Add list of attached documents links = get_links(container) if links.present? @@ -110,18 +154,23 @@ module RedmineDmsf controller.send(:render_to_string, {:partial => 'dmsf_files/links', :locals => { :links => links, :thumbnails => Setting.thumbnails_enabled? }}) else - attachment_rows(links, container, controller) + attachment_rows(links, container, controller, attachments) end end end - def attachment_rows(links, issue, controller) - html = '' - links.each do |dmsf_file, link, create_at| - html << attachment_row(dmsf_file, link, issue, controller) + def attachment_rows(links, issue, controller, attachments) + if links.any? + html = '' + if attachments.any? + html << "#{l(:label_dmsf_attachments)} (#{links.count})" + end + links.each do |dmsf_file, link, create_at| + html << attachment_row(dmsf_file, link, issue, controller) + end + html << '' + html.html_safe end - html << '' - html.html_safe end def attachment_row(dmsf_file, link, issue, controller) diff --git a/lib/redmine_dmsf/patches/user_preference_patch.rb b/lib/redmine_dmsf/patches/user_preference_patch.rb index b29e79ba..058e23ee 100644 --- a/lib/redmine_dmsf/patches/user_preference_patch.rb +++ b/lib/redmine_dmsf/patches/user_preference_patch.rb @@ -18,22 +18,41 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -module DmsfUserPreference - def self.included(base) - base.send(:include, InstanceMethods) - end +module RedmineDmsf + module Patches + module UserPreference - module InstanceMethods + def self.included(base) + base.send(:include, InstanceMethods) + end - def dmsf_tree_view - self[:dmsf_tree_view] || '1' - end + module InstanceMethods + + def dmsf_tree_view + self[:dmsf_tree_view] || '1' + end + + def dmsf_tree_view=(value) + self[:dmsf_tree_view] = value + end + + def dmsf_attachments_upload_choice + self[:dmsf_attachments_upload_choice] || 'DMSF' + end + + def dmsf_attachments_upload_choice=(value) + self[:dmsf_attachments_upload_choice] = value + end + + end - def dmsf_tree_view=(value) - self[:dmsf_tree_view] = value end end - end -UserPreference.send(:include, DmsfUserPreference) +# Apply patch +Rails.configuration.to_prepare do + unless UserPreference.included_modules.include?(RedmineDmsf::Patches::UserPreference) + UserPreference.send(:include, RedmineDmsf::Patches::UserPreference) + end +end diff --git a/test/functional/dmsf_folder_permissions_controller_test.rb b/test/functional/dmsf_folder_permissions_controller_test.rb index 2f2ce0e2..cbfa0ed1 100644 --- a/test/functional/dmsf_folder_permissions_controller_test.rb +++ b/test/functional/dmsf_folder_permissions_controller_test.rb @@ -21,7 +21,8 @@ require File.expand_path('../../test_helper', __FILE__) class DmsfFolderPermissionsControllerTest < RedmineDmsf::Test::TestCase - fixtures :users, :dmsf_folders, :projects, :roles, :members, :member_roles, :dmsf_folder_permissions + fixtures :users, :dmsf_folders, :projects, :roles, :members, :member_roles, :dmsf_folder_permissions, + :email_addresses def setup @project1 = Project.find_by_id 1