Changing default file query #1386

This commit is contained in:
Karel Pičman 2022-09-07 14:40:53 +02:00
parent 1141b70277
commit d6efc10bca
19 changed files with 365 additions and 48 deletions

View File

@ -703,6 +703,7 @@ class DmsfController < ApplicationController
end
def get_query
retrieve_default_query true
if Redmine::Plugin.installed?(:easy_extensions)
@query = retrieve_query_without_easy_extensions(DmsfQuery, true)
else
@ -710,6 +711,24 @@ class DmsfController < ApplicationController
end
end
def retrieve_default_query(use_session)
return if params[:query_id].present?
return if api_request?
return if params[:set_filter]
if params[:without_default].present?
params[:set_filter] = 1
return
end
if !params[:set_filter] && use_session && session[:issue_query]
query_id, project_id = session[:issue_query].values_at(:id, :project_id)
return if DmsfQuery.where(id: query_id).exists? && project_id == @project&.id
end
if default_query = DmsfQuery.default(project: @project)
params[:query_id] = default_query.id
end
end
def get_project_roles
@project_roles = Role.givable.joins(:member_roles).joins(:members).where(
members: { project_id: @project.id }).distinct

View File

@ -44,6 +44,7 @@ class DmsfStateController < ApplicationController
if Setting.plugin_redmine_dmsf['dmsf_act_as_attachable']
@project.update_attribute :dmsf_act_as_attachable, params[:act_as_attachable]
end
@project.update_attribute :default_dmsf_query_id, params[:default_dmsf_query]
redirect_to settings_project_path(@project, tab: 'dmsf')
end

View File

