#1248 The custom field type is based on revision

This commit is contained in:
Karel Pičman 2023-09-12 08:15:22 +02:00
parent 531d21a14e
commit 7d3865977c
24 changed files with 142 additions and 88 deletions

View File

@ -4,7 +4,7 @@ Changelog for Redmine DMSF
3.1.3 *????-??-??*
------------------
DMS Document as a new custom field type
DMS Document revision as a new custom field type
Copy/Move of multiple entries
REST API
Entries operation (copy, move, download, delete)

View File

@ -39,6 +39,7 @@ Features
* Office documents are displayed inline
* Editing of office documents
* REST API
* DMS Document revision as a custom field type
* Compatible with Redmine 5.0.x
Dependencies

View File

@ -99,7 +99,7 @@
<li>Documents and files symbolic links</li>
<li>Custom fields</li>
<li>Trash bin</li>
<li> Documents preview</li>
<li>Documents preview</li>
</ul>
</div>

View File

@ -266,7 +266,7 @@ cs:
dmsf_new_step: Nový krok
dmsf_new_step_or_approver: Nový krok nebo Nový schvalovatel
message_dmsf_wokflow_note: Váš komentář...
info_revision: "r%{rev}"
info_revision: "r %{rev}"
link_workflow: Schvalovací proces
notice_workflow_started: Schvalovací proces byl úspěšně zahájen
text_email_subject_approved: schválen
@ -475,6 +475,7 @@ cs:
notice_entries_copied: Kopírování se podařilo
notice_entries_moved: Přesun se podařil
label_dmsf_file_revision: DMS Dokument rev.
easy_pages:
modules:

View File

@ -263,7 +263,7 @@ de:
dmsf_new_step: Neuer Schritt
dmsf_new_step_or_approver: Neuer Schritt oder Neuer Genehmiger
message_dmsf_wokflow_note: Ihre Notiz...
info_revision: "r%{rev}"
info_revision: "r %{rev}"
link_workflow: Workflow
notice_workflow_started: Genehmigungs-Workflow gestartet
text_email_subject_approved: genehmigt
@ -350,7 +350,7 @@ de:
note_webdav_ignore: Regulärer Ausdruck (regular expression) mit Dateinamen, die bei PUT-Requests ignoriert werden.
label_document_url: Url
label_last_revision_id: Version
label_last_revision_id: Revision
label_webdav_disable_versioning: Keine Versionen erstellen bei
note_webdav_disable_versioning: Regulärer Ausdruck (regular expression) bei denen die Datei-Versionierung ausgeschaltet wird. Die Standardeinstellung
@ -471,6 +471,7 @@ de:
notice_entries_copied: Kopieren ist gelungen
notice_entries_moved: Verschiebung ist gelungen
label_dmsf_file_revision: DMS Dokument Rev.
easy_pages:
modules:

View File

@ -266,7 +266,7 @@ en:
dmsf_new_step: New step
dmsf_new_step_or_approver: New step or New Approver
message_dmsf_wokflow_note: Your note...
info_revision: "r%{rev}"
info_revision: "r %{rev}"
link_workflow: Workflow
notice_workflow_started: Approval workflow successfully started
text_email_subject_approved: approved
@ -475,6 +475,7 @@ en:
notice_entries_copied: Copying has succeeded
notice_entries_moved: Moving has succeeded
label_dmsf_file_revision: DMS Document rev.
easy_pages:
modules:

View File

@ -266,7 +266,7 @@ es:
dmsf_new_step: Nuevo Paso
dmsf_new_step_or_approver: Nuevo Paso o Nuevo aprobador
message_dmsf_wokflow_note: Tu nota...
info_revision: "r%{rev}"
info_revision: "r %{rev}"
link_workflow: Flujo de Trabajo
notice_workflow_started: "Flujo de trabajo de aprobación iniciado satisfactoriamente"
text_email_subject_approved: aprobado
@ -475,6 +475,7 @@ es:
notice_entries_copied: Copying has succeeded
notice_entries_moved: Moving has succeeded
label_dmsf_file_revision: DMS Document rev.
easy_pages:
modules:

View File

@ -259,7 +259,7 @@ fa:
dmsf_new_step: گام جدید
dmsf_new_step_or_approver: گام یا تایید کننده جدید
message_dmsf_wokflow_note: یادداشت شما ...
info_revision: "r%{rev}"
info_revision: "r %{rev}"
link_workflow: روال تایید
notice_workflow_started: روال تایید با موفقت شروع شد
text_email_subject_approved: تایید شده
@ -454,6 +454,7 @@ fa:
notice_entries_copied: Copying has succeeded
notice_entries_moved: Moving has succeeded
label_dmsf_file_revision: DMS Document rev.
easy_pages:
modules:

View File

@ -266,7 +266,7 @@ fr:
dmsf_new_step: Nouvelle étape
dmsf_new_step_or_approver: Nouvelle étape ou Nouvel approbateur
message_dmsf_wokflow_note: Votre note...
info_revision: "r%{rev}"
info_revision: "r %{rev}"
link_workflow: Flux
notice_workflow_started: Flux de validation démarré avec succès
text_email_subject_approved: approuvé
@ -475,6 +475,7 @@ fr:
notice_entries_copied: Copying has succeeded
notice_entries_moved: Moving has succeeded
label_dmsf_file_revision: DMS Document rev.
easy_pages:
modules:

View File

@ -266,7 +266,7 @@ hu:
dmsf_new_step: Új lépés
dmsf_new_step_or_approver: Új lépés vagy új jóváhagyó
message_dmsf_wokflow_note: Saját jegyzet
info_revision: "r%{rev}"
info_revision: "r %{rev}"
link_workflow: Workflow
notice_workflow_started: Jóváhagyási workflow sikeresen elkezdődött
text_email_subject_approved: elfogadott
@ -474,6 +474,7 @@ hu:
notice_entries_copied: Copying has succeeded
notice_entries_moved: Moving has succeeded
label_dmsf_file_revision: DMS Document rev.
easy_pages:
modules:

View File

@ -266,7 +266,7 @@ it: # Italian strings thx 2 Matteo Arceci!
dmsf_new_step: Nuovo passo
dmsf_new_step_or_approver: Nuovo passo oppure Nuovo approver
message_dmsf_wokflow_note: La tua nota...
info_revision: "r%{rev}"
info_revision: "r %{rev}"
link_workflow: Flusso di lavoro
notice_workflow_started: Approvazione di flusso di lavoro inizializzato
text_email_subject_approved: "Approvazione di flusso di lavoro %{name} approvato"
@ -475,6 +475,7 @@ it: # Italian strings thx 2 Matteo Arceci!
notice_entries_copied: Copying has succeeded
notice_entries_moved: Moving has succeeded
label_dmsf_file_revision: DMS Document rev.
easy_pages:
modules:

View File

@ -266,7 +266,7 @@ ja:
dmsf_new_step: 新規ステップ
dmsf_new_step_or_approver: 新規ステップまたは新規承認者
message_dmsf_wokflow_note: コメント
info_revision: "r%{rev}"
info_revision: "r %{rev}"
link_workflow: ワークフロー
notice_workflow_started: 承認ワークフローが開始されました
text_email_subject_approved: は承認されました
@ -476,6 +476,7 @@ ja:
notice_entries_copied: Copying has succeeded
notice_entries_moved: Moving has succeeded
label_dmsf_file_revision: DMS Document rev.
easy_pages:
modules:

View File

@ -266,7 +266,7 @@ ko:
dmsf_new_step: 새로운 단계
dmsf_new_step_or_approver: 새로운 단계 혹은 새로운 승인자
message_dmsf_wokflow_note: 사용자의 노트...
info_revision: "r%{rev}"
info_revision: "r %{rev}"
link_workflow: 작업 흐름
notice_workflow_started: 승인된 작업 흐름이 성공적으로 시작되었습니다
text_email_subject_approved: 승인됨
@ -475,6 +475,7 @@ ko:
notice_entries_copied: Copying has succeeded
notice_entries_moved: Moving has succeeded
label_dmsf_file_revision: DMS Document rev.
easy_pages:
modules:

View File

@ -266,7 +266,7 @@ nl:
dmsf_new_step: Nieuwe stap
dmsf_new_step_or_approver: Nieuw stap of Nieuwe goedkeurder
message_dmsf_wokflow_note: Uw notitie...
info_revision: "r%{rev}"
info_revision: "r %{rev}"
link_workflow: Workflow
notice_workflow_started: Goedkeuring workflow succesvol gestart
text_email_subject_approved: goedgekeurd
@ -475,6 +475,7 @@ nl:
notice_entries_copied: Copying has succeeded
notice_entries_moved: Moving has succeeded
label_dmsf_file_revision: DMS Document rev.
easy_pages:
modules:

View File

@ -265,7 +265,7 @@ pl:
dmsf_new_step: Nowy krok
dmsf_new_step_or_approver: Nowy krok lub Nowy akceptować
message_dmsf_wokflow_note: Twoja notatka...
info_revision: "r%{rev}"
info_revision: "r %{rev}"
link_workflow: Proces akceptacji
notice_workflow_started: Proces akceptacji został uruchomiony
text_email_subject_approved: został zakończony akceptacją
@ -474,6 +474,7 @@ pl:
notice_entries_copied: Copying has succeeded
notice_entries_moved: Moving has succeeded
label_dmsf_file_revision: DMS Document rev.
easy_pages:
modules:

View File

@ -266,7 +266,7 @@ pt-BR:
dmsf_new_step: Novo passo
dmsf_new_step_or_approver: Novo passo ou Novo aprovador
message_dmsf_wokflow_note: Sua observação...
info_revision: "r%{rev}"
info_revision: "r %{rev}"
link_workflow: Workflow
notice_workflow_started: Workflow de aprovação foi iniciado com êxito
text_email_subject_approved: aprovado
@ -475,6 +475,7 @@ pt-BR:
notice_entries_copied: Copying has succeeded
notice_entries_moved: Moving has succeeded
label_dmsf_file_revision: DMS Document rev.
easy_pages:
modules:

View File

@ -266,7 +266,7 @@ sl:
dmsf_new_step: New step
dmsf_new_step_or_approver: New step or New approver
message_dmsf_wokflow_note: Your note...
info_revision: "r%{rev}"
info_revision: "r %{rev}"
link_workflow: Workflow
notice_workflow_started: Approval workflow successfully started
text_email_subject_approved: approved
@ -475,6 +475,7 @@ sl:
notice_entries_copied: Copying has succeeded
notice_entries_moved: Moving has succeeded
label_dmsf_file_revision: DMS Document rev.
easy_pages:
modules:

View File

@ -267,7 +267,7 @@ uk:
dmsf_new_step: Новий крок
dmsf_new_step_or_approver: Новий крок або Новий затверджувач
message_dmsf_wokflow_note: Ваша примітка...
info_revision: "r%{rev}"
info_revision: "r %{rev}"
link_workflow: Робочий процес
notice_workflow_started: Підтвердження робочого процесу почалося усішно
text_email_subject_approved: підтверджено
@ -477,6 +477,7 @@ uk:
notice_entries_copied: Copying has succeeded
notice_entries_moved: Moving has succeeded
label_dmsf_file_revision: DMS Document rev.
easy_pages:
modules:

View File

@ -265,7 +265,7 @@ zh-TW:
dmsf_new_step: New step
dmsf_new_step_or_approver: New step or New approver
message_dmsf_wokflow_note: Your note...
info_revision: "r%{rev}"
info_revision: "r %{rev}"
link_workflow: Workflow
notice_workflow_started: Approval workflow successfully started
text_email_subject_approved: approved
@ -474,6 +474,7 @@ zh-TW:
notice_entries_copied: Copying has succeeded
notice_entries_moved: Moving has succeeded
label_dmsf_file_revision: DMS Document rev.
easy_pages:
modules:

View File

@ -266,7 +266,7 @@ zh:
dmsf_new_step: New step
dmsf_new_step_or_approver: New step or New approver
message_dmsf_wokflow_note: Your note...
info_revision: "r%{rev}"
info_revision: "r %{rev}"
link_workflow: Workflow
notice_workflow_started: Approval workflow successfully started
text_email_subject_approved: approved
@ -475,6 +475,7 @@ zh:
notice_entries_copied: Copying has succeeded
notice_entries_moved: Moving has succeeded
label_dmsf_file_revision: DMS Document rev.
easy_pages:
modules:

View File

@ -95,4 +95,4 @@ require "#{File.dirname(__FILE__)}/redmine_dmsf/hooks/helpers/project_helper_hoo
require "#{File.dirname(__FILE__)}/redmine_dmsf/macros"
# Field formats
require "#{File.dirname(__FILE__)}/redmine_dmsf/field_formats/dmsf_file_format"
require "#{File.dirname(__FILE__)}/redmine_dmsf/field_formats/dmsf_file_revision_format"

View File

@ -1,64 +0,0 @@
# frozen_string_literal: true
# Redmine plugin for Document Management System "Features"
#
# Copyright © 2011 Vít Jonáš <vit.jonas@gmail.com>
# Copyright © 2011-23 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.
module RedmineDmsf
module FieldFormats
# Custom field type DmsfFile
class DmsfFileFormat < Redmine::FieldFormat::RecordList
add 'dmsf_file'
self.customized_class_names = nil
self.multiple_supported = false
self.bulk_edit_supported = false
def possible_values_options(_custom_field, object = nil)
options = []
if object&.project
files = object.project.dmsf_files.visible.to_a
object.project.dmsf_folders.visible.each do |f|
files += f.dmsf_files.visible.to_a
end
files.sort! { |a, b| a.title.casecmp(b.title) }
options = files.map { |f| [f.name, f.id.to_s] }
end
options
end
def formatted_value(view, _custom_field, value, _customized = nil, _html = false)
return '' if value.blank?
dmsf_file = DmsfFile.find_by(id: value)
return '' unless dmsf_file
file_view_url = view.url_for({ controller: :dmsf_files, action: 'view', id: dmsf_file })
view.link_to(
h(dmsf_file.title),
file_view_url,
target: '_blank',
rel: 'noopener',
class: "icon icon-file #{DmsfHelper.filetype_css(dmsf_file.name)}",
title: h(dmsf_file.last_revision.try(:tooltip)),
'data-downloadurl' => "#{dmsf_file.last_revision.detect_content_type}:#{h(dmsf_file.name)}:#{file_view_url}"
)
end
end
end
end

