#183 Create document links

This commit is contained in:
Karel Picman 2014-02-18 17:20:08 +01:00
parent 7992c460ef
commit adb33cd7f7
95 changed files with 1209 additions and 647 deletions

View File

@ -37,13 +37,20 @@ class DmsfController < ApplicationController
@file_manipulation_allowed = User.current.allowed_to?(:file_manipulation, @project)
@force_file_unlock_allowed = User.current.allowed_to?(:force_file_unlock, @project)
@workflows_available = DmsfWorkflow.where(['project_id = ? OR project_id IS NULL', @project.id]).count > 0
unless @folder
@subfolders = @project.dmsf_folders.visible
@files = @project.dmsf_files.visible
@files = @project.dmsf_files.visible
@locked_for_user = false
@dir_links = @project.folder_links
@file_links = @project.file_links
else
@subfolders = @folder.subfolders.visible
@files = @folder.files.visible
@locked_for_user = @folder.locked_for_user?
@dir_links = @folder.folder_links
@file_links = @folder.file_links
end
@files.sort! do |a,b|
@ -58,15 +65,32 @@ class DmsfController < ApplicationController
end
def entries_operation
selected_folders = params[:subfolders]
selected_files = params[:files]
selected_folders = params[:subfolders].present? ? params[:subfolders] : []
selected_files = params[:files].present? ? params[:files] : []
selected_dir_links = params[:dir_links]
selected_file_links = params[:file_links]
if selected_folders.nil? && selected_files.nil?
flash[:warning] = l(:warning_no_entries_selected)
redirect_to :action => 'show', :id => @project, :folder_id => @folder
if selected_folders.blank? && selected_files.blank? &&
selected_dir_links.blank? && selected_file_links.blank?
flash[:warning] = l(:warning_no_entries_selected)
redirect_to :back
return
end
if selected_dir_links.present?
selected_dir_links.each do |id|
link = DmsfLink.find_by_id id
selected_folders << link.target_id if link
end
end
if selected_file_links.present?
selected_file_links.each do |id|
link = DmsfLink.find_by_id id
selected_files << link.target_id if link
end
end
if params[:email_entries].present?
email_entries(selected_folders, selected_files)
else
@ -74,10 +98,10 @@ class DmsfController < ApplicationController
end
rescue ZipMaxFilesError
flash[:error] = l(:error_max_files_exceeded, :number => Setting.plugin_redmine_dmsf['dmsf_max_file_download'])
redirect_to({:controller => 'dmsf', :action => 'show', :id => @project, :folder_id => @folder})
redirect_to :back
rescue EmailMaxFileSize
flash[:error] = l(:error_max_email_filesize_exceeded, :number => Setting.plugin_redmine_dmsf['dmsf_max_email_filesize'])
redirect_to({:controller => 'dmsf', :action => 'show', :id => @project, :folder_id => @folder})
redirect_to :back
rescue FileNotFound
render_404
rescue DmsfAccessError
@ -101,42 +125,67 @@ class DmsfController < ApplicationController
def delete_entries
selected_folders = params[:subfolders]
selected_files = params[:files]
if selected_folders.nil? && selected_files.nil?
selected_dir_links = params[:dir_links]
selected_file_links = params[:file_links]
if selected_folders.blank? && selected_files.blank? &&
selected_dir_links.blank? && selected_file_links.blank?
flash[:warning] = l(:warning_no_entries_selected)
else
failed_entries = []
deleted_files = []
deleted_folders = []
if selected_folders
if User.current.allowed_to?(:folder_manipulation, @project)
failed_entries = []
if User.current.allowed_to?(:folder_manipulation, @project)
# Folders
if selected_folders.present?
selected_folders.each do |subfolderid|
subfolder = DmsfFolder.visible.find(subfolderid)
next if subfolder.nil?
subfolder = DmsfFolder.visible.find_by_id subfolderid
next unless subfolder
if subfolder.project != @project || !subfolder.delete
failed_entries.push(subfolder)
else
deleted_folders.push(subfolder)
failed_entries.push(subfolder)
end
end
else
flash[:error] = l(:error_user_has_not_right_delete_folder)
end
end
# Folder links
if selected_dir_links.present?
selected_dir_links.each do |dir_link_id|
link_folder = DmsfLink.visible.find_by_id dir_link_id
next unless link_folder
if link_folder.project != @project || !link_folder.delete
failed_entries.push(link_folder)
end
end
end
else
flash[:error] = l(:error_user_has_not_right_delete_folder)
end
if selected_files
if User.current.allowed_to?(:file_manipulation, @project)
deleted_files = []
if User.current.allowed_to?(:file_manipulation, @project)
# Files
if selected_files.present?
selected_files.each do |fileid|
file = DmsfFile.visible.find(fileid)
file = DmsfFile.visible.find_by_id fileid
next unless file
if file.project != @project || !file.delete
failed_entries.push(file)
else
deleted_files.push(file)
end
end
else
flash[:error] = l(:error_user_has_not_right_delete_file)
end
end
# File links
if selected_file_links.present?
selected_file_links.each do |file_link_id|
file_link = DmsfLink.visible.find_by_id file_link_id
next unless file_link
if file_link.project != @project || !file_link.delete
failed_entries.push(file_link)
end
end
end
else
flash[:error] = l(:error_user_has_not_right_delete_file)
end
unless deleted_files.empty?
deleted_files.each do |f|
log_activity(f, 'deleted')
@ -149,8 +198,8 @@ class DmsfController < ApplicationController
flash[:warning] = l(:warning_some_entries_were_not_deleted, :entries => failed_entries.map{|e| e.title}.join(', '))
end
end
redirect_to :controller => 'dmsf', :action => 'show', :id => @project, :folder_id => @folder
redirect_to :back
end
# Folder manipulation
@ -202,8 +251,8 @@ class DmsfController < ApplicationController
else
flash[:error] = @delete_folder.errors[:base][0]
end
end
redirect_to :controller => 'dmsf', :action => 'show', :id => @project, :folder_id => @folder
end
redirect_to dmsf_folder_path(:id => @project, :folder_id => @delete_folder.dmsf_folder_id)
rescue DmsfAccessError
render_403
end
@ -229,14 +278,8 @@ class DmsfController < ApplicationController
@project.save
end
flash[:notice] = l(:notice_folder_notifications_activated)
end
if params[:current]
redirect_to params[:current]
elsif @folder
redirect_to({:controller => 'dmsf', :action => 'show', :id => @project, :folder_id => @folder.folder})
else
redirect_to({:controller => 'dmsf', :action => 'show', :id => @project})
end
redirect_to :back
end
def notify_deactivate
@ -250,17 +293,10 @@ class DmsfController < ApplicationController
@project.save
end
flash[:notice] = l(:notice_folder_notifications_deactivated)
end
if params[:current]
redirect_to params[:current]
elsif @folder
redirect_to({:controller => 'dmsf', :action => 'show', :id => @project, :folder_id => @folder.folder})
else
redirect_to({:controller => 'dmsf', :action => 'show', :id => @project})
end
redirect_to :back
end
def lock
if @folder.nil?
flash[:warning] = l(:warning_foler_unlockable)
@ -269,9 +305,8 @@ class DmsfController < ApplicationController
else
@folder.lock!
flash[:notice] = l(:notice_folder_locked)
end
redirect_to params[:current] ? params[:current] :
{:controller => 'dmsf', :action => 'show', :id => @project, :folder_id => @folder.folder}
end
redirect_to :back
end
def unlock
@ -286,9 +321,8 @@ class DmsfController < ApplicationController
else
flash[:error] = l(:error_only_user_that_locked_folder_can_unlock_it)
end
end
redirect_to params[:current] ? params[:current] :
{:controller => 'dmsf', :action => 'show', :id => @project, :folder_id => @folder.folder}
end
redirect_to :back
end
private

View File

@ -172,9 +172,8 @@ class DmsfFilesController < ApplicationController
else
@file.lock!
flash[:notice] = l(:notice_file_locked)
end
redirect_to params[:current] ? params[:current] :
{:controller => 'dmsf', :action => 'show', :id => @project, :folder_id => @file.folder}
end
redirect_to :back
end
def unlock
@ -187,9 +186,8 @@ class DmsfFilesController < ApplicationController
else
flash[:error] = l(:error_only_user_that_locked_file_can_unlock_it)
end
end
redirect_to params[:current] ? params[:current] :
{:controller => 'dmsf', :action => 'show', :id => @project, :folder_id => @file.folder}
end
redirect_to :back
end
def notify_activate
@ -198,9 +196,8 @@ class DmsfFilesController < ApplicationController
else
@file.notify_activate
flash[:notice] = l(:notice_file_notifications_activated)
end
redirect_to params[:current] ? params[:current] :
{:controller => 'dmsf', :action => 'show', :id => @project, :folder_id => @file.folder}
end
redirect_to :back
end
def notify_deactivate
@ -209,9 +206,8 @@ class DmsfFilesController < ApplicationController
else
@file.notify_deactivate
flash[:notice] = l(:notice_file_notifications_deactivated)
end
redirect_to params[:current] ? params[:current] :
{:controller => 'dmsf', :action => 'show', :id => @project, :folder_id => @file.folder}
end
redirect_to :back
end
private
@ -234,13 +230,16 @@ class DmsfFilesController < ApplicationController
def find_file
@file = DmsfFile.visible.find(params[:id])
@project = @file.project
rescue
rescue ActiveRecord::RecordNotFound
render_404
end
def find_revision
@revision = DmsfFileRevision.visible.find(params[:id])
@file = @revision.file
@project = @file.project
rescue ActiveRecord::RecordNotFound
render_404
end
def check_project(entry)

View File

@ -0,0 +1,91 @@
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2014 Karel Pičman <karel.picman@lbcfree.net>
#
# 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 DmsfLinksController < ApplicationController
unloadable
model_object DmsfLink
before_filter :find_model_object, :only => [:destroy]
before_filter :find_link_project
before_filter :authorize
def new
@dmsf_link = DmsfLink.new
@dmsf_link.project_id = @project.id
@dmsf_link.target_type = DmsfFolder.model_name
@dmsf_link.dmsf_folder_id = params[:dmsf_folder_id]
if params[:dmsf_link].present?
@dmsf_link.target_project_id = params[:dmsf_link][:target_project_id]
@target_folder_id = DmsfLinksHelper.is_a_number?(params[:dmsf_link][:target_folder_id]) ? params[:dmsf_link][:target_folder_id].to_i : nil
else
@dmsf_link.target_project_id = @project.id
@target_folder_id = @dmsf_link.dmsf_folder_id
end
render :layout => !request.xhr?
end
def create
@dmsf_link = DmsfLink.new
@dmsf_link.project_id = @project.id
@dmsf_link.target_project_id = params[:dmsf_link][:target_project_id]
@dmsf_link.dmsf_folder_id = params[:dmsf_link][:dmsf_folder_id]
if params[:dmsf_link][:target_file_id].present?
@dmsf_link.target_id = params[:dmsf_link][:target_file_id]
@dmsf_link.target_type = DmsfFile.model_name
else
@dmsf_link.target_id = DmsfLinksHelper.is_a_number?(params[:dmsf_link][:target_folder_id]) ? params[:dmsf_link][:target_folder_id].to_i : nil
@dmsf_link.target_type = DmsfFolder.model_name
end
@dmsf_link.name = params[:dmsf_link][:name]
if @dmsf_link.save
flash[:notice] = l(:notice_successful_create)
redirect_to dmsf_folder_path(:id => @project.id, :folder_id => @dmsf_link.dmsf_folder_id)
else
render :action => 'new'
end
end
def destroy
begin
@dmsf_link.destroy
flash[:notice] = l(:notice_successful_delete)
rescue
flash[:error] = l(:error_unable_delete_dmsf_workflow)
end
redirect_to :back
end
private
def find_link_project
if @dmsf_link
@project = @dmsf_link.project
else
@project = Project.find(params[:dmsf_link].present? ? params[:dmsf_link][:project_id] : params[:project_id])
end
rescue ActiveRecord::RecordNotFound
render_404
end
end

View File

@ -269,25 +269,23 @@ class DmsfWorkflowsController < ApplicationController
def start
revision = DmsfFileRevision.find_by_id(params[:dmsf_file_revision_id])
if revision
if request.post?
revision.set_workflow(@workflow.id, params[:action])
if revision.save
assignments = @workflow.next_assignments revision.id
assignments.each do |assignment|
DmsfMailer.workflow_notification(
assignment.user,
@workflow,
revision,
l(:text_email_subject_started, :name => @workflow.name),
l(:text_email_started, :name => @workflow.name, :filename => revision.file.name),
l(:text_email_to_proceed)).deliver if assignment.user
end
flash[:notice] = l(:notice_workflow_started)
else
flash[:error] = l(:notice_cannot_start_workflow)
if revision
revision.set_workflow(@workflow.id, params[:action])
if revision.save
assignments = @workflow.next_assignments revision.id
assignments.each do |assignment|
DmsfMailer.workflow_notification(
assignment.user,
@workflow,
revision,
l(:text_email_subject_started, :name => @workflow.name),
l(:text_email_started, :name => @workflow.name, :filename => revision.file.name),
l(:text_email_to_proceed)).deliver if assignment.user
end
end
flash[:notice] = l(:notice_workflow_started)
else
flash[:error] = l(:notice_cannot_start_workflow)
end
end
redirect_to :back
end

View File

