From dc306f1b73853c8c5527c4da0c9747e7de45f4e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Pi=C4=8Dman?= Date: Thu, 13 Feb 2020 14:58:34 +0100 Subject: [PATCH] #1080 Option & Filters --- app/controllers/dmsf_controller.rb | 7 +- app/models/dmsf_author_query_column.rb | 29 ---- app/models/dmsf_folder.rb | 8 +- app/models/dmsf_query.rb | 153 +++++++++++++----- app/views/dmsf/_url.html.erb | 6 +- app/views/dmsf/show.html.erb | 4 +- config/locales/en.yml | 2 + .../patches/queries_helper_patch.rb | 47 +++++- 8 files changed, 179 insertions(+), 77 deletions(-) delete mode 100644 app/models/dmsf_author_query_column.rb diff --git a/app/controllers/dmsf_controller.rb b/app/controllers/dmsf_controller.rb index e00bb0c5..dc703490 100644 --- a/app/controllers/dmsf_controller.rb +++ b/app/controllers/dmsf_controller.rb @@ -75,7 +75,12 @@ class DmsfController < ApplicationController def show @rlf = cookies[:dmsf_switch_rlf] == 'true' if @rlf - @query = DmsfQuery.new(name: 'Dmsf', dmsf_folder: @folder, project: @project) + use_session = !request.format.csv? + @query = retrieve_query(DmsfQuery, use_session) + @query.dmsf_folder_id = @folder ? @folder.id : nil + @query.deleted = false + #@query.project = @project + #@query = DmsfQuery.new(name: 'Dmsf', dmsf_folder: @folder, project: @project) if (@folder && @folder.deleted?) || (params[:folder_title].present? && !@folder) render_404 return diff --git a/app/models/dmsf_author_query_column.rb b/app/models/dmsf_author_query_column.rb deleted file mode 100644 index c51ddd1c..00000000 --- a/app/models/dmsf_author_query_column.rb +++ /dev/null @@ -1,29 +0,0 @@ -# encode: utf-8 -# frozen_string_literal: true -# -# Redmine plugin for Document Management System "Features" -# -# Copyright © 2011-20 Karel Pičman -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# - -class DmsfAuthorQueryColumn < QueryColumn - - def value_object(object) - "#{object.firstname} #{object.lastname}" - end - -end diff --git a/app/models/dmsf_folder.rb b/app/models/dmsf_folder.rb index b0e1373f..e82a9ed8 100644 --- a/app/models/dmsf_folder.rb +++ b/app/models/dmsf_folder.rb @@ -577,7 +577,13 @@ class DmsfFolder < ActiveRecord::Base end def css_classes - 'dir' + classes = ['dir'] + if title =~ /^\./ + classes << 'dmsf_system' + elsif ['DmsfFolderLink', 'DmsfFileLink'].include?(type) + classes << 'dmsf_gray' + end + classes.join(' ') end private diff --git a/app/models/dmsf_query.rb b/app/models/dmsf_query.rb index fcb33481..904e327e 100644 --- a/app/models/dmsf_query.rb +++ b/app/models/dmsf_query.rb @@ -22,26 +22,27 @@ class DmsfQuery < Query - attr_accessor :dmsf_folder, :project + attr_accessor :dmsf_folder_id, :deleted + + self.queried_class = DmsfFolder + self.view_permission = :view_dmsf_files # Standard columns self.available_columns = [ QueryColumn.new(:id, sortable: 'id', caption: '#'), - DmsfTitleQueryColumn.new(:title, frozen: true), - QueryColumn.new(:extension), - QueryColumn.new(:size), - DmsfModifiedQueryColumn.new(:modified), - DmsfVersionQueryColumn.new(:version), - QueryColumn.new(:workflow), - DmsfAuthorQueryColumn.new(:author), + DmsfTitleQueryColumn.new(:title, sortable: 'title', frozen: true), + QueryColumn.new(:extension, sortable: 'extension'), + QueryColumn.new(:size, sortable: 'size'), + DmsfModifiedQueryColumn.new(:modified, sortable: 'updated'), + DmsfVersionQueryColumn.new(:version, sortable: 'major_version, minor_version'), + QueryColumn.new(:workflow, sortable: 'workflow'), + QueryColumn.new(:author, sortable: 'firstname, lastname') ] def initialize(attributes) super attributes self.sort_criteria = [] self.filters = {} - @deleted = false - @dmsf_folder_id = @dmsf_folder ? @dmsf_folder.id : nil end ###################################################################################################################### @@ -51,7 +52,12 @@ class DmsfQuery < Query def available_columns unless @available_columns @available_columns = self.class.available_columns.dup - @available_columns += DmsfFileRevisionCustomField.visible.collect { |cf| QueryCustomFieldColumn.new(cf) } + @available_columns += DmsfFileRevisionCustomField.visible.collect do |cf| + c = QueryCustomFieldColumn.new(cf) + # We would like to prevent grouping in the Option form + c.groupable = false + c + end end @available_columns end @@ -72,19 +78,22 @@ class DmsfQuery < Query end def default_sort_criteria - [['title', 'desc']] + [['title', 'ASC']] end def base_scope unless @scope - @scope = [dmsf_folders_scope, dmsf_folder_links_scope, dmsf_files_scope, dmsf_file_links_scope, dmsf_url_links_scope].inject(:union_all) + @scope = [dmsf_folders_scope, dmsf_folder_links_scope, dmsf_files_scope, dmsf_file_links_scope, dmsf_url_links_scope]. + inject(:union_all) end @scope end # Returns the issue count def dmsf_count - base_scope.count + base_scope. + where(statement). + count rescue ::ActiveRecord::StatementInvalid => e raise StatementInvalid.new(e.message) end @@ -93,11 +102,57 @@ class DmsfQuery < Query 'DmsfQuery' end + def initialize_available_filters + add_available_filter 'author', type: :list, values: lambda { author_values } + add_available_filter 'title', type: :text + add_available_filter 'updated', type: :date_past + add_custom_fields_filters(DmsfFileRevisionCustomField.all) + end + + def statement + unless @statement + filters_clauses = [] + filters.each_key do |field| + v = values_for(field).clone + next unless v and !v.empty? + operator = operator_for(field) + if field == 'author' + if v.delete('me') + v.push(User.current.id.to_s) + end + end + filters_clauses << '(' + sql_for_field(field, operator, v, queried_table_name, field) + ')' + end + filters_clauses.reject!(&:blank?) + if filters_clauses.any? + @statement = filters_clauses.join(' AND '). + gsub("#{queried_class.table_name}.", '') + DmsfFileRevisionCustomField.visible.pluck(:id, :name).each do |id, name| + @statement.gsub!("cf_#{id}", "`#{name}`") + end + end + end + @statement + end + ###################################################################################################################### # New def dmsf_nodes(options={}) - nodes = base_scope. + order_option = ['sort', group_by_sort_order, (options[:order] || sort_clause[0]), 'title'].flatten.reject(&:blank?) + if order_option.size > 2 + DmsfFileRevisionCustomField.visible.pluck(:id, :name).each do |id, name| + order_option[1].gsub!("COALESCE(cf_#{id}.value, '')", "`#{name}`") + end + order_option[1].gsub!(',', " #{$1},") + if order_option[1] =~ /(DESC|ASC)$/ + order_option[1].gsub!(',', " #{$1},") + end + end + + base_scope. + where(statement). + order(order_option). limit(options[:limit]). offset(options[:offset]) end @@ -116,20 +171,24 @@ class DmsfQuery < Query DmsfFolder. select(%{ dmsf_folders.id AS id, + dmsf_folders.project_id AS project_id, + NULL AS revision_id, dmsf_folders.title AS title, NULL AS filename, - NULL AS extensions, + NULL AS extension, NULL AS size, dmsf_folders.updated_at AS updated, NULL AS major_version, NULL AS minor_version, NULL AS workflow, + NULL AS workflow_id, users.firstname AS firstname, - users.lastname AS lastname, + users.lastname AS lastname, + users.id AS author, 'DmsfFolder' AS type, 0 AS sort #{cf_columns}}). joins('LEFT JOIN users ON dmsf_folders.user_id = users.id'). - where(dmsf_folders: { project_id: @project.id, dmsf_folder_id: @dmsf_folder_id, deleted: @deleted }) + where(dmsf_folders: { project_id: project.id, dmsf_folder_id: dmsf_folder_id, deleted: deleted }) end def dmsf_folder_links_scope @@ -140,22 +199,26 @@ class DmsfQuery < Query DmsfLink. select(%{ dmsf_folders.id AS id, - dmsf_folders.title AS title, - NULL AS filename, - NULL AS extensions, + COALESCE(dmsf_folders.project_id, dmsf_links.project_id) AS project_id, + NULL AS revision_id, + dmsf_links.name AS title, + dmsf_folders.title AS filename, + NULL AS extension, NULL AS size, - dmsf_folders.updated_at AS updated, + COALESCE(dmsf_folders.updated_at, dmsf_links.updated_at) AS updated, NULL AS major_version, NULL AS minor_version, NULL AS workflow, + NULL AS workflow_id, users.firstname AS firstname, - users.lastname AS lastname, + users.lastname AS lastname, + users.id AS author, 'DmsfFolderLink' AS type, 0 AS sort #{cf_columns}}). - joins('JOIN dmsf_folders ON dmsf_links.target_id = dmsf_folders.id'). - joins('LEFT JOIN users ON dmsf_folders.user_id = users.id '). - where(dmsf_links: { target_type: 'DmsfFolder', project_id: @project.id, dmsf_folder_id: @dmsf_folder_id, - deleted: @deleted }) + joins('LEFT JOIN dmsf_folders ON dmsf_links.target_id = dmsf_folders.id'). + joins('LEFT JOIN users ON users.id = COALESCE(dmsf_folders.user_id, dmsf_links.user_id)'). + where(dmsf_links: { target_type: 'DmsfFolder', project_id: project.id, dmsf_folder_id: dmsf_folder_id, + deleted: deleted }) end def dmsf_files_scope @@ -166,22 +229,26 @@ class DmsfQuery < Query DmsfFile. select(%{ dmsf_files.id AS id, - dmsf_file_revisions.name AS title, - dmsf_file_revisions.disk_filename AS filename, - SUBSTR(dmsf_file_revisions.disk_filename, POSITION('.' IN dmsf_file_revisions.disk_filename) + 1, LENGTH(dmsf_file_revisions.disk_filename) - POSITION('.' IN dmsf_file_revisions.disk_filename)) AS extensions, + dmsf_files.project_id AS project_id, + dmsf_file_revisions.id AS revision_id, + dmsf_file_revisions.title AS title, + dmsf_file_revisions.name AS filename, + SUBSTR(dmsf_file_revisions.disk_filename, POSITION('.' IN dmsf_file_revisions.disk_filename) + 1, LENGTH(dmsf_file_revisions.disk_filename) - POSITION('.' IN dmsf_file_revisions.disk_filename)) AS extension, dmsf_file_revisions.size AS size, dmsf_file_revisions.updated_at AS updated, dmsf_file_revisions.major_version AS major_version, dmsf_file_revisions.minor_version AS minor_version, dmsf_file_revisions.workflow AS workflow, + dmsf_file_revisions.dmsf_workflow_id AS workflow_id, users.firstname AS firstname, - users.lastname AS lastname, + users.lastname AS lastname, + users.id AS author, 'DmsfFile' AS type, 1 AS sort #{cf_columns}}). joins(:dmsf_file_revisions). joins('LEFT JOIN users ON dmsf_file_revisions.user_id = users.id '). where('dmsf_file_revisions.created_at = (SELECT MAX(r.created_at) FROM dmsf_file_revisions r WHERE r.dmsf_file_id = dmsf_file_revisions.dmsf_file_id)'). - where(dmsf_files: { project_id: @project.id, dmsf_folder_id: @dmsf_folder_id, deleted: @deleted }) + where(dmsf_files: { project_id: project.id, dmsf_folder_id: dmsf_folder_id, deleted: deleted }) end def dmsf_file_links_scope @@ -192,23 +259,27 @@ class DmsfQuery < Query DmsfLink. select(%{ dmsf_files.id AS id, + dmsf_files.project_id AS project_id, + dmsf_file_revisions.id AS revision_id, dmsf_links.name AS title, - dmsf_file_revisions.disk_filename AS filename, - SUBSTR(dmsf_file_revisions.disk_filename, POSITION('.' IN dmsf_file_revisions.disk_filename) + 1, LENGTH(dmsf_file_revisions.disk_filename) - POSITION('.' IN dmsf_file_revisions.disk_filename)) AS extensions, + dmsf_file_revisions.name AS filename, + SUBSTR(dmsf_file_revisions.disk_filename, POSITION('.' IN dmsf_file_revisions.disk_filename) + 1, LENGTH(dmsf_file_revisions.disk_filename) - POSITION('.' IN dmsf_file_revisions.disk_filename)) AS extension, dmsf_file_revisions.size AS size, dmsf_file_revisions.updated_at AS updated, dmsf_file_revisions.major_version AS major_version, dmsf_file_revisions.minor_version AS minor_version, dmsf_file_revisions.workflow AS workflow, + dmsf_file_revisions.dmsf_workflow_id AS workflow_id, users.firstname AS firstname, - users.lastname AS lastname, + users.lastname AS lastname, + users.id AS author, 'DmsfFileLink' AS type, 1 AS sort #{cf_columns}}). joins('JOIN dmsf_files ON dmsf_files.id = dmsf_links.target_id'). joins('JOIN dmsf_file_revisions ON dmsf_file_revisions.dmsf_file_id = dmsf_files.id'). joins('LEFT JOIN users ON dmsf_file_revisions.user_id = users.id '). where('dmsf_file_revisions.created_at = (SELECT MAX(r.created_at) FROM dmsf_file_revisions r WHERE r.dmsf_file_id = dmsf_file_revisions.dmsf_file_id)'). - where(dmsf_files: { project_id: @project.id, dmsf_folder_id: @dmsf_folder_id, deleted: @deleted }) + where(dmsf_files: { project_id: project.id, dmsf_folder_id: dmsf_folder_id, deleted: deleted }) end def dmsf_url_links_scope @@ -219,20 +290,24 @@ class DmsfQuery < Query DmsfLink. select(%{ dmsf_links.id AS id, + dmsf_links.project_id AS project_id, + NULL AS revision_id, dmsf_links.name AS title, dmsf_links.external_url AS filename, - NULL AS extensions, + NULL AS extension, NULL AS size, dmsf_links.updated_at AS updated, NULL AS major_version, NULL AS minor_version, NULL AS workflow, + NULL AS workflow_id, users.firstname AS firstname, - users.lastname AS lastname, + users.lastname AS lastname, + users.id AS author, 'DmsfUrlLink' AS type, 1 AS sort #{cf_columns}}). joins('LEFT JOIN users ON dmsf_links.user_id = users.id '). - where(target_type: 'DmsfUrl', project_id: @project.id, dmsf_folder_id: @dmsf_folder_id, deleted: @deleted) + where(target_type: 'DmsfUrl', project_id: project.id, dmsf_folder_id: dmsf_folder_id, deleted: deleted) end end diff --git a/app/views/dmsf/_url.html.erb b/app/views/dmsf/_url.html.erb index b80bc40a..bfc7e52d 100644 --- a/app/views/dmsf/_url.html.erb +++ b/app/views/dmsf/_url.html.erb @@ -30,9 +30,9 @@ > <% end %> <%= link_to(h(title), - link.external_url, - :target => '_blank', - :class => 'icon icon-link') %> + link.external_url, + :target => '_blank', + :class => 'icon icon-link') %>
<% if link.external_url && link.external_url.length > 50 %> <%= "#{link.external_url[0, 25]}...#{link.external_url[-25, 25]}" %> diff --git a/app/views/dmsf/show.html.erb b/app/views/dmsf/show.html.erb index 858643ec..fed8fd64 100644 --- a/app/views/dmsf/show.html.erb +++ b/app/views/dmsf/show.html.erb @@ -91,7 +91,7 @@
<% if @query %> - <%= form_tag(dmsf_path(@project, @folder), method: :get, id: 'query_form') do %> + <%= form_tag(dmsf_folder_path(d: @project, folder_id: @folder), method: :get, id: 'query_form') do %> <%= render partial: 'queries/query_form' %> <% end %> <%= render partial: 'query_list', locals: { query: @query } %> @@ -258,4 +258,4 @@ <%= submit_tag l(:button_cancel), name: nil, onclick: "hideModal(this);", type: 'button' %>