@ -43,6 +43,9 @@ class DmsfQuery < Query
super attributes
self.sort_criteria = []
self.filters ||= { 'title' => { operator: '~', values: ['']} }
self.dmsf_folder_id = nil
self.deleted = false
self.sub_projects = false
end
######################################################################################################################
@ -94,17 +97,13 @@ class DmsfQuery < Query
@scope
end
# Returns the issue count
# Returns the count of all items
def dmsf_count
base_scope.where(statement).count
rescue ::ActiveRecord::StatementInvalid => e
raise StatementInvalid.new e.message
end
def type
'DmsfQuery'
end
def initialize_available_filters
add_available_filter 'author', type: :list, values: lambda { author_values }
add_available_filter 'title', type: :text
@ -317,12 +316,12 @@ class DmsfQuery < Query
scope = scope.visible
end
if dmsf_folder_id
scope.where dmsf_folders: { dmsf_folder_id: dmsf_folder_id, deleted: deleted }
scope.where dmsf_folders: { dmsf_folder_id: dmsf_folder_id }
else
if statement.present? || deleted
scope.where dmsf_folders: { project_id: project.id, deleted: deleted }
scope.where dmsf_folders: { project_id: project.id }
else
scope.where dmsf_folders: { project_id: project.id, dmsf_folder_id: nil, deleted: deleted }
scope.where dmsf_folders: { project_id: project.id, dmsf_folder_id: nil }
end
end
end
@ -356,13 +355,18 @@ class DmsfQuery < Query
1 AS sort#{cf_columns}}).
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)')
if deleted
scope = scope.deleted
else
scope = scope.visible
end
if dmsf_folder_id
scope.where dmsf_links: { target_type: 'DmsfFolder', dmsf_folder_id: dmsf_folder_id, deleted: deleted }
scope.where dmsf_links: { target_type: 'DmsfFolder', dmsf_folder_id: dmsf_folder_id}
else
if statement.present? || deleted
scope.where dmsf_links: { target_type: 'DmsfFolder', project_id: project.id, deleted: deleted }
scope.where dmsf_links: { target_type: 'DmsfFolder', project_id: project.id }
else
scope.where dmsf_links: { target_type: 'DmsfFolder', project_id: project.id, dmsf_folder_id: nil, deleted: deleted }
scope.where dmsf_links: { target_type: 'DmsfFolder', project_id: project.id, dmsf_folder_id: nil }
end
end
end
@ -397,13 +401,18 @@ class DmsfQuery < Query
joins(:dmsf_file_revisions).
joins('LEFT JOIN users ON dmsf_file_revisions.user_id = users.id ').
where(sub_query)
if deleted
scope = scope.deleted
else
scope = scope.visible
end
if dmsf_folder_id
scope.where dmsf_files: { dmsf_folder_id: dmsf_folder_id, deleted: deleted }
scope.where dmsf_files: { dmsf_folder_id: dmsf_folder_id }
else
if statement.present? || deleted
scope.where dmsf_files: { project_id: project.id, deleted: deleted }
scope.where dmsf_files: { project_id: project.id }
else
scope.where dmsf_files: { project_id: project.id, dmsf_folder_id: nil, deleted: deleted }
scope.where dmsf_files: { project_id: project.id, dmsf_folder_id: nil }
end
end
end
@ -439,13 +448,18 @@ class DmsfQuery < Query
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(sub_query)
if deleted
scope = scope.deleted
else
scope = scope.visible
end
if dmsf_folder_id
scope.where dmsf_links: { target_type: 'DmsfFile', dmsf_folder_id: dmsf_folder_id, deleted: deleted }
scope.where dmsf_links: { target_type: 'DmsfFile', dmsf_folder_id: dmsf_folder_id }
else
if statement.present? || deleted
scope.where dmsf_links: { target_type: 'DmsfFile', project_id: project.id, deleted: deleted }
scope.where dmsf_links: { target_type: 'DmsfFile', project_id: project.id }
else
scope.where dmsf_links: { target_type: 'DmsfFile', project_id: project.id, dmsf_folder_id: nil, deleted: deleted }
scope.where dmsf_links: { target_type: 'DmsfFile', project_id: project.id, dmsf_folder_id: nil }
end
end
@ -479,15 +493,39 @@ class DmsfQuery < Query
0 as customized_id,
2 AS sort#{cf_columns}}).
joins('LEFT JOIN users ON dmsf_links.user_id = users.id ')
if deleted
scope = scope.deleted
else
scope = scope.visible
end
if dmsf_folder_id
scope.where dmsf_links: { target_type: 'DmsfUrl', dmsf_folder_id: dmsf_folder_id, deleted: deleted }
scope.where dmsf_links: { target_type: 'DmsfUrl', dmsf_folder_id: dmsf_folder_id }
else
if statement.present? || deleted
scope.where dmsf_links: { target_type: 'DmsfUrl', project_id: project.id, deleted: deleted }
scope.where dmsf_links: { target_type: 'DmsfUrl', project_id: project.id }
else
scope.where dmsf_links: { target_type: 'DmsfUrl', project_id: project.id, dmsf_folder_id: nil, deleted: deleted }
scope.where dmsf_links: { target_type: 'DmsfUrl', project_id: project.id, dmsf_folder_id: nil }
end
end
end
def self.default(project = nil, user = User.current)
# User's default
if user&.logged? && (query_id = user.pref.default_dmsf_query).present?
query = find_by(id: query_id)
return query if query&.visible?
end
# Project's default
query = project&.default_dmsf_query
return query if query&.visibility == VISIBILITY_PUBLIC
# Global default
if (query_id = Setting.plugin_redmine_dmsf['dmsf_default_query']).present?
query = find_by(id: query_id)
return query if query&.visibility == VISIBILITY_PUBLIC
end
nil
end
end

View File

