#1080 Revision accesses

This commit is contained in:
Karel Pičman 2020-02-18 15:28:34 +01:00
parent 7469988dbe
commit 3f6a722bcb
9 changed files with 186 additions and 37 deletions

View File

@ -95,7 +95,7 @@ class DmsfController < ApplicationController
format.html { format.html {
@dmsf_count = @query.dmsf_count @dmsf_count = @query.dmsf_count
@dmsf_pages = Paginator.new @dmsf_count, per_page_option, params['page'] @dmsf_pages = Paginator.new @dmsf_count, per_page_option, params['page']
@dmsf_nodes = @query.dmsf_nodes(offset: @dmsf_pages.offset, limit: @dmsf_pages.per_page) #@dmsf_nodes = @query.dmsf_nodes(offset: @dmsf_pages.offset, limit: @dmsf_pages.per_page)
render layout: !request.xhr? render layout: !request.xhr?
} }
format.api format.api
@ -141,7 +141,7 @@ class DmsfController < ApplicationController
format.html { format.html {
@dmsf_count = @query.dmsf_count @dmsf_count = @query.dmsf_count
@dmsf_pages = Paginator.new @dmsf_count, per_page_option, params['page'] @dmsf_pages = Paginator.new @dmsf_count, per_page_option, params['page']
@dmsf_nodes = @query.dmsf_nodes(offset: @dmsf_pages.offset, limit: @dmsf_pages.per_page) #@dmsf_nodes = @query.dmsf_nodes(offset: @dmsf_pages.offset, limit: @dmsf_pages.per_page)
render layout: !request.xhr? render layout: !request.xhr?
} }
end end

View File