<% end %> - + \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index 72a66c7c..2358fcf0 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -416,6 +416,8 @@ en: button_edit_content: Edit content field_workflow: Workflow field_modified: Updated + field_extension: Ext. + field_updated: Updated easy_pages: modules: diff --git a/lib/redmine_dmsf/patches/queries_helper_patch.rb b/lib/redmine_dmsf/patches/queries_helper_patch.rb index 3d51329f..a80726cc 100644 --- a/lib/redmine_dmsf/patches/queries_helper_patch.rb +++ b/lib/redmine_dmsf/patches/queries_helper_patch.rb @@ -29,16 +29,59 @@ module RedmineDmsf # Overridden methods def column_value(column, item, value) + unless item.is_a? DmsfFolder + return super column, item, value + end case column.name - when :title + when :id case item.type when 'DmsfFile', 'DmsfFileLink' - h(value) + content_tag('div', item.filename, class: 'dmsf_filename', title: l(:title_filename_for_download)) + link_to h(value), dmsf_file_path(id: item.id) + when 'DmsfFolder', 'DmsfFolderLink' + if(item.id) + link_to h(value), edit_dmsf_path(id: item.project_id, folder_id: item.id) + else + link_to h(item.project_id), edit_root_dmsf_path(id: item.project_id) + end + else + h(value) + end + when :author + link_to "#{item.firstname} #{item.lastname}", user_path(id: value) + when :title + case item.type + when 'DmsfFolder', 'DmsfFolderLink' + link_to(h(value), + dmsf_folder_path(id: item.project_id, folder_id: item.id), + class: 'icon icon-folder', + title: h(value)) + + content_tag('div', item.filename, class: 'dmsf_filename', title: l(:title_filename_for_download)) + when 'DmsfFile', 'DmsfFileLink' + file_view_url = url_for({ controller: :dmsf_files, action: 'view', id: item.id }) + content_type = Redmine::MimeType.of(value) + content_type = 'application/octet-stream' if content_type.blank? + link_to(h(value), + file_view_url, + target: '_blank', + class: "icon icon-file #{DmsfHelper.filetype_css(item.filename)}", + title: h(value), + 'data-downloadurl': "#{content_type}:#{h(value)}:#{file_view_url}") + + content_tag('div', item.filename, class: 'dmsf_filename', title: l(:title_filename_for_download)) + when 'DmsfUrlLink' + link_to(h(value), item.filename, target: '_blank', class: 'icon icon-link') + + content_tag('div', item.filename, class: 'dmsf_filename', title: l(:title_filename_for_download)) else h(value) end when :size number_to_human_size(value) + when :workflow + if value + link_to h(DmsfWorkflowStepAction.workflow_str(value)), + log_dmsf_workflow_path(project_id: item.project_id, id: item.workflow_id, + dmsf_file_revision_id: item.revision_id), + remote: true + end else super column, item, value end