@ -46,9 +46,10 @@
</p>
</fieldset>
<% end %>
<% if Setting.plugin_redmine_dmsf['dmsf_act_as_attachable'] %>
<fieldset class="box tabular">
<legend><%= l(:field_project) %> <%= l(:label_preferences) %></legend>
<% if Setting.plugin_redmine_dmsf['dmsf_act_as_attachable'] %>
<p>
<%= content_tag(:label, "#{l(:label_act_as_attachable)}:") %>
<%= select_tag 'act_as_attachable',
@ -57,13 +58,18 @@
[l(:label_attachment_plural), Project::ATTACHABLE_ATTACHMENTS],
], selected: @project.dmsf_act_as_attachable) %>
</p>
</fieldset>
<p>
<%= content_tag(:label, "#{l(:label_default_query)}:") %>
<% options = [[l(:label_none), nil]] %>
<% options.concat DmsfQuery.only_public.where(project_id: nil).pluck(:name, :id) %>
<%= select_tag 'default_dmsf_query',
options_for_select(options, selected: @project.default_dmsf_query_id) %>
</p>
<% end %>
<% if member || Setting.plugin_redmine_dmsf['dmsf_act_as_attachable'] %>
</fieldset>
<div class="form-actions">
<%= submit_tag l(:submit_save), title: l(:title_save_preferences), class: 'button-positive' %>
</div>
<% else %>
<p class="nodata"><%= l(:label_no_data) %></p>
<% end %>
<% end %>

View File

@ -0,0 +1,33 @@
<%#
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright © 2011 Vít Jonáš <vit.jonas@gmail.com>
# Copyright © 2012 Daniel Munn <dan.munn@munnster.co.uk>
# Copyright © 2011-22 Karel Pičman <karel.picman@kontron.com>
#
# 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.
%>
<%= labelled_fields_for :pref, @user.pref do |pref_fields| %>
<p>
<% options = [[l(:label_none), nil]] %>
<% options.concat DmsfQuery.only_public.where(project_id: nil).or(DmsfQuery.where(user_id: @user.id)).
pluck(:name, :id) %>
<%= pref_fields.select :default_dmsf_query,
options_for_select(options, selected: @user.pref.default_dmsf_query) %>
</p>
<% end %>

View File

@ -167,6 +167,14 @@
<%= render partial: 'settings/dmsf_columns', locals: { selected_columns: @settings['dmsf_columns'] } %>
<p>
<%= content_tag :label, l(:label_default_query) %>
<% options = [[l(:label_none), nil]] %>
<% options.concat DmsfQuery.only_public.where(project_id: nil).pluck(:name, :id) %>
<%= select_tag 'settings[dmsf_default_query]',
options_for_select(options, selected: @settings['dmsf_default_query']) %>
</p>
<hr/>
<em class="info">
<%= l(:heading_send_documents_by_email) %>

View File

@ -0,0 +1,27 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright © 2011-22 Karel Pičman <karel.picman@kontron.com>
#
# 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 AddProjectsDefaultDmsfQueryId < ActiveRecord::Migration[4.2]
def change
add_column :projects, :default_dmsf_query_id, :integer, default: nil
end
end

View File

@ -57,7 +57,8 @@ Redmine::Plugin.register :redmine_dmsf do
'only_approval_zero_minor_version' => '0',
'dmsf_max_notification_receivers_info' => 10,
'office_bin' => 'libreoffice',
'dmsf_global_menu_disabled' => 0
'dmsf_global_menu_disabled' => 0,
'dmsf_default_query' => nil
}
end

View File

@ -75,8 +75,9 @@ require File.dirname(__FILE__) + '/redmine_dmsf/hooks/controllers/search_control
require File.dirname(__FILE__) + '/redmine_dmsf/hooks/controllers/issues_controller_hooks'
require File.dirname(__FILE__) + '/redmine_dmsf/hooks/views/view_projects_form_hook'
require File.dirname(__FILE__) + '/redmine_dmsf/hooks/views/base_view_hooks'
require File.dirname(__FILE__) + '/redmine_dmsf/hooks/views/issue_view_hooks'
require File.dirname(__FILE__) + '/redmine_dmsf/hooks/views/custom_field_view_hooks'
require File.dirname(__FILE__) + '/redmine_dmsf/hooks/views/issue_view_hooks'
require File.dirname(__FILE__) + '/redmine_dmsf/hooks/views/my_account_view_hooks'
require File.dirname(__FILE__) + '/redmine_dmsf/hooks/views/search_view_hooks'
require File.dirname(__FILE__) + '/redmine_dmsf/hooks/helpers/issues_helper_hooks'
require File.dirname(__FILE__) + '/redmine_dmsf/hooks/helpers/search_helper_hooks'

View File