@ -0,0 +1,40 @@
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2014 Karel Pičman <karel.picman@lbcfree.net>
#
# 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.
module DmsfLinksHelper
def folder_tree_options_for_select(folder_tree, options = {})
s = ''
folder_tree.each do |name, id|
tag_options = {:value => id}
if id == options[:selected]
tag_options[:selected] = 'selected'
else
tag_options[:selected] = nil
end
s << content_tag('option', name, tag_options)
end
s.html_safe
end
# An integer test
def self.is_a_number?(s)
s.to_s.match(/\A[+-]?\d+?(\.\d+)?\Z/) == nil ? false : true
end
end

View File

@ -31,14 +31,16 @@ class DmsfFile < ActiveRecord::Base
belongs_to :project
belongs_to :folder, :class_name => 'DmsfFolder', :foreign_key => 'dmsf_folder_id'
belongs_to :deleted_by_user, :class_name => 'User', :foreign_key => 'deleted_by_user_id'
has_many :revisions, :class_name => 'DmsfFileRevision', :foreign_key => 'dmsf_file_id',
:order => "#{DmsfFileRevision.table_name}.major_version DESC, #{DmsfFileRevision.table_name}.minor_version DESC, #{DmsfFileRevision.table_name}.updated_at DESC",
:dependent => :destroy
has_many :locks, :class_name => 'DmsfLock', :foreign_key => 'entity_id',
:order => "#{DmsfLock.table_name}.updated_at DESC",
:conditions => {:entity_type => 0},
:dependent => :destroy
belongs_to :deleted_by_user, :class_name => 'User', :foreign_key => 'deleted_by_user_id'
:dependent => :destroy
has_many :referenced_links, :class_name => 'DmsfLink', :foreign_key => 'target_id',
:conditions => {:target_type => DmsfFile.model_name}, :dependent => :destroy
scope :visible, lambda {|*args| where(DmsfFile.visible_condition(args.shift || User.current, *args)).readonly(false)}

View File

@ -26,12 +26,17 @@ class DmsfFolder < ActiveRecord::Base
belongs_to :project
belongs_to :folder, :class_name => 'DmsfFolder', :foreign_key => 'dmsf_folder_id'
has_many :subfolders, :class_name => 'DmsfFolder', :foreign_key => 'dmsf_folder_id', :order => "#{DmsfFolder.table_name}.title ASC",
:dependent => :destroy
has_many :subfolders, :class_name => 'DmsfFolder', :foreign_key => 'dmsf_folder_id',
:order => "#{DmsfFolder.table_name}.title ASC", :dependent => :destroy
has_many :files, :class_name => 'DmsfFile', :foreign_key => 'dmsf_folder_id',
:dependent => :destroy
belongs_to :user
has_many :folder_links, :class_name => 'DmsfLink', :foreign_key => 'dmsf_folder_id',
:conditions => {:target_type => DmsfFolder.model_name}, :dependent => :destroy
has_many :file_links, :class_name => 'DmsfLink', :foreign_key => 'dmsf_folder_id',
:conditions => {:target_type => DmsfFile.model_name}, :dependent => :destroy
has_many :referenced_links, :class_name => 'DmsfLink', :foreign_key => 'target_id',
:conditions => {:target_type => DmsfFolder.model_name}, :dependent => :destroy
has_many :locks, :class_name => 'DmsfLock', :foreign_key => 'entity_id',
:order => "#{DmsfLock.table_name}.updated_at DESC",
:conditions => {:entity_type => 1},
@ -133,20 +138,29 @@ class DmsfFolder < ActiveRecord::Base
end
end
return tree
end
end
def self.file_list(files)
options = Array.new
options.push ['', nil]
files.each do |f|
options.push [f.title, f.id]
end
options
end
def deep_file_count
file_count = self.files.visible.count
self.subfolders.visible.each {|subfolder| file_count += subfolder.deep_file_count}
file_count
file_count + self.file_links.visible.count
end
def deep_folder_count
folder_count = self.subfolders.visible.count
self.subfolders.visible.each {|subfolder| folder_count += subfolder.deep_folder_count}
folder_count
end
folder_count + self.folder_links.visible.count
end
def deep_size
size = 0
self.files.visible.each {|file| size += file.size}
@ -239,7 +253,7 @@ class DmsfFolder < ActiveRecord::Base
def self.directory_subtree(tree, folder, level, current_folder)
folder.subfolders.visible.each do |subfolder|
unless subfolder == current_folder
tree.push(["#{"..." * level}#{subfolder.title}", subfolder.id])
tree.push(["#{'...' * level}#{subfolder.title}", subfolder.id])
directory_subtree(tree, subfolder, level + 1, current_folder)
end
end

62
app/models/dmsf_link.rb Normal file
View File

@ -0,0 +1,62 @@
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2014 Karel Pičman <karel.picman@lbcfree.net>
#
# 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 DmsfLink < ActiveRecord::Base
unloadable
belongs_to :project
belongs_to :dmsf_folder
validates :name, :presence => true
validates :target_id, :presence => true
validates_length_of :name, :maximum => 255
scope :visible, :conditions => 'deleted = 0'
def target_folder_id
if self.target_type == DmsfFolder.model_name
self.target_id
else
f = DmsfFile.find_by_id self.target_id
f.dmsf_folder_id if f
end
end
def target_folder
DmsfFolder.find self.target_folder_id if self.target_folder_id
end
def target_file_id
self.target_id if self.target_type == DmsfFile.model_name
end
def target_file
DmsfFile.find self.target_file_id if self.target_file_id
end
def target_project
Project.find self.target_project_id
end
def folder
DmsfFolder.find_by_id self.dmsf_folder_id
end
def title
self.name
end
end

View File

@ -0,0 +1,102 @@
<%#=
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2014 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.
%>
<% locked_for_user = subfolder.locked_for_user? %>
<% locked = subfolder.locked? %>
<td class="check"><%= check_box_tag(link ? 'dir_links[]' : 'subfolders[]',
link ? link.id : subfolder.id, false, :title => l(:title_check_for_zip_download_or_email)) %></td>
<td class="title">
<%= link_to(h(link ? link.name : subfolder.title),
dmsf_folder_path(:id => @project, :folder_id => subfolder),
:class => 'icon icon-folder') %>
<div class="filename" title="<%= l(:title_number_of_files_in_directory)%>">[<%= subfolder.files.visible.count %>]</div>
</td>
<td class="size"></td>
<td class="modified"><%= format_time(subfolder.updated_at) %>
<% if locked_for_user %>
<% if subfolder.lock.reverse[0].user %>
<%= link_to('',
user_path(subfolder.lock.reverse[0].user),
:title => l(:title_locked_by_user, :user => subfolder.lock.reverse[0].user),
:class => 'icon icon-dmsf-locked') %>
<% else %>
<%= content_tag(:span, '', :title => l(:notice_account_unknown_email),
:class => 'icon icon-dmsf-locked') %>
<% end %>
<% elsif locked %>
<%= content_tag(:span, '', :title => l(:title_locked_by_you),
:class => 'icon icon-dmsf-lockedbycurrent') %>
<% end %>
</td>
<td class="version"></td>
<td class="workflow"></td>
<td class="author"><%= h(subfolder.user) %></td>
<td class="actions">
<% if @folder_manipulation_allowed %>
<div class="right_icon_box">
<% unless locked %>
<%= link_to('',
edit_dmsf_path(:id => @project, :folder_id => subfolder),
:title => l(:link_edit, :title => h(subfolder.title)),
:class => 'icon icon-edit') %>
<%= link_to('',
lock_dmsf_path(:id => @project, :folder_id => subfolder),
:title => l(:title_lock_file),
:class => 'icon icon-dmsf-lock') %>
<% if subfolder.notification %>
<%= link_to('',
notify_deactivate_dmsf_path(:id => @project, :folder_id => subfolder),
:title => l(:title_notifications_active_deactivate),
:class => 'icon icon-notification-on') %>
<% else %>
<%= link_to('',
notify_activate_dmsf_path(:id => @project, :folder_id => subfolder),
:title => l(:title_notifications_not_active_activate),
:class => 'icon icon-notification-off') %>
<% end %>
<% if link %>
<%= link_to('',
dmsf_link_path(link),
:data => {:confirm => l(:text_are_you_sure)},
:method => :delete,
:title => l(:title_delete),
:class => 'icon icon-del') %>
<% else %>
<%= link_to('',
delete_dmsf_path(:id => @project, :folder_id => @folder, :delete_folder_id => subfolder),
:data => {:confirm => l(:text_are_you_sure)},
:title => l(:title_delete),
:class => 'icon icon-del') %>
<% end %>
<% else %>
<span class="icon"></span>
<% if (!locked_for_user || @force_file_unlock_allowed) && subfolder.unlockable? %>
<%= link_to('',
unlock_dmsf_path(:id => @project, :folder_id => subfolder),
:title => l(:title_unlock_file),
:class => 'icon icon-dmsf-unlock')%>
<% end %>
<% end %>
</div>
<% end %>
</td>
<td class="hidden">0</td>
<td class="hidden">0</td>

View File