View File

@ -0,0 +1,100 @@
# frozen_string_literal: true
# Redmine plugin for Document Management System "Features"
#
# Copyright © 2011 Vít Jonáš <vit.jonas@gmail.com>
# Copyright © 2011-23 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.
module RedmineDmsf
module FieldFormats
# Custom field type DmsfFileRevision
class DmsfFileRevisionFormat < Redmine::FieldFormat::Unbounded
add 'dmsf_file_revision'
self.customized_class_names = nil
self.multiple_supported = false
self.bulk_edit_supported = false
def edit_tag(view, tag_id, tag_name, custom_value, options={})
member = Member.find_by(user_id: User.current.id, project_id: custom_value.customized.project.id)
if member.dmsf_fast_links?
view.text_field_tag(tag_name, custom_value.value, options.merge(:id => tag_id))
else
select_edit_tag(view, tag_id, tag_name, custom_value, options)
end
end
def select_edit_tag(view, tag_id, tag_name, custom_value, options={})
blank_option = ''.html_safe
if custom_value.custom_field.is_required?
unless custom_value.custom_field.default_value.present?
blank_option =
view.content_tag(
'option',
"--- #{l(:actionview_instancetag_blank_option)} ---",
:value => ''
)
end
else
blank_option = view.content_tag('option', '&nbsp;'.html_safe, value: '')
end
options_tags =
blank_option + view.options_for_select(possible_custom_value_options(custom_value), custom_value.value)
view.select_tag(tag_name,
options_tags,
options.merge(id: tag_id, multiple: custom_value.custom_field.multiple?))
end
def possible_values_options(_custom_field, object = nil)
options = []
if object&.project
files = object.project.dmsf_files.visible.to_a
DmsfFolder.visible(false).where(project_id: object.project.id).each do |f|
files += f.dmsf_files.visible.to_a
end
files.sort! { |a, b| a.title.casecmp(b.title) }
options = files.map { |f| [f.name, f.last_revision.id.to_s] }
end
options
end
def formatted_value(view, _custom_field, value, _customized = nil, _html = false)
return '' if value.blank?
revision = DmsfFileRevision.find_by(id: value)
unless revision &&
User.current.allowed_to?(:view_dmsf_files, revision.dmsf_file.project) &&
(revision.dmsf_file.dmsf_folder.nil? || revision.dmsf_file.dmsf_folder.visible?)
return ''
end
member = Member.find_by(user_id: User.current.id, project_id: revision.dmsf_file.project.id)
filename = revision.formatted_name(member)
file_view_url = view.static_dmsf_file_path(revision.dmsf_file, download: revision, filename: filename)
view.link_to(
h(filename),
file_view_url,
target: '_blank',
rel: 'noopener',
class: "icon icon-file #{DmsfHelper.filetype_css(revision.dmsf_file.name)}",
title: h(revision.try(:tooltip)),
'data-downloadurl' => "#{revision.detect_content_type}:#{h(revision.dmsf_file.name)}:#{file_view_url}"
)
end
end
end
end

View File

@ -25,14 +25,14 @@ class CustomFieldDmsfFileFormatTest < RedmineDmsf::Test::UnitTest
fixtures :custom_fields, :projects, :issues, :trackers
def setup
super
User.current = nil
User.current = @jsmith
@issue = Issue.find 1
@field = IssueCustomField.create!(name: 'DMS Document', field_format: 'dmsf_file')
@field = IssueCustomField.create!(name: 'DMS Document rev.', field_format: 'dmsf_file_revision')
end
def test_possible_values_options
n = @issue.project.dmsf_files.visible.all.size
@issue.project.dmsf_folders.visible.each do |f|
DmsfFolder.visible(false).where(project_id: @issue.project.id).each do |f|
n += f.dmsf_files.visible.all.size
end
assert_equal n, @field.possible_values_options(@issue).size