@ -32,10 +32,13 @@ class DmsfFilesController < ApplicationController
accept_api_auth :show, :view, :delete accept_api_auth :show, :view, :delete
helper :all helper :all #TODO: Is it needed?
helper :dmsf_workflows helper :dmsf_workflows
helper :dmsf helper :dmsf
helper :queries
include QueriesHelper
def permissions def permissions
if @file if @file
render_403 unless DmsfFolder.permissions?(@file.dmsf_folder) render_403 unless DmsfFolder.permissions?(@file.dmsf_folder)
@ -84,6 +87,13 @@ class DmsfFilesController < ApplicationController
@file_delete_allowed = User.current.allowed_to?(:file_delete, @project) @file_delete_allowed = User.current.allowed_to?(:file_delete, @project)
@file_manipulation_allowed = User.current.allowed_to?(:file_manipulation, @project) @file_manipulation_allowed = User.current.allowed_to?(:file_manipulation, @project)
@revision_pages = Paginator.new @file.dmsf_file_revisions.visible.count, params['per_page'] ? params['per_page'].to_i : 25, params['page'] @revision_pages = Paginator.new @file.dmsf_file_revisions.visible.count, params['per_page'] ? params['per_page'].to_i : 25, params['page']
@rlf = cookies[:dmsf_switch_rlf] == 'true'
if @rlf
@revision_access_query = retrieve_query(DmsfFileRevisionAccessQuery, true)
@revision_access_query.revision_id = @revision.id
@revision_access_count = @revision_access_query.access_count
@revision_access_pages = Paginator.new @revision_access_count, per_page_option, params['page']
end
respond_to do |format| respond_to do |format|
format.html { format.html {

View File

@ -142,21 +142,6 @@ class DmsfFileRevision < ActiveRecord::Base
super super
end end
# In a static call, we find the first matched record on base object type and
# then run the access_grouped call against it
def self.access_grouped(revision_id)
DmsfFileRevision.find(revision_id).first.access_grouped
end
# Get grouped data from dmsf_file_revision_access about file interactions
# - 22-06-2012 - Rather than calling a static, we should use the access
# (has_many) to re-run a query - it makes more sense then executing
# custom SQL into a temporary object
#
def access_grouped
dmsf_file_revision_access.select('user_id, COUNT(*) AS count, MIN(created_at) AS first_at, MAX(created_at) AS last_at').group('user_id')
end
def version def version
ver = DmsfUploadHelper::gui_version(major_version).to_s ver = DmsfUploadHelper::gui_version(major_version).to_s
if -minor_version != ' '.ord if -minor_version != ' '.ord

View File

@ -24,9 +24,13 @@ class DmsfFileRevisionAccess < ActiveRecord::Base
belongs_to :dmsf_file_revision belongs_to :dmsf_file_revision
belongs_to :user belongs_to :user
delegate :dmsf_file, :to => :dmsf_file_revision, :allow_nil => false delegate :dmsf_file, :to => :dmsf_file_revision, :allow_nil => false
delegate :project, :to => :dmsf_file, :allow_nil => false delegate :project, :to => :dmsf_file, :allow_nil => false
# TODO: dmsf_file_revision_accesses.dmsf_file_revision_id should be a key
scope :access_grouped, -> { select('user_id, COUNT(*) AS count, MIN(created_at) AS first_at, MAX(created_at) AS last_at').group('user_id') }
validates :dmsf_file_revision, presence: true validates :dmsf_file_revision, presence: true
DownloadAction = 0 DownloadAction = 0

View File

@ -0,0 +1,90 @@
# encode: utf-8
# frozen_string_literal: true
#
# Redmine plugin for Document Management System "Features"
#
# Copyright © 2011-20 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 DmsfFileRevisionAccessQuery < Query
attr_accessor :revision_id
self.queried_class = DmsfFileRevisionAccess
self.view_permission = :view_dmsf_files
# Standard columns
self.available_columns = [
QueryColumn.new(:user, frozen: true),
QueryColumn.new(:count, frozen: true),
QueryColumn.new(:first_at, frozen: true),
QueryColumn.new(:last_at, frozen: true)
]
def initialize(attributes)
super attributes
self.sort_criteria = []
self.filters = {}
end
######################################################################################################################
# Inherited
#
def base_scope
unless @scope
@scope = DmsfFileRevisionAccess.
where(dmsf_file_revision_id: revision_id)
end
@scope
end
# Returns the issue count
def access_count
base_scope.
group(:user_id).
count.size
rescue ::ActiveRecord::StatementInvalid => e
raise StatementInvalid.new(e.message)
end
def type
'DmsfFileRevisionAccessQuery'
end
def available_columns
unless @available_columns
@available_columns = self.class.available_columns.dup
end
@available_columns
end
#alias default_columns_names available_columns
######################################################################################################################
# New
def accesses(options={})
base_scope.
access_grouped.
joins(:user).
order('`count` DESC').
limit(options[:limit]).
offset(options[:offset])
end
end

View File

@ -22,23 +22,49 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
%> %>
<table id="browser" class="display list dmsf_list"> <% if query %>
<thead> <% query_options = nil unless defined?(query_options) %>
<tr> <% query_options ||= {} %>
<th class="dmsf_th"><%= l(:field_user) %></th> <div class="autoscroll">
<th class="dmsf_th"><%= l(:heading_access_downloads_emails) %></th> <table class="list dmsf odd-even <%= query.css_classes %>">
<th class="dmsf_th"><%= l(:heading_access_first) %></th> <thead>
<th class="dmsf_th"><%= l(:heading_access_last) %></th>
</tr>
</thead>
<tbody>
<% revision.access_grouped.each do |access| %>
<tr> <tr>
<td class="dmsf_author"><%= link_to_user(access.user) %></td> <% query.inline_columns.each do |column| %>
<td class="dmsf_version"><%= access.count %></td> <%= column_header(query, column, query_options) %>
<td class="dmsf_modified"><%= format_time(access.first_at) %></td> <% end %>
<td class="dmsf_modified"><%= format_time(access.last_at) %></td>
</tr> </tr>
<% end %> </thead>
</tbody> <tbody>
</table> <% query.accesses.each do |access| %>
<tr>
<% query.inline_columns.each do |column| %>
<%= content_tag('td', column_content(column, access), class: column.css_classes) %>
<% end %>
</tr>
<% end %>
</tbody>
</table>
</div>
<span class="pagination"><%= pagination_links_full revision_access_pages, revision_access_count %></span>
<% else %>
<table id="browser" class="display list dmsf_list">
<thead>
<tr>
<th class="dmsf_th"><%= l(:field_user) %></th>
<th class="dmsf_th"><%= l(:heading_access_downloads_emails) %></th>
<th class="dmsf_th"><%= l(:heading_access_first) %></th>
<th class="dmsf_th"><%= l(:heading_access_last) %></th>
</tr>
</thead>
<tbody>
<% DmsfFileRevisionAccess.access_grouped.where(dmsf_file_revision_id: revision.id).each do |access| %>
<tr>
<td class="dmsf_author"><%= link_to_user(access.user) %></td>
<td class="dmsf_version"><%= access.count %></td>
<td class="dmsf_modified"><%= format_time(access.first_at) %></td>
<td class="dmsf_modified"><%= format_time(access.last_at) %></td>
</tr>
<% end %>
</tbody>
</table>
<% end %>

View File

@ -167,7 +167,11 @@
</div> </div>
</div> </div>
<div id="<%= "revision_access-#{revision.id}" %>" style="display:none"> <div id="<%= "revision_access-#{revision.id}" %>" style="display:none">
<%= render(:partial => 'revision_access', locals: { revision: revision }) if @file_manipulation_allowed %> <% if @file_manipulation_allowed %>
<%= render partial: 'revision_access', locals: { revision: revision, query: @query,
revision_access_count: @revision_access_count,
revision_access_pages: @revision_access_pages } %>
<% end %>
</div> </div>
</div> </div>
</div> </div>

View File

@ -418,6 +418,9 @@ en:
field_modified: Updated field_modified: Updated
field_extension: Ext. field_extension: Ext.
field_updated: Updated field_updated: Updated
field_count: Downloads/Email
field_first_at: First
field_last_at: Last
easy_pages: easy_pages:
modules: modules:

View File

@ -0,0 +1,27 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright © 2011-20 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 AddIndexOnDmsfFileRevisionIdToAccess < ActiveRecord::Migration[5.2]
def change
add_index :dmsf_file_revision_accesses, :dmsf_file_revision_id
end
end