@ -0,0 +1,179 @@
<%#=
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2014 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.
%>
<% locked_for_user = file.locked_for_user? %>
<% locked = file.locked? %>
<% wf = DmsfWorkflow.find_by_id(file.last_revision.dmsf_workflow_id) %>
<td class="check"><%= check_box_tag(link ? 'file_links[]' : 'files[]',
link ? link.id : file.id, false, :title => l(:title_check_for_zip_download_or_email)) %></td>
<td class="title">
<% file_download_url = url_for({:only_path => false, :controller => :dmsf_files, :action => 'show', :id => file, :download => ''}) %>
<%= link_to(h(link ? link.name : file.last_revision.display_title),
file_download_url,
:class => "icon icon-file #{DmsfHelper.filetype_css(file.name)}",
:title => l(:title_title_version_version_download, :title => h(file.title), :version => file.version),
'data-downloadurl' => "#{file.last_revision.detect_content_type}:#{h(file.name)}:#{file_download_url}") %>
<div class="filename" title="<%= l(:title_filename_for_download)%>"><%= h(file.display_name) %></div>
</td>
<td class="size"><%= number_to_human_size(file.last_revision.size) %></td>
<td class="modified">
<%= format_time(file.last_revision.updated_at) %>
<% if locked_for_user %>
<% if file.lock.reverse[0].user %>
<%= link_to('',
user_path(file.lock.reverse[0].user),
:title => l(:title_locked_by_user, :user => file.lock.reverse[0].user),
:class => 'icon icon-dmsf-locked') %>
<% else %>
<%= content_tag(:span, '',
:title => l(:notice_account_unknown_email),
:class => 'icon icon-dmsf-locked') %>
<% end %>
<% elsif locked %>
<%= content_tag(:span, '', :title => l(:title_locked_by_you),
:class => 'icon icon-dmsf-lockedbycurrent') %>
<% end %>
</td>
<td class="version"><%= file.last_revision.version %></td>
<td class="workflow">
<% if wf && @file_manipulation_allowed %>
<%= link_to(
file.last_revision.workflow_str(false),
log_dmsf_workflow_path(
:project_id => @project.id,
:id => wf.id,
:dmsf_file_revision_id => file.last_revision.id),
:title => DmsfWorkflow.assignments_to_users_str(wf.next_assignments(file.last_revision.id)),
:remote => true) %>
<% else %>
<%= file.last_revision.workflow_str(false) %>
<% end %>
</td>
<td class="author"><%= h(file.last_revision.user) %></td>
<td class="actions">
<% if @file_manipulation_allowed %>
<div class="right_icon_box">
<% unless locked %>
<%= link_to('',
dmsf_file_path(:id => file),
:title => l(:link_details, :title => h(file.last_revision.title)),
:class => 'icon icon-dmsf-file-details') %>
<%= link_to('',
lock_dmsf_files_path(:id => file),
:title => l(:title_lock_file),
:class => 'icon icon-dmsf-lock') %>
<% if file.notification %>
<%= link_to('',
notify_deactivate_dmsf_files_path(:id => file),
:title => l(:title_notifications_active_deactivate),
:class => 'icon icon-notification-on') %>
<% else %>
<%= link_to('',
notify_activate_dmsf_files_path(:id => file),
:title => l(:title_notifications_not_active_activate),
:class => 'icon icon-notification-off') %>
<% end %>
<% if link %>
<%= link_to('',
dmsf_link_path(link),
:data => {:confirm => l(:text_are_you_sure)},
:method => :delete,
:title => l(:title_delete),
:class => 'icon icon-del') %>
<% else %>
<%= link_to('',
dmsf_file_path(:id => file),
:data => {:confirm => l(:text_are_you_sure)},
:method => :delete,
:title => l(:title_delete),
:class => 'icon icon-del') unless locked_for_user %>
<% end %>
<% else %>
<span class="icon"></span>
<% if (!locked_for_user || @force_file_unlock_allowed) && file.unlockable? %>
<%= link_to('',
unlock_dmsf_files_path(:id => file),
:title => l(:title_unlock_file),
:class => 'icon icon-dmsf-unlock')%>
<% end %>
<span class="icon icon-margin-left"></span>
<span class="icon"></span>
<% end %>
<% case file.last_revision.workflow %>
<% when DmsfWorkflow::STATE_WAITING_FOR_APPROVAL %>
<% if wf %>
<% assignments = wf.next_assignments(file.last_revision.id) %>
<% index = assignments.find_index{|assignment| assignment.user_id == User.current.id} if assignments %>
<% if index %>
<%= link_to('',
action_dmsf_workflow_path(
:project_id => @project.id,
:id => wf.id,
:dmsf_workflow_step_assignment_id => assignments[index].id,
:dmsf_file_revision_id => file.last_revision.id),
:title => l(:title_waiting_for_approval),
:class => 'icon icon-dmsf-waiting-for-approval',
:remote => true) %>
<% else %>
<%= content_tag(:span, '',
:title => "#{l(:label_dmsf_wokflow_action_approve)} #{l(:label_dmsf_wokflow_action_reject)} #{l(:label_dmsf_wokflow_action_delegate)}",
:class => 'icon icon-dmsf-waiting-for-approval') %>
<% end %>
<% else %>
<%= content_tag(:span, '',
:title => "#{l(:label_dmsf_wokflow_action_approve)} #{l(:label_dmsf_wokflow_action_reject)} #{l(:label_dmsf_wokflow_action_delegate)}",
:class => 'icon icon-dmsf-waiting-for-approval') %>
<% end %>
<% when DmsfWorkflow::STATE_APPROVED %>
<%= content_tag(:span, '', :title => l(:title_approved),
:class => 'icon icon-dmsf-approved') %>
<% when DmsfWorkflow::STATE_ASSIGNED %>
<% if User.current && (file.last_revision.dmsf_workflow_assigned_by == User.current.id) && wf %>
<%= link_to('',
start_dmsf_workflow_path(
: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-dmsf-assigned') %>
<% else %>
<%= content_tag(:span, '',
title => l(:label_dmsf_wokflow_action_start),
:class => 'icon icon-dmsf-assigned') %>
<% end %>
<% when DmsfWorkflow::STATE_REJECTED %>
<%= content_tag(:span, '', :title => l(:title_rejected),
:class => 'icon icon-dmsf-rejected') %>
<% else %>
<% if @workflows_available %>
<%= link_to('',
assign_dmsf_workflow_path(
:project_id => @project.id,
:dmsf_file_revision_id => file.last_revision.id),
:title => l(:label_dmsf_wokflow_action_assign),
:class => 'icon icon-dmsf-none',
:remote => true) %>
<% end %>
<% end %>
</div>
<% end %>
</td>
<td class="hidden">1</td>
<td class="hidden"><%= file.last_revision.size %></td>

View File

@ -18,17 +18,17 @@
<h2>
<% if folder %>
<%= link_to l(:link_documents), dmsf_path(:id => @project) %>
<%= link_to l(:link_documents), dmsf_folder_path(:id => @project) %>
<% folder.dmsf_path.each do |path_element| %>
/
<% if !filename && path_element == folder.dmsf_path.last %>
<%= h(path_element.title) %>
<% else %>
<%= link_to h(path_element.title), dmsf_path(:id => @project, :folder_id => path_element) %>
<%= link_to h(path_element.title), dmsf_folder_path(:id => @project, :folder_id => path_element) %>
<% end %>
<% end %>
<% else %>
<%= link_to l(:link_documents), dmsf_path(:id => @project) %>
<%= link_to l(:link_documents), dmsf_folder_path(:id => @project) %>
<% end %>
<% if filename %>
/

View File

@ -20,9 +20,39 @@
<% html_title(l(:dmsf)) %>
<div class="contextual">
<%= link_to(image_tag('copy.png'),
{:controller => :dmsf_folders_copy, :action => 'new', :id => @folder },
:title => l(:title_copy)) if @folder.id %>
<% if User.current.allowed_to?(:folder_manipulation, @project) && params[:action] == 'edit' %>
<% unless @folder.locked? %>
<%= link_to(l(:button_lock),
lock_dmsf_path(:id => @project, :folder_id => @folder),
:title => l(:title_lock_file),
:class => 'icon icon-dmsf-lock') %>
<% if @folder.notification %>
<%= link_to(l(:label_notifications_off),
notify_deactivate_dmsf_path(:id => @project, :folder_id => @folder),
:title => l(:title_notifications_active_deactivate),
:class => 'icon icon-notification-on') %>
<% else %>
<%= link_to(l(:label_notifications_on),
notify_activate_dmsf_path(:id => @project, :folder_id => @folder),
:title => l(:title_notifications_not_active_activate),
:class => 'icon icon-notification-off') %>
<% end %>
<%= link_to(l(:button_copy), copy_folder_path(:id => @folder),
:title => l(:title_copy), :class => 'icon icon-copy') %>
<%= link_to(l(:button_delete),
delete_dmsf_path(:id => @project, :folder_id => @folder.dmsf_folder_id, :delete_folder_id => @folder),
:data => {:confirm => l(:text_are_you_sure)},
:title => l(:title_delete),
:class => 'icon icon-del') %>
<% else %>
<% if (!@folder.locked_for_user? || User.current.allowed_to?(:force_file_unlock, @project)) && @folder.unlockable? %>
<%= link_to(l(:button_unlock),
unlock_dmsf_path(:id => @project, :folder_id => @folder),
:title => l(:title_unlock_file),
:class => 'icon icon-dmsf-unlock')%>
<% end %>
<% end %>
<% end %>
</div>
<% create = @pathfolder == @parent %>
@ -64,7 +94,3 @@
<% end %>
<%= wikitoolbar_for 'dmsf_folder_description' %>
<% content_for :header_tags do %>
<%= stylesheet_link_tag 'dmsf', :plugin => 'redmine_dmsf' %>
<% end %>

View File

@ -20,11 +20,22 @@
<% html_title(l(:dmsf)) %>
<div class="contextual">
<% if User.current.allowed_to?(:folder_manipulation, @project) %>
<% if @project.dmsf_notification %>
<%= link_to(l(:label_notifications_off),
notify_deactivate_dmsf_path(:id => @project),
:title => l(:title_notifications_active_deactivate),
:class => 'icon icon-notification-on') %>
<% else %>
<%= link_to(l(:label_notifications_on),
notify_activate_dmsf_path(:id => @project),
:title => l(:title_notifications_active_deactivate),
:class => 'icon icon-notification-off') %>
<% end %>
<% end %>
</div>
<h2>
<%= link_to l(:link_documents), {:controller => 'dmsf', :action => 'show', :id => @project } %>
</h2>
<%= render(:partial => 'path', :locals => {:folder => nil, :filename => nil}) %>
<%= form_for(@project, :url => {:action => 'save_root', :id => @project},
:html => {:method=>:post}) do |f| %>
@ -39,8 +50,4 @@
<%= submit_tag(l(:submit_save)) %>
<% end %>
<%= wikitoolbar_for 'dmsf_folder_description' %>
<% content_for :header_tags do %>
<%= stylesheet_link_tag 'dmsf', :plugin => 'redmine_dmsf' %>
<% end %>
<%= wikitoolbar_for 'project_dmsf_description' %>

View File

@ -1,9 +1,9 @@
<%#=
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2011 Vít Jonáš <vit.jonas@gmail.com>
# Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk>
# Copyright (C) 2013 Karel Pičman <karel.picman@kontron.com>
# Copyright (C) 2011 Vít Jonáš <vit.jonas@gmail.com>
# Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk>
# Copyright (C) 2014 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
@ -22,47 +22,73 @@
<% html_title(l(:dmsf)) %>
<div class="contextual">
<% if User.current.allowed_to?(:folder_manipulation, @project) %>
<% if @folder.nil? %>
&nbsp;
<%= link_to('', {:action => 'edit_root', :id => @project},
:title => l(:link_edit, :title => l(:link_documents)), :class => 'icon icon-edit') %>
<% elsif @locked_for_user %>
&nbsp;
<%= link_to('', {:action => 'edit', :id => @project, :folder_id => @folder },
:title => l(:link_edit, :title => h(@folder.title)), :class => 'icon icon-edit') %>
<% if @folder_manipulation_allowed %>
<% if @folder.nil? %>
<%= link_to(l(:button_edit),
edit_root_dmsf_path(:id => @project),
:title => l(:link_edit, :title => l(:link_documents)),
:class => 'icon icon-edit') %>
<% elsif !@locked_for_user %>
<%= link_to(l(:button_edit),
edit_dmsf_path(:id => @project, :folder_id => @folder),
:title => l(:link_edit, :title => h(@folder.title)),
:class => 'icon icon-edit') %>
<% end %>
<% if @folder && (!@locked_for_user || User.current.allowed_to?(:force_file_unlock, @project)) %>
<% if @folder.locked? %>
<% unless @folder.unlockable? %>
<%= image_tag('locked.png', :plugin => :redmine_dmsf, :title => l(:title_folder_parent_locked, :name => @folder.folder.lock.reverse[0].folder.title)) unless @folder.nil?%>
<%= link_to(l(:button_unlock),
:title => l(:title_folder_parent_locked, :name => @folder.folder.lock.reverse[0].folder.title),
:class => 'icon icon-dmsf-unlock') if @folder %>
<% else %>
<%= link_to_function(image_tag('unlock.png', :plugin => 'redmine_dmsf'),
"manipulation_link('#{url_for(:action => 'unlock', :id => @project, :folder_id => @folder, :current => request.url)}')",
:title => l(:title_unlock_folder)) if @folder %>
<%= link_to(l(:button_unlock),
unlock_dmsf_path(:id => @project, :folder_id => @folder, :current => request.url),
:title => l(:title_unlock_folder),
:class => 'icon icon-dmsf-unlock') if @folder %>
<% end %>
<% else %>
<%= link_to_function(image_tag('lock.png', :plugin => 'redmine_dmsf'),
"manipulation_link('#{url_for(:action => 'lock', :id => @project, :folder_id => @folder, :current => request.url)}')",
:title => l(:title_lock_folder)) if @folder %>
<%= link_to(l(:button_lock),
lock_dmsf_path(:id => @project, :folder_id => @folder, :current => request.url),
:title => l(:title_lock_folder),
:class => 'icon icon-dmsf-lock') if @folder %>
<% end %>
<% end %>
<% unless @folder %>
&nbsp;
<% if @project.dmsf_notification %>
<%= link_to_function(image_tag('notify.png', :plugin => :redmine_dmsf),
"manipulation_link('#{url_for(:action => 'notify_deactivate', :id => @project)}')",
:title => l(:title_notifications_active_deactivate)) %>
<% else %>
<%= link_to_function(image_tag('notifynot.png', :plugin => :redmine_dmsf),
"manipulation_link('#{url_for(:action => 'notify_activate', :id => @project)}')",
:title => l(:title_notifications_not_active_activate)) %>
<% end %>
<% end %>
&nbsp;
<%= link_to('', {:action => 'new', :id => @project, :parent_id => @folder },
:title => l(:link_create_folder), :class => 'icon icon-add') unless @locked_for_user %>
<% end %>
<% unless @folder %>
<% if @project.dmsf_notification %>
<%= link_to(l(:label_notifications_off),
notify_deactivate_dmsf_path(:id => @project),
:title => l(:title_notifications_active_deactivate),
:class => 'icon icon-notification-on') %>
<% else %>
<%= link_to(l(:label_notifications_on),
notify_activate_dmsf_path(:id => @project),
:title => l(:title_notifications_active_deactivate),
:class => 'icon icon-notification-off') %>
<% end %>
<% else %>
<% if @folder.notification %>
<%= link_to(l(:label_notifications_off),
notify_deactivate_dmsf_path(:id => @project, :folder_id => @folder),
:title => l(:title_notifications_active_deactivate),
:class => 'icon icon-notification-on') %>
<% else %>
<%= link_to(l(:label_notifications_on),
notify_activate_dmsf_path(:id => @project, :folder_id => @folder),
:title => l(:title_notifications_not_active_activate),
:class => 'icon icon-notification-off') %>
<% end %>
<% end %>
<% if @file_manipulation_allowed %>
<%= link_to(l(:label_create_link),
new_dmsf_link_path(:project_id => @project.id, :dmsf_folder_id => @folder ? @folder.id : @folder, :target_project_id => @project.id),
:title => l(:link_create_link),
:class => 'icon icon-link') unless @locked_for_user %>
<% end %>
<%= link_to(l(:link_create_folder),
new_dmsf_path(:id => @project, :parent_id => @folder),
:title => l(:link_create_folder),
:class => 'icon icon-add') unless @locked_for_user %>
<% end %>
</div>
<%= render(:partial => 'path', :locals => {:folder => @folder, :filename => nil}) %>
@ -81,7 +107,7 @@
<div class="controls" style="float: left">
<%= submit_tag(l(:submit_download), :title => l(:title_download_checked), :name => 'download_entries') %>
<%= submit_tag(l(:submit_email), :title => l(:title_send_checked_by_email), :name => 'email_entries') %>
<% if User.current.allowed_to?(:file_manipulation, @project) && @folder && !@locked_for_user %>
<% if @file_manipulation_allowed && @folder_manipulation_allowed && !@locked_for_user %>
<button type="button" id="entries_delete_button" title="<%= l(:title_delete_checked) %>"><%= l(:button_delete) %></button>
<% end %>
</div>
@ -102,236 +128,37 @@
<th class="hidden"></th>
</tr>
</thead>
<tbody>
<% @subfolders.each do |subfolder| %>
<% locked_for_user = subfolder.locked_for_user? %>
<% locked = subfolder.locked? %>
<tbody>
<% @subfolders.each do |subfolder| %>
<tr class="dir">
<td class="check"><%= check_box_tag('subfolders[]', subfolder.id, false, :title => l(:title_check_for_zip_download_or_email)) %></td>
<td class="title">
<%= link_to(h(subfolder.title),
{:action => 'show', :id => @project, :folder_id => subfolder}, :class => 'icon icon-folder') %>
<div class="filename" title="<%= l(:title_number_of_files_in_directory)%>">[<%= subfolder.files.visible.count %>]</div>
</td>
<td class="size"></td>
<td class="modified"><%= format_time(subfolder.updated_at) %>
<% if locked_for_user %>
<% if subfolder.lock.reverse[0].user %>
<%= link_to(image_tag('locked.png', :plugin => :redmine_dmsf),
{ :controller => 'users', :action => 'show', :id => subfolder.lock.reverse[0].user },
:title => l(:title_locked_by_user, :user => subfolder.lock.reverse[0].user.to_s)) %>
<% else %>
<%= image_tag('locked.png', :title => l(:notice_account_unknown_email), :plugin => :redmine_dmsf) %>
<% end %>
<% elsif locked %>
<%= image_tag('lockedbycurrent.png', :title => l(:title_locked_by_you), :plugin => :redmine_dmsf) %>
<% end %>
</td>
<td class="version"></td>
<td class="workflow"></td>
<td class="author"><%= h(subfolder.user) %></td>
<td class="actions">
<% if @folder_manipulation_allowed %>
<div class="right_icon_box" style="width:26px;">
<% if subfolder.notification %>
<%= link_to_function(image_tag('notify.png', :plugin => :redmine_dmsf),
"manipulation_link('#{url_for(:action => 'notify_deactivate', :id => @project, :folder_id => subfolder)}')",
:title => l(:title_notifications_active_deactivate)) %>
<% else %>
<%= link_to_function(image_tag('notifynot.png', :plugin => :redmine_dmsf),
"manipulation_link('#{url_for(:action => 'notify_activate', :id => @project, :folder_id => subfolder)}')",
:title => l(:title_notifications_not_active_activate)) %>
<% end %>
</div>
<div class="right_icon_box" style="width: 70px;">
<div style="float: left">
<%= link_to(image_tag('edit.png', :class =>'detail_icon'),
{:action => 'edit', :id => @project, :folder_id => subfolder },
:title => l(:link_edit, :title => h(subfolder.title))) unless locked_for_user %>
</div>
<div style="float: right; width: 44px;">
<% unless locked_for_user && !User.current.allowed_to?(:force_file_unlock, @project)%>
<% if locked %>
<% if subfolder.unlockable? %>
<%= link_to_function(image_tag('unlock.png', :plugin => :redmine_dmsf),
"manipulation_link('#{url_for(:controller => 'dmsf', :action => 'unlock',
:id => @project, :folder_id => subfolder)}')",
:title => l(:title_unlock_file))%>
<% else %>
<%= image_tag('locked.png', :plugin => :redmine_dmsf,
:title => l(:title_folder_parent_locked, :name => subfolder.lock.reverse[0].folder.title)) %>
<% end %>
<% else %>
<%= link_to_function(image_tag('lock.png', :plugin => :redmine_dmsf),
"manipulation_link('#{url_for(:controller => 'dmsf', :action => 'lock',
:id => @project, :folder_id => subfolder)}')",
:title => l(:title_lock_file)) %>
<% end %>
&nbsp;
<% end %>
<%= link_to_function(image_tag('delete.png', :plugin => :redmine_dmsf),
"confirmation_link('#{url_for(:action => 'delete', :id => @project, :folder_id => @folder, :delete_folder_id => subfolder)}', '#{l(:question_do_you_really_want_to_delete_this_entry)}')",
:title => l(:title_delete)) unless locked_for_user %>
</div>
</div>
<br class="clear" />
<% end %>
</td>
<td class="hidden">0</td>
<td class="hidden">0</td>
<%= render(:partial => 'dir', :locals => {:subfolder => subfolder, :link => nil}) %>
</tr>
<% end %>
<% workflows_available = DmsfWorkflow.where(['project_id = ? OR project_id IS NULL', @project.id]).count > 0 %>
<% @dir_links.each do |link| %>
<tr class="gray">
<%= render(:partial => 'dir', :locals => {:subfolder => link.target_folder, :link => link}) %>
</tr>
<% end %>
<% @files.each do |file| %>
<% unless file.last_revision %>
<% Rails.logger.error "Error: dmsf_file id #{file.id} has no revision!" %>
<% next %>
<% end %>
<% locked_for_user = file.locked_for_user? %>
<% locked = file.locked? %>
<% wf = DmsfWorkflow.find_by_id(file.last_revision.dmsf_workflow_id) %>
<% end %>
<tr class="file">
<td class="check"><%= check_box_tag('files[]', file.id, false, :title => l(:title_check_for_zip_download_or_email)) %></td>
<td class="title">
<% file_download_url = url_for({:only_path => false, :controller => :dmsf_files, :action => 'show', :id => file, :download => ''}) %>
<%= link_to(h(file.last_revision.display_title),
file_download_url,
:class => "icon icon-file #{DmsfHelper.filetype_css(file.name)}",
:title => l(:title_title_version_version_download, :title => h(file.title), :version => file.version),
'data-downloadurl' => "#{file.last_revision.detect_content_type}:#{h(file.name)}:#{file_download_url}") %>
<div class="filename" title="<%= l(:title_filename_for_download)%>"><%= h(file.display_name) %></div>
</td>
<td class="size"><%= number_to_human_size(file.last_revision.size) %></td>
<td class="modified">
<%= format_time(file.last_revision.updated_at) %>
<% if locked_for_user %>
<% if file.lock.reverse[0].user %>
<%= link_to(image_tag('locked.png', :plugin => :redmine_dmsf),
{:controller => 'users', :action => 'show', :id => file.lock.reverse[0].user },
:title => l(:title_locked_by_user, :user => file.lock.reverse[0].user.to_s)) %>
<% else %>
<%= image_tag('locked.png', :title => l(:notice_account_unknown_email), :plugin => :redmine_dmsf) %>
<% end %>
<% elsif locked %>
<%= image_tag('lockedbycurrent.png', :title => l(:title_locked_by_you), :plugin => :redmine_dmsf) %>
<% end %>
</td>
<td class="version"><%= file.last_revision.version %></td>
<td class="workflow">
<% if wf && @file_manipulation_allowed %>
<%= link_to(
file.last_revision.workflow_str(false),
log_dmsf_workflow_path(
:project_id => @project.id,
:id => wf.id,
:dmsf_file_revision_id => file.last_revision.id),
:title => DmsfWorkflow.assignments_to_users_str(wf.next_assignments(file.last_revision.id)),
:remote => true) %>
<% else %>
<%= file.last_revision.workflow_str(false) %>
<% end %>
</td>
<td class="author"><%= h(file.last_revision.user) %></td>
<td class="actions">
<% if @file_manipulation_allowed %>
<div class="right_icon_box" style="width:26px;">
<% if file.notification %>
<%= link_to_function(image_tag('notify.png', :plugin => :redmine_dmsf),
"manipulation_link('#{url_for(:controller => 'dmsf_files', :action => 'notify_deactivate', :id => file)}')",
:title => l(:title_notifications_active_deactivate)) %>
<% else %>
<%= link_to_function(image_tag('notifynot.png', :plugin => :redmine_dmsf),
"manipulation_link('#{url_for(:controller => 'dmsf_files', :action => 'notify_activate', :id => file)}')",
:title => l(:title_notifications_not_active_activate)) %>
<% end %>
<% case file.last_revision.workflow %>
<% when DmsfWorkflow::STATE_WAITING_FOR_APPROVAL %>
<% if wf %>
<% assignments = wf.next_assignments(file.last_revision.id) %>
<% index = assignments.find_index{|assignment| assignment.user_id == User.current.id} if assignments %>
<% if index %>
<%= link_to(
image_tag('waiting_for_approval.png', :plugin => :redmine_dmsf),
action_dmsf_workflow_path(
:project_id => @project.id,
:id => wf.id,
:dmsf_workflow_step_assignment_id => assignments[index].id,
:dmsf_file_revision_id => file.last_revision.id),
:title => l(:title_waiting_for_approval),
:remote => true) %>
<% else %>
<%= image_tag('waiting_for_approval.png', :title => "#{l(:label_dmsf_wokflow_action_approve)} #{l(:label_dmsf_wokflow_action_reject)} #{l(:label_dmsf_wokflow_action_delegate)}", :plugin => :redmine_dmsf) %>
<% end %>
<% else %>
<%= image_tag('waiting_for_approval.png', :title => "#{l(:label_dmsf_wokflow_action_approve)} #{l(:label_dmsf_wokflow_action_reject)} #{l(:label_dmsf_wokflow_action_delegate)}", :plugin => :redmine_dmsf) %>
<% end %>
<% when DmsfWorkflow::STATE_APPROVED %>
<%= image_tag('approved.png', :title => l(:title_approved), :plugin => :redmine_dmsf) %>
<% when DmsfWorkflow::STATE_ASSIGNED %>
<% if User.current && (file.last_revision.dmsf_workflow_assigned_by == User.current.id) && wf %>
<%= link_to_function(image_tag('assigned.png', :plugin => :redmine_dmsf),
"manipulation_link('#{start_dmsf_workflow_path(
:id => file.last_revision.dmsf_workflow_id,
:dmsf_file_revision_id => file.last_revision.id)}')",
:title => l(:label_dmsf_wokflow_action_start)) %>
<% else %>
<%= image_tag('assigned.png', :title => l(:label_dmsf_wokflow_action_start), :plugin => :redmine_dmsf) %>
<% end %>
<% when DmsfWorkflow::STATE_REJECTED %>
<%= image_tag('rejected.png', :title => l(:title_rejected), :plugin => :redmine_dmsf) %>
<% else %>
<% if workflows_available %>
<%= link_to(
image_tag('none.png', :plugin => :redmine_dmsf),
assign_dmsf_workflow_path(
:project_id => @project.id,
:dmsf_file_revision_id => file.last_revision.id),
:title => l(:label_dmsf_wokflow_action_assign),
:remote => true) %>
<% end %>
<% end %>
</div>
<div class="right_icon_box" style="width: 70px">
<div style="float: left">
<%= link_to(image_tag('filedetails.png', :plugin => :redmine_dmsf, :class =>'detail_icon'),
{:controller => 'dmsf_files', :action => :show, :id => file },
:title => l(:link_details, :title =>h(file.last_revision.title))) %>
</div>
<div style="float: right; width: 44px;">
<% if !locked_for_user || @force_file_unlock_allowed %>
<% if locked %>
<% if file.unlockable? %>
<%= link_to_function(image_tag('unlock.png', :plugin => :redmine_dmsf),
"manipulation_link('#{url_for(:controller => 'dmsf_files', :action => 'unlock', :id => file)}')",
:title => l(:title_unlock_file))%>
<% else %>
<%= image_tag('locked.png', :plugin => :redmine_dmsf,
:title => l(:title_file_parent_locked, :name => file.folder.lock.reverse[0].folder.title)) %>
<% end%>
<% else %>
<%= link_to_function(image_tag('lock.png', :plugin => :redmine_dmsf),
"manipulation_link('#{url_for(:controller => 'dmsf_files', :action => 'lock', :id => file)}')",
:title => l(:title_lock_file)) %>
<% end %>
&nbsp;
<% end %>
<% unless locked_for_user %>
<%= link_to_function(image_tag('delete.png', :plugin => :redmine_dmsf),
"confirmation_link('#{url_for(:controller => 'dmsf_files', :action => 'delete', :id => file)}', '#{l(:question_do_you_really_want_to_delete_this_entry)}')",
:title => l(:title_delete)) %>
<% end %>
</div>
</div>
<br class="clear" />
<% end %>
</td>
<td class="hidden">1</td>
<td class="hidden"><%= file.last_revision.size %></td>
<%= render(:partial => 'file', :locals => {:file => file, :link => nil}) %>
</tr>
<% end %>
<% @file_links.each do |link| %>
<% unless link.target_file.last_revision %>
<% Rails.logger.error "Error: dmsf_file id #{link.target_id} has no revision!" %>
<% next %>
<% end %>
<tr class="gray">
<%= render(:partial => 'file', :locals => {:file => link.target_file, :link => link}) %>
</tr>
<% end %>
</tbody>
</table>
<br />
</table>
<% end %>
<script type="text/javascript">
@ -355,19 +182,16 @@
end
%>
<% content_for :header_tags do %>
<%= stylesheet_link_tag 'jquery-ui/jquery-ui-1.9.2.css', :plugin => 'redmine_dmsf' %>
<% content_for :header_tags do %>
<%= stylesheet_link_tag 'plupload/jquery.ui.plupload.css', :plugin => 'redmine_dmsf' %>
<%= stylesheet_link_tag 'jquery.dataTables/jquery-ui.dataTables.css', :plugin => 'redmine_dmsf' %>
<%= stylesheet_link_tag 'dmsf', :plugin => 'redmine_dmsf' %>
<%= javascript_include_tag 'jquery-1.6.1.min.js', :plugin => 'redmine_dmsf' %>
<%= javascript_include_tag 'jquery-ui-1.8.13.min.js', :plugin => 'redmine_dmsf' %>
<%= javascript_include_tag 'jquery.dataTables/jquery.dataTables.min.js', :plugin => 'redmine_dmsf' %>
<script type="text/javascript">
jQuery.noConflict();
jQuery(document).ready(function() {
jQuery('#browser').dataTable({
<script type="text/javascript">
$(document).ready(function() {
$('#browser').dataTable({
'bJQueryUI': true,
'oLanguage': {
'sUrl': "<%= plugin_asset_path(:redmine_dmsf, 'javascripts', sUrl) %>"
@ -382,14 +206,14 @@
{ 'iDataSort': 9, 'aTargets': [ 2 ] }
],
'fnInitComplete': function() {
jQuery('div.controls').prependTo(jQuery('#browser_wrapper div.fg-toolbar')[0]);
jQuery('div.controls').prependTo(jQuery('#browser_wrapper div.fg-toolbar')[0]);
},
'fnInfoCallback': function( oSettings, iStart, iEnd, iMax, iTotal, sPre ) {
return "<%= l(:label_number_of_folders)%>: <%= @subfolders.length %>, <%= l(:label_number_of_documents)%>: <%= @files.length %>";
return "<%= l(:label_number_of_folders)%>: <%= @subfolders.count + @dir_links.count %>, <%= l(:label_number_of_documents)%>: <%= @files.count + @file_links.count %>";
}
});
jQuery('[data-downloadurl]').each(function() {
$('[data-downloadurl]').each(function() {
var url = this.getAttribute('data-downloadurl');
if (this.addEventListener) {
this.addEventListener('dragstart', function(e) {
@ -400,12 +224,11 @@
}
});
jQuery('#entries_form').submit(function () {
jQuery(this).removeAttr('data-submitted');
$('#entries_form').submit(function () {
$(this).removeAttr('data-submitted');
});
});
</script>
<% end %>
<%= render(:partial => 'multi_upload') if (@file_manipulation_allowed && !@locked_for_user) %>
<br/>
<%= render(:partial => 'multi_upload') if (@file_manipulation_allowed && !@locked_for_user) %>

View File

@ -24,40 +24,34 @@
<div class="contextual">
<% if User.current.allowed_to?(:file_manipulation, @project) %>
<% unless @file.locked_for_user? && !User.current.allowed_to?(:force_file_unlock, @project)%>
<% if @file.locked? %>
<% unless @file.unlockable? %>
<%= image_tag('locked.png', :plugin => :redmine_dmsf, :title => l(:title_file_parent_locked, :name => @file.lock.reverse[0].folder.title)) %>
<% else %>
<%= link_to_function(image_tag('unlock.png', :plugin => 'redmine_dmsf'),
"manipulation_link('#{url_for(:action => 'unlock', :id => @file, :current => request.url)}')",
:title => l(:title_unlock_file)) %>
<% end %>
<% else %>
<%= link_to_function(image_tag('lock.png', :plugin => 'redmine_dmsf'),
"manipulation_link('#{url_for(:action => 'lock', :id => @file, :current => request.url)}')",
:title => l(:title_lock_file)) %>
<% end %>
<% end %>
<% unless @file.locked_for_user? %>
&nbsp;
<%= link_to_function(image_tag('delete.png', :plugin => 'redmine_dmsf'),
"confirmation_link('#{url_for(:action => 'delete', :id => @file)}', '#{l(:question_do_you_really_want_to_delete_this_entry)}')",
:title => l(:title_delete)) %>
<% end %>
&nbsp;
<% if @file.notification %>
<%= link_to_function(image_tag('notify.png', :plugin => 'redmine_dmsf'),
"manipulation_link('#{url_for(:action => 'notify_deactivate', :id => @file, :current => request.url)}')",
:title => l(:title_notifications_active_deactivate)) %>
<% unless @file.locked? %>
<%= link_to(l(:button_lock),
lock_dmsf_files_path(:id => @file),
:title => l(:title_lock_file),
:class => 'icon icon-dmsf-lock') %>
<% if @file.notification %>
<%= link_to(l(:label_notifications_off),
notify_deactivate_dmsf_files_path(:id => @file),
:title => l(:title_notifications_active_deactivate),
:class => 'icon icon-notification-on') %>
<% else %>
<%= link_to(l(:label_notifications_on),
notify_activate_dmsf_files_path(:id => @file),
:title => l(:title_notifications_not_active_activate),
:class => 'icon icon-notification-off') %>
<% end %>
<%= link_to(l(:button_copy), copy_file_path(:id => @file),
:title => l(:title_copy), :class => 'icon icon-copy') %>
<%= delete_link @file %>
<% else %>
<%= link_to_function(image_tag('notifynot.png', :plugin => 'redmine_dmsf'),
"manipulation_link('#{url_for(:action => 'notify_activate', :id => @file, :current => request.url)}')",
:title => l(:title_notifications_not_active_activate)) %>
<% end %>
&nbsp;
<%= link_to(image_tag('copy.png'), {:controller => :dmsf_files_copy, :action => 'new', :id => @file }, :title => l(:title_copy_or_move)) %>
<% end %>
<% if (!@file.locked_for_user? || User.current.allowed_to?(:force_file_unlock, @project)) && @file.unlockable? %>
<%= link_to(l(:button_unlock),
unlock_dmsf_files_path(:id => @file),
:title => l(:title_unlock_file),
:class => 'icon icon-dmsf-unlock')%>
<% end %>
<% end %>
<% end %>
</div>
<%= render(:partial => '/dmsf/path', :locals => {:folder => @file.folder, :filename => @file.title}) %>
@ -72,15 +66,22 @@
<div class="revision_box dmsf_detail dataTables_wrapper">
<div class="fg-toolbar ui-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix">
<div class="dataTables_lenght">
<div class="controls" style="float: right">
<%= link_to_function(image_tag('rev_downloads.png', :plugin => 'redmine_dmsf'), "$('#revision_access-#{revision.id}').toggle()", :title => 'Download entries')%>
<%= link_to(image_tag('rev_download.png', :plugin => 'redmine_dmsf'),
{:action => 'show', :id => @file, :download => revision},
:title => l(:title_title_version_version_download, :title => h(revision.title), :version => revision.version)) %>
<div class="controls" style="float: right">
<%= link_to_function(
'',
"$('#revision_access-#{revision.id}').toggle()",
:title => l(:title_download_entries),
:class => 'icon icon-dmsf-rev-downloads') %>
<%= link_to('',
dmsf_file_path(@file, :download => revision),
:title => l(:title_title_version_version_download, :title => h(revision.title), :version => revision.version),
:class => 'icon icon-dmsf-rev-download') %>
<% if User.current.allowed_to?(:file_manipulation, @project) %>
<%= link_to_function(image_tag('rev_delete.png', :plugin => 'redmine_dmsf'),
"confirmation_link('#{url_for(:action => 'delete_revision', :id => revision)}', '#{l(:question_do_you_really_want_to_delete_this_revision)}')",
:title => l(:title_delete_revision)) %>
<%= link_to '',
delete_revision_path(revision),
:data => {:confirm => l(:text_are_you_sure)},
:title => l(:title_delete_revision),
:class => 'icon icon-dmsf-rev-delete' %>
<% end %>
</div>
<i><%= l(:info_revision, :rev => revision.id) %></i>
@ -158,34 +159,34 @@
%>
<script type="text/javascript">
jQuery('a.delete-revision').click(function(event) {
if(!window.confirm('<%= l(:question_do_you_really_want_to_delete_this_revision) %>')) {
$('a.delete-revision').click(function(event) {
if(!window.confirm('<%= l(:text_are_you_sure) %>')) {
event.preventDefault();
}
});
jQuery('a.delete-entry').click(function(event) {
if(!window.confirm('<%= l(:question_do_you_really_want_to_delete_this_entry) %>')) {
$('a.delete-entry').click(function(event) {
if(!window.confirm('<%= l(:text_are_you_sure) %>')) {
event.preventDefault();
}
});
jQuery('#file_upload').change(function() {
if(jQuery("input[name='version']:checked").val() == '0') {
jQuery('#fileMinorVersionRadio').prop('checked', true);
$('#file_upload').change(function() {
if($("input[name='version']:checked").val() == '0') {
$('#fileMinorVersionRadio').prop('checked', true);
}
jQuery('#fileSameVersionRadio').prop('disabled', true);
$('#fileSameVersionRadio').prop('disabled', true);
});
jQuery('#newRevisionFormContentToggle').toggle(function() {
jQuery('#newRevisionFormContentToggle').text('[-]');
jQuery('#newRevisionFormContent').show();
$('#newRevisionFormContentToggle').toggle(function() {
$('#newRevisionFormContentToggle').text('[-]');
$('#newRevisionFormContent').show();
}, function() {
jQuery('#newRevisionFormContentToggle').text('[+]');
jQuery('#newRevisionFormContent').hide();
$('#newRevisionFormContentToggle').text('[+]');
$('#newRevisionFormContent').hide();
});
jQuery('.access-table').dataTable({
$('.access-table').dataTable({
'bJQueryUI': true,
'oLanguage': {
'sUrl': '/plugin_assets/<%= :redmine_dmsf %>/javascripts/<%= url %>'
@ -194,15 +195,13 @@
</script>
<% if @revision.valid? && @file.valid? %>
<script type="text/javascript">
jQuery('#newRevisionFormContentToggle').text('[+]');
jQuery('#newRevisionFormContent').hide();
$('#newRevisionFormContentToggle').text('[+]');
$('#newRevisionFormContent').hide();
</script>
<% end %>
<% content_for :header_tags do %>
<%= stylesheet_link_tag 'jquery-ui/jquery-ui-1.9.2.css', :plugin => 'redmine_dmsf' %>
<% content_for :header_tags do %>
<%= stylesheet_link_tag 'jquery.dataTables/jquery-ui.dataTables.css', :plugin => 'redmine_dmsf' %>
<%= stylesheet_link_tag 'dmsf', :plugin => 'redmine_dmsf' %>
<%= javascript_include_tag 'jquery-1.6.1.min.js', :plugin => 'redmine_dmsf' %>
<%= javascript_include_tag 'jquery-ui-1.8.13.min.js', :plugin => 'redmine_dmsf' %>
<%= javascript_include_tag 'jquery.dataTables/jquery.dataTables.min.js', :plugin => 'redmine_dmsf' %>

View File

@ -28,12 +28,12 @@
<%= form_tag({:action => 'create', :id => @file}, :id => 'copyForm') do |f| %>
<div class="box dmsf_detail">
<p>
<label for="target_project_id"><%=l(:label_target_project)%>:</label>
<label for="target_project_id"><%=l(:field_target_project)%>:</label>
<%= select_tag('target_project_id',
project_tree_options_for_select(DmsfFile.allowed_target_projects_on_copy, :selected => @target_project)) %>
</p>
<p>
<%= label_tag('target_folder_id', "#{l(:label_target_folder)}:") %>
<%= label_tag('target_folder_id', "#{l(:field_target_folder)}:") %>
<%= select_tag('target_folder_id',
options_for_select(DmsfFolder.directory_tree(@target_project),
:selected => (@target_folder.id if @target_folder))) %>
@ -55,12 +55,4 @@
jQuery('#target_project_id').change(function () {
jQuery('#content').load("<%= url_for(:action => 'new') %>", jQuery('#copyForm').serialize());
});
</script>
<% content_for :header_tags do %>
<%= stylesheet_link_tag 'dmsf', :plugin => 'redmine_dmsf' %>
<%= javascript_include_tag 'jquery-1.6.1.min.js', :plugin => 'redmine_dmsf' %>
<script type="text/javascript">
jQuery.noConflict();
</script>
<% end %>
</script>

View File

@ -27,12 +27,12 @@
<%= form_tag({:action => 'copy_to', :id => @folder}, :id => 'copyForm') do |f| %>
<div class="box dmsf_detail">
<p>
<label for="target_project_id"><%= l(:label_target_project) %>:</label>
<label for="target_project_id"><%= l(:field_target_project) %>:</label>
<%= select_tag('target_project_id',
project_tree_options_for_select(DmsfFolder.allowed_target_projects_on_copy, :selected => @target_project)) %>
</p>
<p>
<%= label_tag('target_folder_id', "#{l(:label_target_folder)}:") %>
<%= label_tag('target_folder_id', "#{l(:field_target_folder)}:") %>
<%= select_tag('target_folder_id',
options_for_select(DmsfFolder.directory_tree(@target_project, @folder),
:selected => (@target_folder.id if @target_folder))) %>
@ -46,12 +46,4 @@
jQuery('#target_project_id').change(function () {
jQuery('#content').load("<%= url_for(:action => 'new') %>", jQuery('#copyForm').serialize());
});
</script>
<% content_for :header_tags do %>
<%= stylesheet_link_tag 'dmsf', :plugin => 'redmine_dmsf' %>
<%= javascript_include_tag 'jquery-1.6.1.min.js', :plugin => 'redmine_dmsf' %>
<script type="text/javascript">
jQuery.noConflict();
</script>
<% end %>
</script>

View File

@ -0,0 +1,64 @@
<%# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2014 Karel Pičman <karel.picman@lbcfree.net>
#
# 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.%>
<% html_title(l(:dmsf)) %>
<div class="contextual">
</div>
<%= render(:partial => '/dmsf/path', :locals => {:folder => @dmsf_link.folder, :filename => nil}) %>
<%= labelled_form_for @dmsf_link do |f| %>
<%= error_messages_for @dmsf_link %>
<%= f.hidden_field :project_id, :value => @dmsf_link.project_id %>
<%= f.hidden_field :dmsf_folder_id, :value => @dmsf_link.dmsf_folder_id if @dmsf_link.dmsf_folder_id %>
<div class="box dmsf_detail">
<p>
<%= f.select(:target_project_id,
project_tree_options_for_select(DmsfFile.allowed_target_projects_on_copy,
:selected => @dmsf_link.target_project),
{:required => true}) %>
</p>
<p>
<%= f.select(:target_folder_id,
folder_tree_options_for_select(DmsfFolder.directory_tree(@dmsf_link.target_project),
:selected => @target_folder_id),
{:required => true}) %>
</p>
<p>
<%= f.select(:target_file_id,
options_for_select(
DmsfFolder.file_list(
(@target_folder_id ? DmsfFolder.find(@target_folder_id).files : @dmsf_link.target_project.dmsf_files).visible),
@target_file_id)) %>
</p>
<p>
<%= f.text_field :name, :size => 40, :maxlength => 255, :required => true, :value => @dmsf_link.name %>
</p>
</div>
<%= f.submit l(:button_create) %>
<% end %>
<script type="text/javascript">
$('#dmsf_link_target_project_id').change(function () {
$('#content').load("<%= url_for(:action => 'new', :project_id => @project.id, :dmsf_folder_id => @dmsf_link.dmsf_folder_id, :reload => true) %>", $('#new_dmsf_link').serialize());
});
$('#dmsf_link_target_folder_id').change(function () {
$('#content').load("<%= url_for(:action => 'new', :project_id => @project.id, :dmsf_folder_id => @dmsf_link.dmsf_folder_id) %>", $('#new_dmsf_link').serialize());
});
</script>

View File

@ -0,0 +1,19 @@
<%# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2014 Karel Pičman <karel.picman@lbcfree.net>
#
# 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.%>
<%= render 'form' %>

View File

@ -32,8 +32,4 @@
<%= submit_tag(l(:submit_save), :title => l(:title_save_preferences)) %>
</div>
<% end %>
</div>
<% content_for :header_tags do %>
<%= stylesheet_link_tag 'dmsf', :plugin => 'redmine_dmsf' %>
<% end %>
</div>

View File

@ -41,14 +41,4 @@
<% i += 1 %>
<% end %>
<%= submit_tag(l(:submit_commit)) %>
<% end %>
<% content_for :header_tags do %>
<%= stylesheet_link_tag 'dmsf', :plugin => 'redmine_dmsf' %>
<%= javascript_include_tag 'jquery-1.6.1.min.js', :plugin => 'redmine_dmsf' %>
<script type="text/javascript">
jQuery.noConflict();
jQuery(document).ready(function() {
});
</script>
<% end %>
<% end %>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 459 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 471 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 473 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 458 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 419 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 413 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 419 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 419 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 469 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 B

BIN
assets/images/link.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 662 B

View File

@ -1,32 +0,0 @@
/*
* Redmine plugin for Document Management System "Features"
*
* Copyright (C) 2013 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.
*/
function manipulation_link(action) {
jQuery('#entries_form').attr('action', action);
jQuery('#entries_form').submit();
};
function confirmation_link(action, question) {
if(!window.confirm(question)) {
return;
}
jQuery('#entries_form').attr('action', action);
jQuery('#entries_form').submit();
};

View File

@ -34,13 +34,13 @@ table.entries {
}
table.entries td.modified {
min-width: 104px;
width: 104px;
min-width: 127px;
width: 127px;
}
table.entries td.actions {
min-width: 116px;
width: 116px;
min-width: 96px;
width: 96px;
}
table.entries td.title {
@ -71,42 +71,6 @@ table.display tbody tr.odd {
table.display tbody tr:hover { background-color:#ffffdd; }
.icon-file.filetype-doc, .icon-file.filetype-docx {
background-image: url(../images/filetypes/doc.png);
}
.icon-file.filetype-xls, .icon-file.filetype-xlsx {
background-image: url(../images/filetypes/xls.png);
}
.icon-file.filetype-ppt, .icon-file.filetype-pptx {
background-image: url(../images/filetypes/ppt.png);
}
.icon-file.filetype-vsd, .icon-file.filetype-vsdx {
background-image: url(../images/filetypes/vsd.png);
}
.icon-file.filetype-mpp {
background-image: url(../images/filetypes/mpp.png);
}
.icon-file.filetype-odt {
background-image: url(../images/filetypes/odt.png);
}
.icon-file.filetype-ods {
background-image: url(../images/filetypes/ods.png);
}
.icon-file.filetype-odp {
background-image: url(../images/filetypes/odp.png);
}
.icon-file.filetype-odg {
background-image: url(../images/filetypes/odg.png);
}
form.dmfs_entries {
margin-bottom: 10px;
display: block;
@ -167,10 +131,7 @@ div.right_icon_box {
float: right;
white-space: nowrap;
padding: 0 5px 0 5px;
}
div.right_icon_box img.detail_icon {
padding-top: 2px;
width: 96px;
}
/* DMSF entries upload control */
@ -312,3 +273,83 @@ table.list td.step {
.modal a, .modal a:link, .modal a:visited{ color: #169; text-decoration: none; }
.modal a:hover, .modal a:active{ color: #c61a1a; text-decoration: underline;}
.modal{ font-size: 12px}
/* Command icons */
.icon-margin-left { margin-left: 3px; }
.icon-link { background-image: url(../images/link.png); }
.icon-notification-on { background-image: url(../images/notify.png); margin-left: 3px; }
.icon-notification-off { background-image: url(../images/notifynot.png); margin-left: 3px; }
.icon-dmsf-lock { background-image: url(../images/lock.png); }
.icon-dmsf-unlock { background-image: url(../images/unlock.png); }
.icon-dmsf-locked { background-image: url(../images/locked.png); margin-left: 2px }
.icon-dmsf-lockedbycurrent { background-image: url(../images/lockedbycurrent.png); margin-left: 2px }
.icon-dmsf-waiting-for-approval { background-image: url(../images/waiting_for_approval.png); }
.icon-dmsf-approved { background-image: url(../images/approved.png); }
.icon-dmsf-assigned { background-image: url(../images/assigned.png); }
.icon-dmsf-rejected { background-image: url(../images/rejected.png); }
.icon-dmsf-none { background-image: url(../images/none.png); }
.icon-dmsf-file-details { background-image: url(../images/filedetails.png); }
.icon-dmsf-rev-download { background-image: url(../images/rev_download.png); }
.icon-dmsf-rev-downloads { background-image: url(../images/rev_downloads.png); }
.icon-dmsf-rev-delete { background-image: url(../images/rev_delete.png); }
.icon-edit-gray { background-image: url(../images/edit_gray.png); }
.icon-notification-on-gray { background-image: url(../images/notify_gray.png); }
.icon-notification-off-gray { background-image: url(../images/notifynot_gray.png); }
.icon-dmsf-lock-gray { background-image: url(../images/lock_gray.png); }
.icon-dmsf-unlock-gray { background-image: url(../images/unlock_gray.png); }
.icon-dmsf-waiting-for-approval-gray { background-image: url(../images/waiting_for_approval_gray.png); }
.icon-dmsf-approved-gray { background-image: url(../images/approved_gray.png); }
.icon-dmsf-assigned-gray { background-image: url(../images/assigned_gray.png); }
.icon-dmsf-rejected-gray { background-image: url(../images/rejected_gray.png); }
.icon-dmsf-file-details-gray { background-image: url(../images/filedetails_gray.png); }
tr.gray .icon-dmsf-locked { background-image: url(../images/locked_gray.png); margin-left: 2px }
tr.gray .icon-dmsf-lockedbycurrent { background-image: url(../images/lockedbycurrent_gray.png); margin-left: 2px }
tr.gray .icon-dmsf-locked { background-image: url(../images/locked_gray.png); margin-left: 2px }
tr.gray .icon-dmsf-lockedbycurrent { background-image: url(../images/lockedbycurrent_gray.png); margin-left: 2px }
/* File types */
tr.gray .icon-folder { background-image: url(../images/folder_gray.png); }
.icon-file.filetype-doc, .icon-file.filetype-docx { background-image: url(../images/filetypes/doc.png); }
.icon-file.filetype-xls, .icon-file.filetype-xlsx { background-image: url(../images/filetypes/xls.png); }
.icon-file.filetype-ppt, .icon-file.filetype-pptx { background-image: url(../images/filetypes/ppt.png); }
.icon-file.filetype-vsd, .icon-file.filetype-vsdx { background-image: url(../images/filetypes/vsd.png); }
.icon-file.filetype-mpp { background-image: url(../images/filetypes/mpp.png); }
.icon-file.filetype-odt { background-image: url(../images/filetypes/odt.png); }
.icon-file.filetype-ods { background-image: url(../images/filetypes/ods.png); }
.icon-file.filetype-odp { background-image: url(../images/filetypes/odp.png); }
.icon-file.filetype-odg { background-image: url(../images/filetypes/odg.png); }
tr.gray .icon-file.filetype-doc, .icon-file.filetype-docx { background-image: url(../images/filetypes/doc_gray.png); }
tr.gray .icon-file.filetype-xls, .icon-file.filetype-xlsx { background-image: url(../images/filetypes/xls_gray.png); }
tr.gray .icon-file.filetype-ppt, .icon-file.filetype-pptx { background-image: url(../images/filetypes/ppt_gray.png); }
tr.gray .icon-file.filetype-vsd, .icon-file.filetype-vsdx { background-image: url(../images/filetypes/vsd_gray.png); }
tr.gray .icon-file.filetype-mpp { background-image: url(../images/filetypes/mpp_gray.png); }
tr.gray .icon-file.filetype-odt { background-image: url(../images/filetypes/odt_gray.png); }
tr.gray .icon-file.filetype-ods { background-image: url(../images/filetypes/ods_gray.png); }
tr.gray .icon-file.filetype-odp { background-image: url(../images/filetypes/odp_gray.png); }
tr.gray .icon-file.filetype-odg { background-image: url(../images/filetypes/odg_gray.png); }
tr.gray .icon-file.text-x-c { background-image: url(../images/filetypes/c_gray.png); }
tr.gray .icon-file.text-x-csharp { background-image: url(../images/filetypes/csharp_gray.png); }
tr.gray .icon-file.text-x-java { background-image: url(../images/files/filetypes_gray.png); }
tr.gray .icon-file.text-x-javascript { background-image: url(../images/filetypes/js_gray.png); }
tr.gray .icon-file.text-x-php { background-image: url(../images/filetypes/php_gray.png); }
tr.gray .icon-file.text-x-ruby { background-image: url(../images/filetypes/ruby_gray.png); }
tr.gray .icon-file.text-xml { background-image: url(../images/filetypes/xml_gray.png); }
tr.gray .icon-file.text-css { background-image: url(../images/filetypes/css_gray.png); }
tr.gray .icon-file.text-html { background-image: url(../images/filetypes/html_gray.png); }
tr.gray .icon-file.image-gif { background-image: url(../images/filetypes/image_gray.png); }
tr.gray .icon-file.image-jpeg { background-image: url(../images/filetypes/image_gray.png); }
tr.gray .icon-file.image-png { background-image: url(../images/filetypes/image_gray.png); }
tr.gray .icon-file.image-tiff { background-image: url(../images/filetypes/image_gray.png); }
tr.gray .icon-file.application-pdf { background-image: url(../images/filetypes/pdf_gray.png); }
tr.gray .icon-file.application-zip { background-image: url(../images/filetypes/zip_gray.png); }
tr.gray .icon-file.application-x-gzip { background-image: url(../images/filetypes/zip_gray.png); }
/* Links */
.gray { color: #AAA }
.gray a, .gray a:link, .gray a:visited{ color: #484848; text-decoration: none; }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 260 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 251 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

File diff suppressed because one or more lines are too long

View File

@ -26,10 +26,8 @@ cs:
notice_file_locked: Soubor byl zamčen
warning_file_not_locked: Soubor není zamčen
notice_file_unlocked: Soubor byl odemčen
error_only_user_that_locked_file_can_unlock_it: Soubor může být odemčen pouze uživatelem, který ho zamkl
question_do_you_really_want_to_delete_this_entry: Chcete to skutečně smazat?
error_max_files_exceeded: "Limit pro %{number} najednou stažených souborů je překročen"
question_do_you_really_want_to_delete_this_revision: Chcete skutečně smazat tuto revizi?
error_only_user_that_locked_file_can_unlock_it: Soubor může být odemčen pouze uživatelem, který ho zamkl
error_max_files_exceeded: "Limit pro %{number} najednou stažených souborů je překročen"
error_entry_project_does_not_match_current_project: Zadaný projekt neodpovídá aktuálnímu projektu
notice_folder_created: Adresář byl vytvořen
error_folder_creation_failed: Vytváření složky selhalo
@ -183,8 +181,8 @@ cs:
comment_copied_from: "Zkopírováno z %{source}"
notice_file_copied: Soubor zkopírován
notice_file_moved: Soubor přesunut
label_target_project: Cílový projekt
label_target_folder: Cílový adresář
field_target_project: Cílový projekt
field_target_folder: Cílový adresář
title_copy_or_move: Kopírovat/Přesunout
label_dmsf_folder_plural: Dmsf složky
comment_moved_from: "Přesunuto z %{source}"
@ -276,6 +274,13 @@ cs:
text_email_to_see_history: Pro zobrazení historie schvalovacího procesu klikněte na status dokumentu v
text_email_to_see_status: Pro zobrazení aktuálního stavu schvalovacího procesu klikněte na status dokumentu v
title_create_link: Vytvořit symbolický odkaz
label_create_link: Vytvořit odkaz
label_notifications_on: Zapnout notifikace
label_notifications_off: Vypnout notifikace
field_target_file: Cílový soubor
title_download_entries: Historie stahování
my:
blocks:
locked_documents: Zamčené dokumenty

View File

@ -26,10 +26,8 @@ de:
notice_file_locked: Datei gesperrt
warning_file_not_locked: Datei nicht gesperrt
notice_file_unlocked: Dateisperre gelöst
error_only_user_that_locked_file_can_unlock_it: Nur der Benutzer, der die Datei gesperrt hat, kann sie auch wieder freigeben
question_do_you_really_want_to_delete_this_entry: Willst du diesen Eintrag wirklich löschen?
error_max_files_exceeded: "Grenze für %{number} gleichzeitig heruntergeladene Dateien überschritten"
question_do_you_really_want_to_delete_this_revision: Möchtest du diese Dateiversion wirklich löschen?
error_only_user_that_locked_file_can_unlock_it: Nur der Benutzer, der die Datei gesperrt hat, kann sie auch wieder freigeben
error_max_files_exceeded: "Grenze für %{number} gleichzeitig heruntergeladene Dateien überschritten"
error_entry_project_does_not_match_current_project: Entry Projekt entspricht nicht aktuellen Projekt
notice_folder_created: Ordner erstellt
error_folder_creation_failed: Ordnererstellung fehlgeschlagen
@ -182,8 +180,8 @@ de:
comment_copied_from: "Kopiert aus %{source}"
notice_file_copied: Datei kopiert
notice_file_moved: Datei verschoben
label_target_project: Zielprojekte
label_target_folder: Zielordner
field_target_project: Zielprojekte
field_target_folder: Zielordner
title_copy_or_move: Kopieren/Verschieben
label_dmsf_folder_plural: Ordner
comment_moved_from: "Verschoben aus %{source}"
@ -277,6 +275,13 @@ de:
text_email_to_see_history: To see the approval history click on the workflow status of the document in
text_email_to_see_status: To see the current status of the approval workflow click on the workflow status the document in
title_create_link: Create a symbolic link
label_create_link: Create link
label_notifications_on: Notifications on
label_notifications_off: Notifications off
field_target_file: Target file
title_download_entries: Download entries
my:
blocks:
locked_documents: Locked documents

View File

@ -27,10 +27,8 @@ en:
notice_file_locked: File locked
warning_file_not_locked: File not locked
notice_file_unlocked: File unlocked
error_only_user_that_locked_file_can_unlock_it: Only user that locked file can unlock it
question_do_you_really_want_to_delete_this_entry: Do you really want to delete this entry?
error_max_files_exceeded: "Limit for %{number} simultaneously downloaded files exceeded"
question_do_you_really_want_to_delete_this_revision: Do you really want to delete this revision?
error_only_user_that_locked_file_can_unlock_it: Only user that locked file can unlock it
error_max_files_exceeded: "Limit for %{number} simultaneously downloaded files exceeded"
error_entry_project_does_not_match_current_project: "Entry project doesn't match current project"
notice_folder_created: Folder created
error_folder_creation_failed: Folder creation failed
@ -185,8 +183,8 @@ en:
comment_copied_from: "Copied from %{source}"
notice_file_copied: File copied
notice_file_moved: File moved
label_target_project: Target project
label_target_folder: Target folder
field_target_project: Target project
field_target_folder: Target folder
title_copy_or_move: Copy/Move
label_dmsf_folder_plural: Dmsf folders
comment_moved_from: "Moved from %{source}"
@ -280,6 +278,13 @@ en:
label_my_open_approvals: My open approvals
label_my_locked_documents: My locked documents
title_create_link: Create a symbolic link
label_create_link: Create link
label_notifications_on: Notifications on
label_notifications_off: Notifications off
field_target_file: Target file
title_download_entries: Download entries
my:
blocks:
locked_documents: Locked documents

View File

@ -25,10 +25,8 @@ es:
notice_file_locked: Archivo bloqueado
warning_file_not_locked: Archivo no bloqueado
notice_file_unlocked: Archivo desbloqueado
error_only_user_that_locked_file_can_unlock_it: Solo los usuarios que bloquearon previamente al archivo lo pueden desbloquear
question_do_you_really_want_to_delete_this_entry: ¿Está seguro de borrar el ítem seleccionado?
error_max_files_exceeded: "Se excedio el numero permitido de archivos bajados de manera simultánea:"
question_do_you_really_want_to_delete_this_revision: ¿Está seguro de borrar la revision seleccionada?
error_only_user_that_locked_file_can_unlock_it: Solo los usuarios que bloquearon previamente al archivo lo pueden desbloquear
error_max_files_exceeded: "Se excedio el numero permitido de archivos bajados de manera simultánea:"
error_entry_project_does_not_match_current_project: Las entradas del proyecto no concuerdan con el proyecto seleccionado
notice_folder_created: Carpeta creada satisfactoriamente
error_folder_creation_failed: La creacion de la carpeta ha fallado
@ -184,8 +182,8 @@ es:
comment_copied_from: "Copied from %{source}"
notice_file_copied: File copied
notice_file_moved: File moved
label_target_project: Target project
label_target_folder: Target folder
field_target_project: Target project
field_target_folder: Target folder
title_copy_or_move: Copy/Move
label_dmsf_folder_plural: Dmsf folders
comment_moved_from: "Moved from %{source}"
@ -277,6 +275,13 @@ es:
text_email_to_see_history: To see the approval history click on the workflow status of the document in
text_email_to_see_status: To see the current status of the approval workflow click on the workflow status the document in
title_create_link: Create a symbolic link
label_create_link: Create link
label_notifications_on: Notifications on
label_notifications_off: Notifications off
field_target_file: Target file
title_download_entries: Download entries
my:
blocks:
locked_documents: Locked documents

View File

@ -27,10 +27,8 @@ fr:
notice_file_locked: Fichier verrouillé
warning_file_not_locked: Fichier déverrouillé
notice_file_unlocked: Fichier déverrouillé
error_only_user_that_locked_file_can_unlock_it: "Le fichier ne peut être déverrouillé que par celui qui l'a verrouillé"
question_do_you_really_want_to_delete_this_entry: Etes-vous sûr de vouloir supprimer cet élément ?
error_max_files_exceeded: Le nombre de fichiers pouvant être téléchargés simultanément est dépassé
question_do_you_really_want_to_delete_this_revision: Etes-vous sûr de vouloir supprimer cette révision ?
error_only_user_that_locked_file_can_unlock_it: "Le fichier ne peut être déverrouillé que par celui qui l'a verrouillé"
error_max_files_exceeded: Le nombre de fichiers pouvant être téléchargés simultanément est dépassé
error_entry_project_does_not_match_current_project: "Le projet saisi ne correspond pas au projet courant"
notice_folder_created: Dossier créé
error_folder_creation_failed: Erreur de création du dossier
@ -185,8 +183,8 @@ fr:
comment_copied_from: "Copie effectuée depuis %{source}"
notice_file_copied: Fichier copié
notice_file_moved: Fichier déplacé
label_target_project: Projet cible
label_target_folder: Dossier cible
field_target_project: Projet cible
field_target_folder: Dossier cible
title_copy_or_move: Copie/Déplacement
label_dmsf_folder_plural: Les dossiers de DMSF
comment_moved_from: "Déplacé depuis %{source}"
@ -279,6 +277,13 @@ fr:
text_email_to_see_status: Pour consulter le statut actuel du flux de validation, cliquez sur le statut du flux du document dans
label_my_open_approvals: Mes approbations en attente
label_my_locked_documents: Mes documents verrouillés
title_create_link: Create a symbolic link
label_create_link: Create link
label_notifications_on: Notifications on
label_notifications_off: Notifications off
field_target_file: Target file
title_download_entries: Download entries
my:
blocks:

View File

@ -25,10 +25,8 @@ ja:
notice_file_locked: ファイルをロックしました
warning_file_not_locked: ファイルはロックされていません
notice_file_unlocked: ファイルをロック解除しました
error_only_user_that_locked_file_can_unlock_it: ファイルをロックしたユーザだけがロック解除できます
question_do_you_really_want_to_delete_this_entry: 本当にこのエントリーを削除しますか?
error_max_files_exceeded: "同時にダウンロードできるファイル数の上限 %{number} を超えています"
question_do_you_really_want_to_delete_this_revision: 本当にこのリビジョンを削除しますか?
error_only_user_that_locked_file_can_unlock_it: ファイルをロックしたユーザだけがロック解除できます
error_max_files_exceeded: "同時にダウンロードできるファイル数の上限 %{number} を超えています"
error_entry_project_does_not_match_current_project: 指定したプロジェクトは現在のプロジェクトと一致しません
notice_folder_created: フォルダを作成しました
error_folder_creation_failed: フォルダを作成できません
@ -182,8 +180,8 @@ ja:
comment_copied_from: "%{source} からコピーしました"
notice_file_copied: ファイルをコピーしました
notice_file_moved: ファイルを移動しました
label_target_project: ターゲットプロジェクト
label_target_folder: ターゲットフォルダ
field_target_project: ターゲットプロジェクト
field_target_folder: ターゲットフォルダ
title_copy_or_move: コピー/移動
label_dmsf_folder_plural: Dmsf フォルダ
comment_moved_from: "%{source} から移動しました"
@ -276,6 +274,13 @@ ja:
text_email_to_proceed: To proceed click on the check box icon next to the document in
text_email_to_see_history: To see the approval history click on the workflow status of the document in
text_email_to_see_status: To see the current status of the approval workflow click on the workflow status the document in
title_create_link: Create a symbolic link
label_create_link: Create link
label_notifications_on: Notifications on
label_notifications_off: Notifications off
field_target_file: Target file
title_download_entries: Download entries
my:
blocks:

View File

@ -25,10 +25,8 @@ ru:
notice_file_locked: Файл заблокирован
warning_file_not_locked: Файл не заблокирован
notice_file_unlocked: Файл разблокирован
error_only_user_that_locked_file_can_unlock_it: Только пользователь, который заблокировал файл, может его разблокировать
question_do_you_really_want_to_delete_this_entry: Вы действительно хотите удалить этот файл?
error_max_files_exceeded: "Ограничение для %{number} одновременно загружаемых файлов превышено"
question_do_you_really_want_to_delete_this_revision: Вы действительно хотите удалить эту редакцию?
error_only_user_that_locked_file_can_unlock_it: Только пользователь, который заблокировал файл, может его разблокировать
error_max_files_exceeded: "Ограничение для %{number} одновременно загружаемых файлов превышено"
error_entry_project_does_not_match_current_project: Проект, которому принадлежит файл, не соответсвует текущему проекту
notice_folder_created: Папка создана
error_folder_creation_failed: Папку не удалось создать
@ -182,8 +180,8 @@ ru:
comment_copied_from: "Скопировано из %{source}"
notice_file_copied: Файл скопирован
notice_file_moved: Файл перемещен
label_target_project: Целевой проект
label_target_folder: Целевая папка
field_target_project: Целевой проект
field_target_folder: Целевая папка
title_copy_or_move: Копировать/Переместить
label_dmsf_folder_plural: DMSF папки
comment_moved_from: "Перемещен из %{source}"
@ -276,6 +274,13 @@ ru:
text_email_to_proceed: To proceed click on the check box icon next to the document in
text_email_to_see_history: To see the approval history click on the workflow status of the document in
text_email_to_see_status: To see the current status of the approval workflow click on the workflow status the document in
title_create_link: Create a symbolic link
label_create_link: Create link
label_notifications_on: Notifications on
label_notifications_off: Notifications off
field_target_file: Target file
title_download_entries: Download entries
my:
blocks:

View File

@ -25,10 +25,8 @@ sl:
notice_file_locked: Datoteka zaklenjena
warning_file_not_locked: Datoteka ni zaklenjena
notice_file_unlocked: Datoteka odklenjena
error_only_user_that_locked_file_can_unlock_it: Samo oseba, ki je zaklenila datoteko, jo lahko odklene.
question_do_you_really_want_to_delete_this_entry: Ste prepričani, da želite izbrisati objekt?
error_max_files_exceeded: "Max %{number} datotek za istočasno nalaganje je preseženo."
question_do_you_really_want_to_delete_this_revision: Ste prepričani, da želite izbrisati verzijo datoteke?
error_only_user_that_locked_file_can_unlock_it: Samo oseba, ki je zaklenila datoteko, jo lahko odklene.
error_max_files_exceeded: "Max %{number} datotek za istočasno nalaganje je preseženo."
error_entry_project_does_not_match_current_project: Projekt se ujema s trenutno nastavljenim projektom
notice_folder_created: Mapa kreirana
error_folder_creation_failed: Mape ne morem kreirati
@ -183,8 +181,8 @@ sl:
comment_copied_from: "Skopirano iz %{source}"
notice_file_copied: Datoteka skopirana
notice_file_moved: Datoteka premaknjena
label_target_project: Ciljni projekt
label_target_folder: Ciljna mapa
field_target_project: Ciljni projekt
field_target_folder: Ciljna mapa
title_copy_or_move: "Kopiraj/Premakni"
label_dmsf_folder_plural: Arhivske mape
comment_moved_from: "Premaknjeno iz %{source}"
@ -276,6 +274,13 @@ sl:
text_email_to_proceed: To proceed click on the check box icon next to the document in
text_email_to_see_history: To see the approval history click on the workflow status of the document in
text_email_to_see_status: To see the current status of the approval workflow click on the workflow status the document in
title_create_link: Create a symbolic link
label_create_link: Create link
label_notifications_on: Notifications on
label_notifications_off: Notifications off
field_target_file: Target file
title_download_entries: Download entries
my:
blocks:

View File

@ -25,10 +25,8 @@ zh:
notice_file_locked: 文件锁定
warning_file_not_locked: 文件未锁定
notice_file_unlocked: 文件解锁
error_only_user_that_locked_file_can_unlock_it: 只有锁定文件的用户才能解锁该文件
question_do_you_really_want_to_delete_this_entry: 您确定删除此条目?
error_max_files_exceeded: "超出同时下载%{number}个文件数量限制"
question_do_you_really_want_to_delete_this_revision: 您确定删除此修订版本吗?
error_only_user_that_locked_file_can_unlock_it: 只有锁定文件的用户才能解锁该文件
error_max_files_exceeded: "超出同时下载%{number}个文件数量限制"
error_entry_project_does_not_match_current_project: 入口项目与当前项目不匹配
notice_folder_created: 文件夹创建完毕
error_folder_creation_failed: 文件夹创建失败
@ -185,8 +183,8 @@ zh:
comment_copied_from: "Copied from %{source}"
notice_file_copied: File copied
notice_file_moved: File moved
label_target_project: Target project
label_target_folder: Target folder
field_target_project: Target project
field_target_folder: Target folder
title_copy_or_move: Copy/Move
label_dmsf_folder_plural: Dmsf folders
comment_moved_from: "Moved from %{source}"
@ -277,6 +275,13 @@ zh:
text_email_to_proceed: To proceed click on the check box icon next to the document in
text_email_to_see_history: To see the approval history click on the workflow status of the document in
text_email_to_see_status: To see the current status of the approval workflow click on the workflow status the document in
title_create_link: Create a symbolic link
label_create_link: Create link
label_notifications_on: Notifications on
label_notifications_off: Notifications off
field_target_file: Target file
title_download_entries: Download entries
my:
blocks:

View File

@ -26,20 +26,20 @@ RedmineApp::Application.routes.draw do
# [As this controller also processes 'folders' it maybe better to branch into a folder route rather than leaving it as is]
##
post '/projects/:id/dmsf/create', :controller => 'dmsf', :action => 'create'
post '/projects/:id/dmsf/notify/activate', :controller => 'dmsf', :action => 'notify_activate'
post '/projects/:id/dmsf/notify/deactivate', :controller => 'dmsf', :action => 'notify_deactivate'
post '/projects/:id/dmsf/delete', :controller => 'dmsf', :action => 'delete'
get '/projects/:id/dmsf/notify/activate', :controller => 'dmsf', :action => 'notify_activate', :as => 'notify_activate_dmsf'
get '/projects/:id/dmsf/notify/deactivate', :controller => 'dmsf', :action => 'notify_deactivate', :as => 'notify_deactivate_dmsf'
get '/projects/:id/dmsf/delete', :controller => 'dmsf', :action => 'delete', :as => 'delete_dmsf'
post '/projects/:id/dmsf/save', :controller => 'dmsf', :action => 'save'
post '/projects/:id/dmsf/save/root', :controller => 'dmsf', :action => 'save_root'
post '/projects/:id/dmsf/entries', :controller => 'dmsf', :action => 'entries_operation'
post '/projects/:id/dmsf/entries/delete', :controller => 'dmsf', :action => 'delete_entries'
post '/projects/:id/dmsf/entries/email', :controller => 'dmsf', :action => 'entries_email'
post '/projects/:id/dmsf/lock', :controller => 'dmsf', :action => 'lock'
post '/projects/:id/dmsf/unlock', :controller => 'dmsf', :action => 'unlock'
get '/projects/:id/dmsf/', :controller => 'dmsf', :action => 'show', :as => 'dmsf'
get '/projects/:id/dmsf/new', :controller => 'dmsf', :action => 'new'
get '/projects/:id/dmsf/edit', :controller=> 'dmsf', :action => 'edit'
get '/projects/:id/dmsf/edit/root', :controller=> 'dmsf', :action => 'edit_root'
get '/projects/:id/dmsf/lock', :controller => 'dmsf', :action => 'lock', :as => 'lock_dmsf'
get '/projects/:id/dmsf/unlock', :controller => 'dmsf', :action => 'unlock', :as => 'unlock_dmsf'
get '/projects/:id/dmsf/', :controller => 'dmsf', :action => 'show', :as => 'dmsf_folder'
get '/projects/:id/dmsf/new', :controller => 'dmsf', :action => 'new', :as => 'new_dmsf'
get '/projects/:id/dmsf/edit', :controller=> 'dmsf', :action => 'edit', :as => 'edit_dmsf'
get '/projects/:id/dmsf/edit/root', :controller=> 'dmsf', :action => 'edit_root', :as => 'edit_root_dmsf'
#
# dmsf_state controller
@ -61,21 +61,17 @@ RedmineApp::Application.routes.draw do
# dmsf_files controller
# /dmsf/files/<file id>
##
post '/dmsf/files/:id/notify/activate', :controller => 'dmsf_files', :action => 'notify_activate'
post '/dmsf/files/:id/notify/deactivate', :controller => 'dmsf_files', :action => 'notify_deactivate'
post '/dmsf/files/:id/lock', :controller => 'dmsf_files', :action => 'lock'
post '/dmsf/files/:id/unlock', :controller => 'dmsf_files', :action => 'unlock'
post '/dmsf/files/:id/delete', :controller => 'dmsf_files', :action => 'delete'
get '/dmsf/files/:id/notify/activate', :controller => 'dmsf_files', :action => 'notify_activate', :as => 'notify_activate_dmsf_files'
get '/dmsf/files/:id/notify/deactivate', :controller => 'dmsf_files', :action => 'notify_deactivate', :as => 'notify_deactivate_dmsf_files'
get '/dmsf/files/:id/lock', :controller => 'dmsf_files', :action => 'lock', :as => 'lock_dmsf_files'
get '/dmsf/files/:id/unlock', :controller => 'dmsf_files', :action => 'unlock', :as => 'unlock_dmsf_files'
post '/dmsf/files/:id/delete', :controller => 'dmsf_files', :action => 'delete', :as => 'delete_dmsf_files'
post '/dmsf/files/:id/revision/create', :controller => 'dmsf_files', :action => 'create_revision'
post '/dmsf/files/:id/revision/delete', :controller => 'dmsf_files', :action => 'delete_revision'
get '/dmsf/files/:id/download', :controller => 'dmsf_files', :action => 'show', :download => '' #Otherwise will not route nil download param
get '/dmsf/files/:id/revision/delete', :controller => 'dmsf_files', :action => 'delete_revision', :as => 'delete_revision'
get '/dmsf/files/:id/download', :controller => 'dmsf_files', :action => 'show', :download => '' # Otherwise will not route nil download param
get '/dmsf/files/:id/download/:download', :controller => 'dmsf_files', :action => 'show'
get '/dmsf/files/:id', :controller => 'dmsf_files', :action => 'show'
# Just to keep backward compatibility of external url links
get '/dmsf_files/:id', :controller => 'dmsf_files', :action => 'show'
# Just to keep backward compatibility with old external direct links
get '/dmsf_files/:id', :controller => 'dmsf_files', :action => 'show'
get '/dmsf/files/:id', :controller => 'dmsf_files', :action => 'show', :as => 'dmsf_file'
delete '/dmsf/files/:id', :controller => 'dmsf_files', :action => 'delete'
#
# files_copy controller
@ -83,7 +79,7 @@ RedmineApp::Application.routes.draw do
##
post '/dmsf/files/:id/copy/create', :controller => 'dmsf_files_copy', :action => 'create'
post '/dmsf/files/:id/copy/move', :controller => 'dmsf_files_copy', :action => 'move'
get '/dmsf/files/:id/copy', :controller => 'dmsf_files_copy', :action => 'new'
get '/dmsf/files/:id/copy', :controller => 'dmsf_files_copy', :action => 'new', :as => 'copy_file'
#
# folders_copy controller
@ -91,7 +87,7 @@ RedmineApp::Application.routes.draw do
##
#verify :method => :post, :only => [:copy_to], :render => { :nothing => true, :status => :method_not_allowed }
post '/dmsf/folders/:id/copy/to', :controller => 'dmsf_folders_copy', :action => 'copy_to'
get '/dmsf/folders/:id/copy', :controller => 'dmsf_folders_copy', :action => 'new'
get '/dmsf/folders/:id/copy', :controller => 'dmsf_folders_copy', :action => 'new', :as => 'copy_folder'
#
# DAV4Rack implementation of Webdav [note: if changing path you'll need to update lib/redmine_dmsf/webdav/no_parse.rb also]
@ -110,7 +106,7 @@ RedmineApp::Application.routes.draw do
get 'assign'
get 'log'
post 'new_action'
post 'start'
get 'start'
post 'assignment'
end
end
@ -118,4 +114,11 @@ RedmineApp::Application.routes.draw do
match 'dmsf_workflows/:id/edit', :controller => 'dmsf_workflows', :action => 'add_step', :id => /\d+/, :via => :post
match 'dmsf_workflows/:id/edit', :controller => 'dmsf_workflows', :action => 'remove_step', :id => /\d+/, :via => :delete
match 'dmsf_workflows/:id/edit', :controller => 'dmsf_workflows', :action => 'reorder_steps', :id => /\d+/, :via => :put
# Links
resources :dmsf_links do
member do
end
end
end

View File

@ -0,0 +1,38 @@
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2014 Karel Pičman <karel.picman@lbcfree.net>
#
# 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 CreateDmsfLinks < ActiveRecord::Migration
def change
create_table :dmsf_links do |t|
t.integer :target_project_id, :null => false
t.integer :target_id, :null => false
t.string :target_type, :limit => 10, :null => false
t.string :name, :null => false
t.references :project, :null => false
t.references :dmsf_folder
t.boolean :deleted, :default => false, :null => false
t.integer :deleted_by_user_id
t.timestamps
end
add_index :dmsf_links, :project_id
end
def self.down
drop_table :dmsf_links
end
end

View File

@ -67,7 +67,9 @@ Redmine::Plugin.register :redmine_dmsf do
permission :file_manipulation,
{:dmsf_files => [:create_revision, :delete, :lock, :unlock, :delete_revision, :notify_activate, :notify_deactivate],
:dmsf_upload => [:upload_files, :upload_file, :commit_files],
:dmsf_workflows => [:action, :new_action, :autocomplete_for_user, :start, :assign, :assignment]}
:dmsf_workflows => [:action, :new_action, :autocomplete_for_user, :start, :assign, :assignment],
:dmsf_links => [:new, :create, :destroy]
}
permission :manage_workflows,
{:dmsf_workflows => [:index, :new, :create, :destroy, :edit, :add_step, :remove_step, :reorder_steps, :update]}
permission :force_file_unlock, {}

View File

@ -23,9 +23,7 @@ module RedmineDmsf
class DmsfViewListener < Redmine::Hook::ViewListener
def view_layouts_base_html_head(context={})
tags = "\n".html_safe + javascript_include_tag('redmine_dmsf', :plugin => :redmine_dmsf)
tags << "\n".html_safe + stylesheet_link_tag('dmsf', :plugin => :redmine_dmsf)
tags
"\n".html_safe + stylesheet_link_tag('dmsf', :plugin => :redmine_dmsf)
end
end

View File

@ -31,9 +31,17 @@ module RedmineDmsf
unloadable
alias_method_chain :copy, :dmsf
has_many :dmsf_files, :class_name => 'DmsfFile', :foreign_key => 'project_id', :conditions => { :dmsf_folder_id => nil }, :dependent => :destroy
has_many :dmsf_folders, :class_name => 'DmsfFolder', :foreign_key => 'project_id', :conditions => {:dmsf_folder_id => nil}, :dependent => :destroy
has_many :dmsf_files, :class_name => 'DmsfFile', :foreign_key => 'project_id',
:conditions => { :dmsf_folder_id => nil }, :dependent => :destroy
has_many :dmsf_folders, :class_name => 'DmsfFolder', :foreign_key => 'project_id',
:conditions => {:dmsf_folder_id => nil}, :dependent => :destroy
has_many :dmsf_workflows, :dependent => :destroy
has_many :folder_links, :class_name => 'DmsfLink', :foreign_key => 'project_id',
:conditions => { :dmsf_folder_id => nil, :target_type => DmsfFolder.model_name },
:dependent => :destroy
has_many :file_links, :class_name => 'DmsfLink', :foreign_key => 'project_id',
:conditions => { :dmsf_folder_id => nil, :target_type => DmsfFile.model_name },
:dependent => :destroy
end
end

View File

@ -0,0 +1,8 @@
require File.expand_path('../../test_helper', __FILE__)
class DmsfLinksControllerTest < ActionController::TestCase
# Replace this with your real tests.
def test_truth
assert true
end
end

View File

@ -0,0 +1,27 @@
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2014 Karel Pičman <karel.picman@lbcfree.net>
#
# 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 DmsfLinksTest < ActiveSupport::TestCase
# Replace this with your real tests.
def test_truth
assert true
end
end