From 67e2fe95612a4c9a0f6d1b2542608bd7d00ebbd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Pi=C4=8Dman?= Date: Fri, 7 Feb 2020 17:25:05 +0100 Subject: [PATCH] #1080 New view --- Gemfile | 1 + app/controllers/dmsf_controller.rb | 30 +- app/models/dmsf_author_query_column.rb | 29 ++ app/models/dmsf_file.rb | 2 +- app/models/dmsf_folder.rb | 9 +- app/models/dmsf_link.rb | 2 +- app/models/dmsf_modified_query_column.rb | 29 ++ app/models/dmsf_query.rb | 238 ++++++++++++++ app/models/dmsf_title_query_column.rb | 29 ++ app/models/dmsf_version_query_column.rb | 29 ++ app/views/dmsf/_dir.html.erb | 2 +- app/views/dmsf/_dir_trash.html.erb | 2 +- app/views/dmsf/_file.html.erb | 2 +- app/views/dmsf/_file_trash.html.erb | 2 +- app/views/dmsf/_list_view.erb | 2 +- app/views/dmsf/_query_list.html.erb | 57 ++++ app/views/dmsf/_tree_view.erb | 2 +- app/views/dmsf/_url.html.erb | 2 +- app/views/dmsf/_url_trash.html.erb | 2 +- app/views/dmsf/show.html.erb | 297 +++++++++--------- app/views/dmsf/trash.html.erb | 2 +- app/views/settings/_dmsf_columns.html.erb | 2 +- assets/stylesheets/redmine_dmsf.css | 6 +- config/locales/cs.yml | 2 + config/locales/de.yml | 2 + config/locales/en.yml | 2 + config/locales/es.yml | 2 + config/locales/fr.yml | 2 + config/locales/hu.yml | 2 + config/locales/it.yml | 2 + config/locales/ja.yml | 2 + config/locales/ko.yml | 2 + config/locales/nl.yml | 2 + config/locales/pl.yml | 2 + config/locales/pt-BR.yml | 2 + config/locales/ru.yml | 2 + config/locales/sl.yml | 2 + config/locales/zh-TW.yml | 2 + config/locales/zh.yml | 2 + config/routes.rb | 6 +- lib/redmine_dmsf.rb | 1 + .../patches/queries_helper_patch.rb | 52 +++ 42 files changed, 705 insertions(+), 164 deletions(-) create mode 100644 app/models/dmsf_author_query_column.rb create mode 100644 app/models/dmsf_modified_query_column.rb create mode 100644 app/models/dmsf_query.rb create mode 100644 app/models/dmsf_title_query_column.rb create mode 100644 app/models/dmsf_version_query_column.rb create mode 100644 app/views/dmsf/_query_list.html.erb create mode 100644 lib/redmine_dmsf/patches/queries_helper_patch.rb diff --git a/Gemfile b/Gemfile index 702cc5dc..e823ed4d 100644 --- a/Gemfile +++ b/Gemfile @@ -25,6 +25,7 @@ gem 'zip-zip' gem 'simple_enum' gem 'uuidtools' gem 'dalli' +gem 'active_record_union' # Redmine extensions unless %w(easyproject easy_gantt).any? { |plugin| Dir.exist?(File.expand_path("../../#{plugin}", __FILE__)) } diff --git a/app/controllers/dmsf_controller.rb b/app/controllers/dmsf_controller.rb index 14dad845..e00bb0c5 100644 --- a/app/controllers/dmsf_controller.rb +++ b/app/controllers/dmsf_controller.rb @@ -37,8 +37,10 @@ class DmsfController < ApplicationController accept_api_auth :show, :create, :save, :delete - helper :all + helper :all # TODO: Is it needed? helper :dmsf_folder_permissions + helper :queries + include QueriesHelper def permissions render_403 unless DmsfFolder.permissions?(@folder, false) @@ -71,7 +73,31 @@ class DmsfController < ApplicationController end def show - Rails.logger.info ">>> RLF get: #{cookies[:dmsf_switch_rlf]}" + @rlf = cookies[:dmsf_switch_rlf] == 'true' + if @rlf + @query = DmsfQuery.new(name: 'Dmsf', dmsf_folder: @folder, project: @project) + if (@folder && @folder.deleted?) || (params[:folder_title].present? && !@folder) + render_404 + return + end + respond_to do |format| + format.html { + @dmsf_count = @query.dmsf_count + @dmsf_pages = Paginator.new @issue_count, per_page_option, params['page'] + @dmsf_nodes = @query.dmsf_nodes(offset: @dmsf_pages.offset, limit: @dmsf_pages.per_page) + render layout: !request.xhr? + } + format.api + format.csv { + filename = @project.name + filename << "_#{@folder.title}" if @folder + filename << DateTime.current.strftime('_%Y%m%d%H%M%S.csv') + send_data(DmsfHelper.dmsf_to_csv(@folder ? @folder : @project, params[:settings][:dmsf_columns]), + :type => 'text/csv; header=present', :filename => filename) + } + end + return + end get_display_params if (@folder && @folder.deleted?) || (params[:folder_title].present? && !@folder) render_404 diff --git a/app/models/dmsf_author_query_column.rb b/app/models/dmsf_author_query_column.rb new file mode 100644 index 00000000..c51ddd1c --- /dev/null +++ b/app/models/dmsf_author_query_column.rb @@ -0,0 +1,29 @@ +# 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_file.rb b/app/models/dmsf_file.rb index 029ce8ae..6ba4a6c9 100644 --- a/app/models/dmsf_file.rb +++ b/app/models/dmsf_file.rb @@ -580,7 +580,7 @@ class DmsfFile < ActiveRecord::Base end end # Custom fields - CustomField.where(type: 'DmsfFileRevisionCustomField').order(:position).each do |c| + DmsfFileRevisionCustomField.visible.order(:position).each do |c| csv << custom_value(c).value if columns.include?(c.name) end csv diff --git a/app/models/dmsf_folder.rb b/app/models/dmsf_folder.rb index 3aa9ab12..b0e1373f 100644 --- a/app/models/dmsf_folder.rb +++ b/app/models/dmsf_folder.rb @@ -317,6 +317,7 @@ class DmsfFolder < ActiveRecord::Base last_update end + # Number of items in the folder def items dmsf_folders.visible.where(project_id: project_id).all.size + @@ -401,7 +402,7 @@ class DmsfFolder < ActiveRecord::Base return nil if column == 'author' end # 9 - custom fields - CustomField.where(type: 'DmsfFileRevisionCustomField').each do |c| + DmsfFileRevisionCustomField.visible.each do |c| if DmsfFolder.is_column_on?(c.name) pos += 1 end @@ -460,7 +461,7 @@ class DmsfFolder < ActiveRecord::Base # Revision csv << '' if columns.include?(l(:label_last_revision_id)) # Custom fields - CustomField.where(type: 'DmsfFileRevisionCustomField').order(:position).each do |c| + DmsfFileRevisionCustomField.visible.order(:position).each do |c| csv << custom_value(c).value if columns.include?(c.name) end csv @@ -575,6 +576,10 @@ class DmsfFolder < ActiveRecord::Base end end + def css_classes + 'dir' + end + private def self.directory_subtree(tree, folder, level, current_folder) diff --git a/app/models/dmsf_link.rb b/app/models/dmsf_link.rb index c2646592..ac57b7bf 100644 --- a/app/models/dmsf_link.rb +++ b/app/models/dmsf_link.rb @@ -192,7 +192,7 @@ class DmsfLink < ActiveRecord::Base # Revision csv << '' if columns.include?(l(:label_last_revision_id)) # Custom fields - CustomField.where(type: 'DmsfFileRevisionCustomField').order(:position).each do |c| + DmsfFileRevisionCustomField.visible.order(:position).each do |c| csv << '' if columns.include?(c.name) end end diff --git a/app/models/dmsf_modified_query_column.rb b/app/models/dmsf_modified_query_column.rb new file mode 100644 index 00000000..4e99fc92 --- /dev/null +++ b/app/models/dmsf_modified_query_column.rb @@ -0,0 +1,29 @@ +# 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 DmsfModifiedQueryColumn < QueryColumn + + def value_object(object) + object.updated + end + +end diff --git a/app/models/dmsf_query.rb b/app/models/dmsf_query.rb new file mode 100644 index 00000000..fcb33481 --- /dev/null +++ b/app/models/dmsf_query.rb @@ -0,0 +1,238 @@ +# 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 DmsfQuery < Query + + attr_accessor :dmsf_folder, :project + + # 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), + ] + + def initialize(attributes) + super attributes + self.sort_criteria = [] + self.filters = {} + @deleted = false + @dmsf_folder_id = @dmsf_folder ? @dmsf_folder.id : nil + end + + ###################################################################################################################### + # Inherited + # + + def available_columns + unless @available_columns + @available_columns = self.class.available_columns.dup + @available_columns += DmsfFileRevisionCustomField.visible.collect { |cf| QueryCustomFieldColumn.new(cf) } + end + @available_columns + end + + def default_columns_names + unless @default_column_names + @default_column_names = [] + columns = available_columns + if columns + columns.each do |column| + if DmsfFolder.is_column_on?(column.name.to_s) + @default_column_names << column.name.to_sym + end + end + end + end + @default_column_names + end + + def default_sort_criteria + [['title', 'desc']] + 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) + end + @scope + end + + # Returns the issue count + def dmsf_count + base_scope.count + rescue ::ActiveRecord::StatementInvalid => e + raise StatementInvalid.new(e.message) + end + + def type + 'DmsfQuery' + end + + ###################################################################################################################### + # New + + def dmsf_nodes(options={}) + nodes = base_scope. + limit(options[:limit]). + offset(options[:offset]) + end + + def extra_columns + [] + end + + private + + def dmsf_folders_scope + cf_columns = +'' + DmsfFileRevisionCustomField.visible.order(:position).pluck(:id, :name).each do |id, name| + cf_columns << ",(SELECT value from custom_values WHERE custom_field_id = #{id} AND customized_type = 'DmsfFolder' AND customized_id = dmsf_folders.id) AS `#{name}`" + end + DmsfFolder. + select(%{ + dmsf_folders.id AS id, + dmsf_folders.title AS title, + NULL AS filename, + NULL AS extensions, + NULL AS size, + dmsf_folders.updated_at AS updated, + NULL AS major_version, + NULL AS minor_version, + NULL AS workflow, + users.firstname AS firstname, + users.lastname AS lastname, + '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 }) + end + + def dmsf_folder_links_scope + cf_columns = +'' + DmsfFileRevisionCustomField.visible.order(:position).pluck(:id, :name).each do |id, name| + cf_columns << ",(SELECT value from custom_values WHERE custom_field_id = #{id} AND customized_type = 'DmsfFolder' AND customized_id = dmsf_folders.id) AS `#{name}`" + end + DmsfLink. + select(%{ + dmsf_folders.id AS id, + dmsf_folders.title AS title, + NULL AS filename, + NULL AS extensions, + NULL AS size, + dmsf_folders.updated_at AS updated, + NULL AS major_version, + NULL AS minor_version, + NULL AS workflow, + users.firstname AS firstname, + users.lastname AS lastname, + '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 }) + end + + def dmsf_files_scope + cf_columns = +'' + DmsfFileRevisionCustomField.visible.order(:position).pluck(:id, :name).each do |id, name| + cf_columns << ",(SELECT value from custom_values WHERE custom_field_id = #{id} AND customized_type = 'DmsfFolder' AND customized_id = dmsf_files.id) AS `#{name}`" + end + 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_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, + users.firstname AS firstname, + users.lastname AS lastname, + '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 }) + end + + def dmsf_file_links_scope + cf_columns = +'' + DmsfFileRevisionCustomField.visible.order(:position).pluck(:id, :name).each do |id, name| + cf_columns << ",(SELECT value from custom_values WHERE custom_field_id = #{id} AND customized_type = 'DmsfFolder' AND customized_id = dmsf_files.id) AS `#{name}`" + end + DmsfLink. + select(%{ + dmsf_files.id AS 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.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, + users.firstname AS firstname, + users.lastname AS lastname, + '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 }) + end + + def dmsf_url_links_scope + cf_columns = +'' + DmsfFileRevisionCustomField.visible.order(:position).pluck(:name).each do |name| + cf_columns << ",NULL AS `#{name}`" + end + DmsfLink. + select(%{ + dmsf_links.id AS id, + dmsf_links.name AS title, + dmsf_links.external_url AS filename, + NULL AS extensions, + NULL AS size, + dmsf_links.updated_at AS updated, + NULL AS major_version, + NULL AS minor_version, + NULL AS workflow, + users.firstname AS firstname, + users.lastname AS lastname, + '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) + end + +end diff --git a/app/models/dmsf_title_query_column.rb b/app/models/dmsf_title_query_column.rb new file mode 100644 index 00000000..876fa9f1 --- /dev/null +++ b/app/models/dmsf_title_query_column.rb @@ -0,0 +1,29 @@ +# 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 DmsfTitleQueryColumn < QueryColumn + + def css_classes + 'dmsf_title' + end + +end diff --git a/app/models/dmsf_version_query_column.rb b/app/models/dmsf_version_query_column.rb new file mode 100644 index 00000000..2e9dfbbb --- /dev/null +++ b/app/models/dmsf_version_query_column.rb @@ -0,0 +1,29 @@ +# 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 DmsfVersionQueryColumn < QueryColumn + + def value_object(object) + "#{object.major_version}.#{object.minor_version}" if object.major_version && object.minor_version + end + +end diff --git a/app/views/dmsf/_dir.html.erb b/app/views/dmsf/_dir.html.erb index b0b90fca..37a71720 100644 --- a/app/views/dmsf/_dir.html.erb +++ b/app/views/dmsf/_dir.html.erb @@ -72,7 +72,7 @@ <% if DmsfFolder.is_column_on?('author') %> <%= h(subfolder.user) if subfolder %> <% end %> -<% CustomField.where(type: 'DmsfFileRevisionCustomField').order(:position).each do |c| %> +<% DmsfFileRevisionCustomField.visible.order(:position).each do |c| %> <% if DmsfFolder.is_column_on?(c.name) %> <%= show_value(subfolder.custom_value(c)) if subfolder %> diff --git a/app/views/dmsf/_dir_trash.html.erb b/app/views/dmsf/_dir_trash.html.erb index d612721b..8f835a57 100644 --- a/app/views/dmsf/_dir_trash.html.erb +++ b/app/views/dmsf/_dir_trash.html.erb @@ -56,7 +56,7 @@ <% if DmsfFolder.is_column_on?('author') %> <%= h(subfolder.user) if subfolder %> <% end %> -<% CustomField.where(type: 'DmsfFileRevisionCustomField').order(:position).each do |c| %> +<% DmsfFileRevisionCustomField.visible.order(:position).each do |c| %> <% if DmsfFolder.is_column_on?(c.name) %> <%= show_value(subfolder.custom_value(c)) if subfolder %> diff --git a/app/views/dmsf/_file.html.erb b/app/views/dmsf/_file.html.erb index fd5a706c..53d76511 100644 --- a/app/views/dmsf/_file.html.erb +++ b/app/views/dmsf/_file.html.erb @@ -76,7 +76,7 @@ <% if DmsfFolder.is_column_on?('author') %> <%= h(file.last_revision.user) %> <% end %> -<% CustomField.where(type: 'DmsfFileRevisionCustomField').order(:position).each do |c| %> +<% DmsfFileRevisionCustomField.visible.order(:position).each do |c| %> <% if DmsfFolder.is_column_on?(c.name) %> <%= show_value file.custom_value(c) %> diff --git a/app/views/dmsf/_file_trash.html.erb b/app/views/dmsf/_file_trash.html.erb index 4784678f..355171b8 100644 --- a/app/views/dmsf/_file_trash.html.erb +++ b/app/views/dmsf/_file_trash.html.erb @@ -56,7 +56,7 @@ <% if DmsfFolder.is_column_on?('author') %> <%= h(file.last_revision.user) %> <% end %> -<% CustomField.where(type: 'DmsfFileRevisionCustomField').order(:position).each do |c| %> +<% DmsfFileRevisionCustomField.visible.order(:position).each do |c| %> <% if DmsfFolder.is_column_on?(c.name) %> <%= show_value file.custom_value(c) %> diff --git a/app/views/dmsf/_list_view.erb b/app/views/dmsf/_list_view.erb index 529d9af0..b31b41be 100644 --- a/app/views/dmsf/_list_view.erb +++ b/app/views/dmsf/_list_view.erb @@ -53,7 +53,7 @@ <% if DmsfFolder.is_column_on?('author') %> <%= l(:link_author) %> <% end %> - <% CustomField.where(type: 'DmsfFileRevisionCustomField').order(:position).each do |c| %> + <% DmsfFileRevisionCustomField.visible.order(:position).each do |c| %> <% if DmsfFolder.is_column_on?(c.name) %> <%= h(c.name) %> <% end %> diff --git a/app/views/dmsf/_query_list.html.erb b/app/views/dmsf/_query_list.html.erb new file mode 100644 index 00000000..3fe93d15 --- /dev/null +++ b/app/views/dmsf/_query_list.html.erb @@ -0,0 +1,57 @@ +<% +# encoding: utf-8 +# +# 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. +%> + +<% query_options = nil unless defined?(query_options) %> +<% query_options ||= {} %> + +<%= form_tag({}, data: { cm_url: dmsf_context_menu_path }) do %> + <%= hidden_field_tag 'back_url', url_for( params: request.query_parameters), id: nil %> + <%= query_columns_hidden_tags(query) %> +
+ + + + + <% query.inline_columns.each do |column| %> + <%= column_header(query, column, query_options) %> + <% end %> + + + + + <% level = 0 %> + <% query.dmsf_nodes.each do |node| %> + "> + + <% query.inline_columns.each do |column| %> + <%= content_tag('td', column_content(column, node), class: column.css_classes) %> + <% end %> + + + <% end %> + +
+ <%= check_box_tag 'check_all', '', false, class: 'toggle-selection', + title: "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %> +
<%= check_box_tag("ids[]", node.id, false, id: nil) %><%= link_to_context_menu %>
+
+<% end %> diff --git a/app/views/dmsf/_tree_view.erb b/app/views/dmsf/_tree_view.erb index 2c414cf7..f26b371e 100644 --- a/app/views/dmsf/_tree_view.erb +++ b/app/views/dmsf/_tree_view.erb @@ -53,7 +53,7 @@ <% if DmsfFolder.is_column_on?('author') %> <%= l(:link_author) %> <% end %> - <% CustomField.where(type: 'DmsfFileRevisionCustomField').order(:position).each do |c| %> + <% DmsfFileRevisionCustomField.visible.order(:position).each do |c| %> <% if DmsfFolder.is_column_on?(c.name) %> <%= c.name %> <% end %> diff --git a/app/views/dmsf/_url.html.erb b/app/views/dmsf/_url.html.erb index e6b93111..b80bc40a 100644 --- a/app/views/dmsf/_url.html.erb +++ b/app/views/dmsf/_url.html.erb @@ -61,7 +61,7 @@ <% if DmsfFolder.is_column_on?('author') %> <%= h(link.user) %> <% end %> -<% CustomField.where(type: 'DmsfFileRevisionCustomField').order(:position).each do |c| %> +<% DmsfFileRevisionCustomField.visible.order(:position).each do |c| %> <% if DmsfFolder.is_column_on?(c.name) %> <% end %> diff --git a/app/views/dmsf/_url_trash.html.erb b/app/views/dmsf/_url_trash.html.erb index c7ceb139..94554a64 100644 --- a/app/views/dmsf/_url_trash.html.erb +++ b/app/views/dmsf/_url_trash.html.erb @@ -57,7 +57,7 @@ <% if DmsfFolder.is_column_on?('author') %> <%= h(link.user) %> <% end %> -<% CustomField.where(type: 'DmsfFileRevisionCustomField').order(:position).each do |c| %> +<% DmsfFileRevisionCustomField.visible.order(:position).each do |c| %> <% if DmsfFolder.is_column_on?(c.name) %> <% end %> diff --git a/app/views/dmsf/show.html.erb b/app/views/dmsf/show.html.erb index 00f0d711..858643ec 100644 --- a/app/views/dmsf/show.html.erb +++ b/app/views/dmsf/show.html.erb @@ -90,165 +90,172 @@ -
-<%= form_tag(entries_operations_dmsf_path(id: @project, folder_id: @folder), method: :post, - class: 'dmsf_entries', id: 'entries_form', data: { cm_url: dmsf_context_menu_path }) do %> - <%= hidden_field_tag('action') %> - <% unless @system_folder %> -
- <%= submit_tag(l(:button_download), title: l(:title_download_checked), name: 'download_entries', - class: 'toggle-selection', data: { disable_with: false }) if @file_view_allowed %> - <%= submit_tag(l(:field_mail), title: l(:title_send_checked_by_email), name: 'email_entries', class: 'toggle-selection', - data: { disable_with: false }) if (@file_view_allowed && User.current.allowed_to?(:email_documents, @project)) %> - <% if @file_delete_allowed %> - <%= submit_tag(l(:button_delete), title: l(:title_delete_checked), name: 'delete_entries', class: 'toggle-selection', - data: { confirm: l(:text_are_you_sure), disable_with: false }) if @file_delete_allowed %> - <% end %> -
+<% if @query %> + <%= form_tag(dmsf_path(@project, @folder), method: :get, id: 'query_form') do %> + <%= render partial: 'queries/query_form' %> <% end %> - <% unless @system_folder %> - <% values = @folder ? @folder.custom_field_values : DmsfFolder.new.custom_field_values %> - <% unless values.empty? %> - <% values.sort! { |a, b| a.custom_field.position <=> b.custom_field.position } %> - <% custom_value = values.first %> - <% if custom_value.custom_field.format.is_a?(Redmine::FieldFormat::ListFormat) %> -
- <% custom_value.custom_field.is_required = false %> - <% custom_value.value = params[:custom_value].present? ? params[:custom_value] : '' %> - <%= h(custom_value.custom_field.name) %>: - <%= custom_value.custom_field.format.edit_tag(self, - custom_field_tag_id(:dmsf_folder, custom_value.custom_field), - custom_field_tag_name(:dmsf_folder, custom_value.custom_field), - custom_value, - :class => "#{custom_value.custom_field.field_format}_cf", - :style => 'width: auto') %> -
+ <%= render partial: 'query_list', locals: { query: @query } %> +<% else %> +
+ <%= form_tag(entries_operations_dmsf_path(id: @project, folder_id: @folder), method: :post, + class: 'dmsf_entries', id: 'entries_form', data: { cm_url: dmsf_context_menu_path }) do %> + <%= hidden_field_tag('action') %> + <% unless @system_folder %> +
+ <%= submit_tag(l(:button_download), title: l(:title_download_checked), name: 'download_entries', + class: 'toggle-selection', data: { disable_with: false }) if @file_view_allowed %> + <%= submit_tag(l(:field_mail), title: l(:title_send_checked_by_email), name: 'email_entries', class: 'toggle-selection', + data: { disable_with: false }) if (@file_view_allowed && User.current.allowed_to?(:email_documents, @project)) %> + <% if @file_delete_allowed %> + <%= submit_tag(l(:button_delete), title: l(:title_delete_checked), name: 'delete_entries', class: 'toggle-selection', + data: { confirm: l(:text_are_you_sure), disable_with: false }) if @file_delete_allowed %> + <% end %> +
+ <% end %> + <% unless @system_folder %> + <% values = @folder ? @folder.custom_field_values : DmsfFolder.new.custom_field_values %> + <% unless values.empty? %> + <% values.sort! { |a, b| a.custom_field.position <=> b.custom_field.position } %> + <% custom_value = values.first %> + <% if custom_value.custom_field.format.is_a?(Redmine::FieldFormat::ListFormat) %> +
+ <% custom_value.custom_field.is_required = false %> + <% custom_value.value = params[:custom_value].present? ? params[:custom_value] : '' %> + <%= h(custom_value.custom_field.name) %>: + <%= custom_value.custom_field.format.edit_tag(self, + custom_field_tag_id(:dmsf_folder, custom_value.custom_field), + custom_field_tag_name(:dmsf_folder, custom_value.custom_field), + custom_value, + :class => "#{custom_value.custom_field.field_format}_cf", + :style => 'width: auto') %> +
+ <% end %> <% end %> <% end %> - <% end %> - <% if @tree_view %> - <%= render(:partial => 'tree_view') %> - <% else %> - <%= render(:partial => 'list_view') %> - <% end %> -<% end %> - -<%= context_menu %> - -<% content_for :header_tags do %> - <%= stylesheet_link_tag 'jquery.dataTables/datatables.min.css', :plugin => :redmine_dmsf %> - <%= javascript_include_tag 'jquery.dataTables/datatables.min.js', :plugin => :redmine_dmsf, defer: true %> - - <% title = DmsfFolder.get_column_position('title') %> - <% position = DmsfFolder.get_column_position('position') %> - <% commands = DmsfFolder.get_column_position('commands') %> - <% position = DmsfFolder.get_column_position('position') %> - <% version = DmsfFolder.get_column_position('version') %> - <% size_calculated = DmsfFolder.get_column_position('size_calculated') %> - <% modified_calculated = DmsfFolder.get_column_position('modified_calculated') %> - <% version_calculated = DmsfFolder.get_column_position('version_calculated') %> - <% size = DmsfFolder.get_column_position('size') %> - <% modified = DmsfFolder.get_column_position('modified') %> - <% clear_title = DmsfFolder.get_column_position('clear_title') %> - - <%= late_javascript_tag do %> - $("#browser").dataTable({ - orderClasses: false, - responsive: { - details: false - }, - language: { - url: "<%= plugin_asset_path(:redmine_dmsf, 'javascripts', json_url) %>" - }, - oLanguage: { - sSearch: "<%= l(:description_filter) %>:" - }, - autoWidth: false, - paginate: false, - <% if title %> - order: [[<%= title %>, "asc"]], - <% end %> - sortingFixed: [[ <%= position %>, "asc"]], - columnDefs: [ - { responsivePriority: 1, targets: <%= title %> }, - { responsivePriority: 2, targets: <%= commands %> }, - { searchable: false, targets: [0, <%= commands %>, <%= position %>, <%= size_calculated %>, <%= modified_calculated %>, <%= version_calculated %>, <%= clear_title %>] }, - { sortable: false, targets: [0, <%= commands %>] } - <% if title %> - ,{ iDataSort: <%= clear_title %>, targets: [ <%= title %> ] } - <% end %> - <% if size %> - ,{ iDataSort: <%= size_calculated %>, targets: [ <%= size %> ] } - <% end %> - <% if modified %> - ,{ iDataSort: <%= modified_calculated %>, targets: [ <%= modified %> ] } - <% end %> - <% if version %> - ,{ iDataSort: <%= version_calculated %>, targets: [ <%= version %> ] } - <% end %> - ], - "fnInitComplete": function() { - var browserFilter = $("#browser_filter"); - $("#dmsf_buttons").insertBefore(browserFilter); - $("#dmsf_tag").insertBefore(browserFilter); - $("#dmsf_ajax_loading").hide(); - $("#browser").show(); - $("#dmsf_buttons").show(); - $("#dmsf_tag").show(); - $("#dmsf_uploader").show(); - $("#dmsf_uploader_header").show(); - }, - "fnInfoCallback": function( oSettings, iStart, iEnd, iMax, iTotal, sPre ) { - <% folder_id = @folder ? @folder.id : nil %> - return "<%= "#{l(:label_number_of_folders)}: #{DmsfFolder.visible.where(project_id: @project.id, dmsf_folder_id: folder_id).all.size + DmsfLink.visible.where(project_id: @project.id, dmsf_folder_id: folder_id, target_type: 'DmsfFolder').all.size}, #{l(:label_number_of_documents)}: #{DmsfFile.visible.where(project_id: @project.id, dmsf_folder_id: folder_id).all.size + DmsfLink.visible.where(project_id: @project.id, dmsf_folder_id: folder_id, target_type: %w(DmsfFile DmsfUrl)).all.size}" %>"; - } - }); - - $("[data-downloadurl]").each(function() { - var url = this.getAttribute("data-downloadurl"); - if (this.addEventListener) { - this.addEventListener("dragstart", function(e) { - if (e.dataTransfer) { - e.dataTransfer.setData("DownloadURL", url); - } - },false); - } - }); - - var entriesForm = $('#entries_form'); - - entriesForm.submit(function () { - $(this).removeAttr("data-submitted"); - }); - - $('.list_cf').change(function() { - entriesForm.attr('action', "<%= tag_changed_path(:id => @project, :folder_id => @folder) %>"); - entriesForm.submit(); - }); + <% if @tree_view %> + <%= render(:partial => 'tree_view') %> + <% else %> + <%= render(:partial => 'list_view') %> <% end %> -<% end %> + <% end %> -<% if @file_manipulation_allowed && !@locked_for_user && !@system_folder %> - <%= render(:partial => 'dmsf_upload/multi_upload', local: { rlf: @rlf }) %> -<% end %> + <%= context_menu %> -<% unless @system_folder %> + <% content_for :header_tags do %> + <%= stylesheet_link_tag 'jquery.dataTables/datatables.min.css', :plugin => :redmine_dmsf %> + <%= javascript_include_tag 'jquery.dataTables/datatables.min.js', :plugin => :redmine_dmsf, defer: true %> + + <% title = DmsfFolder.get_column_position('title') %> + <% position = DmsfFolder.get_column_position('position') %> + <% commands = DmsfFolder.get_column_position('commands') %> + <% position = DmsfFolder.get_column_position('position') %> + <% version = DmsfFolder.get_column_position('version') %> + <% size_calculated = DmsfFolder.get_column_position('size_calculated') %> + <% modified_calculated = DmsfFolder.get_column_position('modified_calculated') %> + <% version_calculated = DmsfFolder.get_column_position('version_calculated') %> + <% size = DmsfFolder.get_column_position('size') %> + <% modified = DmsfFolder.get_column_position('modified') %> + <% clear_title = DmsfFolder.get_column_position('clear_title') %> + + <%= late_javascript_tag do %> + $("#browser").dataTable({ + orderClasses: false, + responsive: { + details: false + }, + language: { + url: "<%= plugin_asset_path(:redmine_dmsf, 'javascripts', json_url) %>" + }, + oLanguage: { + sSearch: "<%= l(:description_filter) %>:" + }, + autoWidth: false, + paginate: false, + <% if title %> + order: [[<%= title %>, "asc"]], + <% end %> + sortingFixed: [[ <%= position %>, "asc"]], + columnDefs: [ + { responsivePriority: 1, targets: <%= title %> }, + { responsivePriority: 2, targets: <%= commands %> }, + { searchable: false, targets: [0, <%= commands %>, <%= position %>, <%= size_calculated %>, <%= modified_calculated %>, <%= version_calculated %>, <%= clear_title %>] }, + { sortable: false, targets: [0, <%= commands %>] } + <% if title %> + ,{ iDataSort: <%= clear_title %>, targets: [ <%= title %> ] } + <% end %> + <% if size %> + ,{ iDataSort: <%= size_calculated %>, targets: [ <%= size %> ] } + <% end %> + <% if modified %> + ,{ iDataSort: <%= modified_calculated %>, targets: [ <%= modified %> ] } + <% end %> + <% if version %> + ,{ iDataSort: <%= version_calculated %>, targets: [ <%= version %> ] } + <% end %> + ], + "fnInitComplete": function() { + var browserFilter = $("#browser_filter"); + $("#dmsf_buttons").insertBefore(browserFilter); + $("#dmsf_tag").insertBefore(browserFilter); + $("#dmsf_ajax_loading").hide(); + $("#browser").show(); + $("#dmsf_buttons").show(); + $("#dmsf_tag").show(); + $("#dmsf_uploader").show(); + $("#dmsf_uploader_header").show(); + }, + "fnInfoCallback": function( oSettings, iStart, iEnd, iMax, iTotal, sPre ) { + <% folder_id = @folder ? @folder.id : nil %> + return "<%= "#{l(:label_number_of_folders)}: #{DmsfFolder.visible.where(project_id: @project.id, dmsf_folder_id: folder_id).all.size + DmsfLink.visible.where(project_id: @project.id, dmsf_folder_id: folder_id, target_type: 'DmsfFolder').all.size}, #{l(:label_number_of_documents)}: #{DmsfFile.visible.where(project_id: @project.id, dmsf_folder_id: folder_id).all.size + DmsfLink.visible.where(project_id: @project.id, dmsf_folder_id: folder_id, target_type: %w(DmsfFile DmsfUrl)).all.size}" %>"; + } + }); + + $("[data-downloadurl]").each(function() { + var url = this.getAttribute("data-downloadurl"); + if (this.addEventListener) { + this.addEventListener("dragstart", function(e) { + if (e.dataTransfer) { + e.dataTransfer.setData("DownloadURL", url); + } + },false); + } + }); + + var entriesForm = $('#entries_form'); + + entriesForm.submit(function () { + $(this).removeAttr("data-submitted"); + }); + + $('.list_cf').change(function() { + entriesForm.attr('action', "<%= tag_changed_path(:id => @project, :folder_id => @folder) %>"); + entriesForm.submit(); + }); + <% end %> + <% end %> + + <% if @file_manipulation_allowed && !@locked_for_user && !@system_folder %> + <%= render(:partial => 'dmsf_upload/multi_upload', local: { rlf: @rlf }) %> + <% end %> +<% end %> +<% unless (@folder && @folder.system) %> <% other_formats_links do |f| %> - <%= f.link_to 'CSV', :onclick => "showModal('csv-export-options', '350px'); return false;" %> + <%= f.link_to 'CSV', onclick: "showModal('dmsf_csv_export_options', '350px'); return false;" %> <% end %> <% end %> -