@ -0,0 +1,39 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright © 2011-22 Karel Pičman <karel.picman@kontron.com>
#
# 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.
# User form view hooks
module RedmineDmsf
module Hooks
module Views
class MyAccountViewHooks < Redmine::Hook::ViewListener
def view_my_account_preferences(context={})
if context.is_a?(Hash) && context[:user]
context[:controller].send(
:render_to_string, { partial: 'hooks/redmine_dmsf/view_my_account', locals: context }).html_safe
end
end
end
end
end
end

View File

@ -69,6 +69,8 @@ module RedmineDmsf
has_many :dmsf_links, -> { where dmsf_folder_id: nil },
class_name: 'DmsfLink', foreign_key: 'project_id', dependent: :destroy
belongs_to :default_dmsf_query, class_name: 'DmsfQuery'
acts_as_watchable
before_save :set_default_dmsf_notification

View File

@ -26,11 +26,7 @@ module RedmineDmsf
##################################################################################################################
# New methods
def self.included(base)
base.class_eval do
safe_attributes 'dmsf_attachments_upload_choice' if self.included_modules.include?(Redmine::SafeAttributes)
end
end
UserPreference::safe_attributes 'dmsf_attachments_upload_choice'
def dmsf_attachments_upload_choice
self[:dmsf_attachments_upload_choice] || 'DMSF'
@ -40,6 +36,16 @@ module RedmineDmsf
self[:dmsf_attachments_upload_choice] = value
end
UserPreference::safe_attributes 'default_dmsf_query'
def default_dmsf_query
self[:default_dmsf_query] || nil
end
def default_dmsf_query=(value)
self[:default_dmsf_query] = value
end
end
end
end

View File

@ -94,7 +94,7 @@ dmsf_file_revisions_005:
disk_filename: 'test5.txt'
size: 4
mime_type: 'application/vnd.oasis.opendocument.text'
title: 'Test File'
title: 'Test file'
description: NULL
workflow: 1 # DmsfWorkflow::STATE_WAITING_FOR_APPROVAL
minor_version: 1
@ -115,7 +115,7 @@ dmsf_file_revisions_006:
disk_filename: 'test.gif'
size: 4
mime_type: 'image/gif'
title: 'Image'
title: 'Test image'
description: NULL
workflow: NULL
minor_version: 0
@ -136,7 +136,7 @@ dmsf_file_revisions_007:
disk_filename: 'test.pdf'
size: 4
mime_type: 'application/pdf'
title: 'PDF'
title: 'Test PDF'
description: NULL
workflow: NULL
minor_version: 0
@ -243,7 +243,7 @@ dmsf_file_revisions_012:
disk_filename: 'test.mp4'
size: 4
mime_type: 'video/mp4'
title: 'Video file'
title: 'test video'
description: 'A video :-)'
workflow: 0
minor_version: 0
@ -265,7 +265,7 @@ dmsf_file_revisions_013:
disk_filename: 'test.odt'
size: 4
mime_type: 'application/vnd.oasis.opendocument.text'
title: 'Office document'
title: 'Test office document'
description: 'LibreOffice text'
workflow: 0
minor_version: 0

View File

@ -43,7 +43,7 @@ file_link2:
target_project_id: 1
target_id: 4
target_type: DmsfFile
name: test_link
name: test_link2
project_id: 1
dmsf_folder_id: NULL
deleted: 0

15
test/fixtures/queries.yml vendored Normal file
View File

@ -0,0 +1,15 @@
---
queries_401:
id: 401
type: DmsfQuery
project_id: 1
visibility: 2
name: Test
filters: |
---
title:
:values:
- 'test'
:operator: '~'
user_id: 2
column_names:

View File

@ -24,20 +24,29 @@ require File.expand_path('../../test_helper', __FILE__)
class DmsfStateControllerTest < RedmineDmsf::Test::TestCase
include Redmine::I18n
fixtures :dmsf_folders, :dmsf_files, :dmsf_file_revisions
fixtures :dmsf_folders, :dmsf_files, :dmsf_file_revisions, :queries
def setup
super
@query401 = Query.find 401
@request.session[:user_id] = @jsmith.id
end
def test_user_pref_save_member
assert @project1
@role_manager.add_permission! :user_preferences
post :user_pref_save, params: { id: @project1.id, email_notify: 1, title_format: '%t_%v' }
post :user_pref_save, params: { id: @project1.id, email_notify: 1, title_format: '%t_%v', fast_links: 1,
act_as_attachable: 1, default_dmsf_query: @query401.id }
assert_redirected_to settings_project_path(@project1, tab: 'dmsf')
assert_not_nil flash[:notice]
assert_equal flash[:notice], l(:notice_your_preferences_were_saved)
member = @project1.members.find_by(user_id: @jsmith.id)
assert member
assert_equal true, member.dmsf_mail_notification
assert_equal '%t_%v', member.dmsf_title_format
assert_equal true, member.dmsf_fast_links
@project1.reload
assert_equal 1, @project1.dmsf_act_as_attachable
assert_equal @query401.id, @project1.default_dmsf_query_id
end
def test_user_pref_save_member_forbidden

View File

@ -0,0 +1,72 @@
# encoding: utf-8
# frozen_string_literal: true
#
# Redmine plugin for Document Management System "Features"
#
# Copyright © 2012 Daniel Munn <dan.munn@munnster.co.uk>
# Copyright © 2011-22 Karel Pičman <karel.picman@kontron.com>
#
# 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.
require File.expand_path('../../test_helper', __FILE__)
class DmsfQueryTest < RedmineDmsf::Test::UnitTest
fixtures :queries, :dmsf_folders, :dmsf_files, :dmsf_file_revisions
def setup
super
@query401 = Query.find 401
User.current = @jsmith
end
def test_type
assert_equal 'DmsfQuery', @query401.type
end
def test_available_columns
n = DmsfQuery.available_columns.size + DmsfFileRevisionCustomField.visible.all.size
assert_equal n, @query401.available_columns.size
end
def test_dmsf_count
n = DmsfFolder.visible.where(project_id: @project1.id).where("title LIKE '%test%'").all.size +
DmsfFile.visible.where(project_id: @project1.id).where("name LIKE '%test%'").all.size +
DmsfLink.visible.where(project_id: @project1.id).where("name LIKE '%test%'").all.size
assert_equal n, @query401.dmsf_count
end
def test_dmsf_nodes
assert @query401.dmsf_nodes.size > 0
end
def test_default
# User
@jsmith.pref.default_dmsf_query = @query401.id
assert_equal @query401, DmsfQuery.default
@jsmith.pref.default_dmsf_query = nil
# Project
@project1.default_dmsf_query_id = @query401.id
assert_equal @query401, DmsfQuery.default(@project1)
@project1.default_dmsf_query_id = nil
# Global
with_settings plugin_redmine_dmsf: {'dmsf_default_query' => @query401.id} do
assert_equal @query401, DmsfQuery.default
end
end
end

View File

@ -53,6 +53,10 @@ class ProjectPatchTest < RedmineDmsf::Test::UnitTest
assert @project1.respond_to?(:dmsf_links)
end
def test_project_has_default_dmsf_query
assert @project1.respond_to?(:default_dmsf_query)
end
def test_dmsf_count
User.current = @jsmith
hash = @project1.dmsf_count

View File

@ -0,0 +1,36 @@
# encoding: utf-8
# frozen_string_literal: true
#
# Redmine plugin for Document Management System "Features"
#
# Copyright © 2011-22 Karel Pičman <karel.picman@kontron.com>
#
# 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.
require File.expand_path('../../test_helper', __FILE__)
class UserPreferencePatchTest < RedmineDmsf::Test::UnitTest
fixtures :dmsf_folders, :dmsf_files, :dmsf_file_revisions
def test_user_preference_has_dmsf_attachments_upload_choice
assert @jsmith.pref.respond_to?(:dmsf_attachments_upload_choice)
end
def test_user_preference_has_default_dmsf_query
assert @jsmith.pref.respond_to?(:default_dmsf_query)
end
end