From 53112b2917e6bd83cd2befae36909e7d3b22b7ce Mon Sep 17 00:00:00 2001
From: Karel Picman
Date: Tue, 19 Dec 2017 14:52:53 +0100
Subject: [PATCH 1/6] alias_method_chain is deprecated
---
init.rb | 7 +++---
.../projects_helper_patch.rb | 22 +++++++------------
2 files changed, 11 insertions(+), 18 deletions(-)
diff --git a/init.rb b/init.rb
index 8248f92..ceefa2f 100644
--- a/init.rb
+++ b/init.rb
@@ -15,13 +15,12 @@ end
require 'redmine_custom_workflows/hooks'
+require File.dirname(__FILE__) + '/lib/redmine_custom_workflows/projects_helper_patch'
+
Rails.application.config.to_prepare do
unless Project.include?(RedmineCustomWorkflows::ProjectPatch)
Project.send(:include, RedmineCustomWorkflows::ProjectPatch)
end
- unless ProjectsHelper.include?(RedmineCustomWorkflows::ProjectsHelperPatch)
- ProjectsHelper.send(:include, RedmineCustomWorkflows::ProjectsHelperPatch)
- end
unless Attachment.include?(RedmineCustomWorkflows::AttachmentPatch)
Attachment.send(:include, RedmineCustomWorkflows::AttachmentPatch)
end
@@ -52,4 +51,4 @@ Rails.application.config.to_prepare do
unless ActionView::Base.include?(RedmineCustomWorkflows::Helper)
ActionView::Base.send(:include, RedmineCustomWorkflows::Helper)
end
-end
\ No newline at end of file
+end
diff --git a/lib/redmine_custom_workflows/projects_helper_patch.rb b/lib/redmine_custom_workflows/projects_helper_patch.rb
index 458e54f..af8f4b6 100644
--- a/lib/redmine_custom_workflows/projects_helper_patch.rb
+++ b/lib/redmine_custom_workflows/projects_helper_patch.rb
@@ -1,20 +1,14 @@
module RedmineCustomWorkflows
module ProjectsHelperPatch
- def self.included(base)
- base.send(:include, InstanceMethods)
- base.class_eval do
- alias_method_chain :project_settings_tabs, :custom_workflows
- end
+ def project_settings_tabs
+ tabs = super
+ tabs << {:name => 'custom_workflows', :action => :manage_project_workflow, :partial => 'projects/settings/custom_workflow',
+ :label => :label_custom_workflow_plural} if User.current.allowed_to?(:manage_project_workflow, @project)
+ tabs
end
- module InstanceMethods
- def project_settings_tabs_with_custom_workflows
- tabs = project_settings_tabs_without_custom_workflows
- tabs << {:name => 'custom_workflows', :action => :manage_project_workflow, :partial => 'projects/settings/custom_workflow',
- :label => :label_custom_workflow_plural} if User.current.allowed_to?(:manage_project_workflow, @project)
- tabs
- end
- end
end
-end
\ No newline at end of file
+end
+
+ProjectsHelper.send(:prepend, RedmineCustomWorkflows::ProjectsHelperPatch)
From ce493be7712e7fe046733d5865509f6e166acb7d Mon Sep 17 00:00:00 2001
From: Karel Picman
Date: Tue, 19 Dec 2017 15:07:46 +0100
Subject: [PATCH 2/6] #88 admin menu
---
init.rb | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/init.rb b/init.rb
index ceefa2f..88f186b 100644
--- a/init.rb
+++ b/init.rb
@@ -8,7 +8,8 @@ Redmine::Plugin.register :redmine_custom_workflows do
url 'http://www.redmine.org/plugins/custom-workflows'
menu :admin_menu, :custom_workflows, {:controller => 'custom_workflows', :action => 'index'},
- :if => Proc.new { User.current.admin? }, :caption => :label_custom_workflow_plural
+ :if => Proc.new { User.current.admin? }, :caption => :label_custom_workflow_plural,
+ :html => {:class => 'icon icon-workflows'}
permission :manage_project_workflow, {}, :require => :member
end
From e5daba9fe7ffe50f2039a7a24d45a5d7f6896a0d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karel=20Pi=C4=8Dman?=
Date: Fri, 12 Oct 2018 07:56:21 +0200
Subject: [PATCH 3/6] Wrong file name for Brasilian localisation
---
config/locales/{pt-br.yml => pt-BR.yml} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename config/locales/{pt-br.yml => pt-BR.yml} (100%)
diff --git a/config/locales/pt-br.yml b/config/locales/pt-BR.yml
similarity index 100%
rename from config/locales/pt-br.yml
rename to config/locales/pt-BR.yml
From 7aadd331ca70accb924234fe8f1f537648666b5a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karel=20Pi=C4=8Dman?=
Date: Wed, 19 Dec 2018 13:36:47 +0100
Subject: [PATCH 4/6] Czech localisation
---
config/locales/cs.yml | 104 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 104 insertions(+)
create mode 100644 config/locales/cs.yml
diff --git a/config/locales/cs.yml b/config/locales/cs.yml
new file mode 100644
index 0000000..d6e3ad4
--- /dev/null
+++ b/config/locales/cs.yml
@@ -0,0 +1,104 @@
+cs:
+ project_module_custom_workflows_module: Uživatelské procesy
+ permission_manage_project_workflow: Spravovat uživatelské procesy
+
+ label_custom_workflow: Uživatelský proces
+ label_custom_workflow_plural: Uživatelské procesy
+ label_custom_workflow_new: Vytvořit uživatelský proces
+ label_workflow_scripts: Skript procesu
+ label_enabled_projects: Povoleno pro projekt(y)
+ label_custom_workflow_export: Export
+ label_custom_workflow_import: Importovat proces
+ label_save_workflows: Uložení sledovaných objektů
+ label_destroy_workflows: Smazání sledovaných objektů
+ label_add_workflows: Přidání sledovaných objektů do sezanmu
+ label_remove_workflows: Odstranění sledovaných objektů za seznamu
+
+ button_import: Import
+ button_custom_workflow_activate: Aktivovat
+ button_custom_workflow_deactivate: Deaktivovat
+
+ field_after_save: Skript spuštěný po uložení sledovaného objektu
+ field_before_save: Skript spuštěný před uložením sledovaného objektu
+ field_after_destroy: Skript spuštěný po smazání sledovaného objektu
+ field_before_destroy: Skript spuštěný před smazáním sledovaného objektu
+ field_after_add: Skript spuštěný po přidání sledovaného objektu do seznamu
+ field_before_add: Skript spuštěný před přidáním sledovaného objektu do seznamu
+ field_after_remove: Skript spuštěný po odstranění sledovaného objektu ze seznamu
+ field_before_remove: Skript spuštěný před odstraněním sledovaného objektu ze seznamu
+ field_shared_code: Sdílený kód
+ field_observable: Sledovaný objekt
+ field_is_enabled: Povoleno
+ field_enabled_for_all_projects: Povoleno pro všechny projekty
+ field_custom_workflow_author: Autorův e-mail
+ field_custom_workflow_file: Select the XML file previously exported process
+ field_custom_workflow_active: Aktivní
+ field_custom_workflow:
+ script: Skript
+
+ notice_successful_import: Uživatelský proces byl úspěšně naimportován
+ notice_successful_status_change: Status byl úspěšně změněn
+ error_failed_import: Chyba při importu uživatelského procesu (Neznámý formát? Podívejte se do logu.)
+
+ activerecord:
+ errors:
+ messages:
+ invalid_script: "obsahuje chyby: %{error}"
+ custom_workflow_error: Chyba uživatelského procesu (kontaktujte administrátora)
+ new_status_invalid: "změna z '%{old_status}' na '%{new_status}' není povolena"
+ scripts_absent: Musí být definován alespoň jeden skript
+
+ text_select_project_custom_workflows: Vyberte uživatelský skript projektu
+ text_custom_workflow_before_save_note: "Zde můžete měnit vlastnosti úkolu. Ve skriptu nevytvářejte ani neměňte
+ související úkoly. Pro ukončení skriptu chybou použijte: `raise WorkflowError, 'Zpráva uživateli'`."
+ text_custom_workflow_after_save_note: Zde můžete aktualizovat nebo vytvářet souvissející úkoly. Mějte na paměti, že
+ tento skript bude také vykonán pro nově vytvořené úkoly. Takže nezapomeňte udělat vhodné kontroly pro zabránění
+ rekurzivnímu volání.
+ text_custom_workflow_issue_code_note: Skripty jsou vykonávány v rámci objektu úkolu stejně jako volání `before_save`
+ a `after_save` funkcí. Takže lze použít přímo vlastností úkolů. Proměnné (@variable) jsou rovněž dostupné a lze jich
+ použít.
+ text_custom_workflow_shared_code_note: Tento kód bude spuštěn pře jakýmkoli jiným procesem a může obsahovat sdílený
+ kód, např. funkce a třídy, které jsou potřeba v jiných procesech
+ text_custom_workflow_user_code_note: Skripty jsou vykonávány v rámci objektu uživatel, když se objekt mění (maže).
+ Můžete přímo použít metody a vlastnosti objektu.
+ text_custom_workflow_group_code_note: Skripty jsou vykonávány v rámci objektu skupina, když se objekt mění (maže).
+ Můžete přímo použít metody a vlastnosti objektu.
+ text_custom_workflow_group_users_code_note: Tyto skripty jsou vykonávány, když je uživatel přidán nebo odebrán ze
+ skupiny. Pro přístup k objektům použijte proměnné @user a @group.
+ text_custom_workflow_attachment_code_note: Skripty jsou vykonávány v rámci objektu příloha, když se tento objekt mění
+ (maže se). Můžete přímo použít metody a vlastnosti objektu. Mějte na paměti, že se to týká všech typů příloh
+ (u úkolů, dokumentů, wiki stránek atd.), takže byste měli zkontrolovat proměnnou 'container_type' pro určení,
+ o jakou přílohu se jedná.
+ text_custom_workflow_issue_attachments_code_note: Tento skripty se vykonávají když je příloha přidána nebo odebrába
+ z úkolu. Můžete použít proměnné @issue a @attachment pro přístup k těmto objektům ve skriptu.
+ text_custom_workflow_project_code_note: SSkripty jsou vykonávány v rámci objektu projekt, když se objekt mění (maže).
+ Můžete přímo použít metody a vlastnosti objektu.
+ text_custom_workflow_project_attachments_code_note: Tyto skripty jsou vykonávány, když se přidává nebo se maže soubor
+ u projektu. Můžete použít proměnné @project a @attachment pro přístup k těmto objektům ve skriptu.
+ text_custom_workflow_wiki_content_code_note: Tyto kripty jsou vykonávány v rámci objektu Wiki, když se mění nebo se
+ maže. Můžete přímo použít metody a vlastnosti objektu.
+ text_custom_workflow_wiki_page_attachments_code_note: Tyto skripty jsou vykonávány, když se přidává nebo se maže
+ příloha u wiki stránky. Můžete použít proměnné @page a @attachment pro přístup k těmto objektům ve skriptu.
+ text_custom_workflow_time_entry_code_note: Skripty jsou vykonávány v rámci objektu časový záznam, kdyže se mění nebo
+ se maže. Můžete přímo použít metody a vlastnosti objektu.
+ text_custom_workflow_version_code_note: Skripty jsou vykonávány v rámci objektu verze, když se mění nebo se maže.
+ Můžete přímo použít metody a vlastnosti objektu.
+
+ text_no_enabled_projects: Žádné projekty
+ text_custom_workflow_author: Bude zahrnuto do exportovaného XML
+ text_custom_workflow_disabled: zakázáno administrátorem
+ text_custom_workflow_is_for_all: povoleno pro všechny projekty
+
+ custom_workflow_observable_shared:
+ custom_workflow_observable_issue: Úkol
+ custom_workflow_observable_issue_attachments: Přílohy úkolů
+ custom_workflow_observable_group: Skupina
+ custom_workflow_observable_user: Uživatel
+ custom_workflow_observable_attachment: Příloha
+ custom_workflow_observable_project: Projekt
+ custom_workflow_observable_project_attachments: Soubory
+ custom_workflow_observable_wiki_content: Wiki
+ custom_workflow_observable_wiki_page_attachments: Přílohy na wiki
+ custom_workflow_observable_group_users: Uživatelé skupin
+ custom_workflow_observable_time_entry: Časový záznam
+ custom_workflow_observable_version: Verze
From 3f11d9eec5e1f6f6cdf30795a5445f2a16bf0d81 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karel=20Pi=C4=8Dman?=
Date: Wed, 19 Dec 2018 13:37:12 +0100
Subject: [PATCH 5/6] Compatibility with Redmine 4
---
Gemfile | 4 +
.../custom_workflows_controller.rb | 68 +++++++++--
app/models/custom_workflow.rb | 2 +-
app/views/custom_workflows/_form.html.erb | 108 +++++++++---------
app/views/custom_workflows/index.html.erb | 10 +-
app/views/layouts/_collapsible.html.erb | 6 -
.../settings/_custom_workflow.html.erb | 2 +-
assets/javascripts/tab_override.js | 9 +-
config/routes.rb | 1 +
.../20110915084858_create_custom_workflows.rb | 7 +-
.../20120601054047_alter_custom_workflows.rb | 4 +-
...054557_create_custom_workflows_projects.rb | 7 +-
...hange_custom_workflows_description_type.rb | 4 +-
...5222_add_after_save_to_custom_workflows.rb | 2 +-
...5252_add_is_for_all_to_custom_workflows.rb | 7 +-
...ake_after_save_and_before_save_nullable.rb | 4 +-
...50522134437_set_position_field_nullable.rb | 4 +-
...thor_and_timestamps_to_custom_workflows.rb | 2 +-
.../20150526132244_create_example_workflow.rb | 2 +-
...40_add_active_field_to_custom_workflows.rb | 2 +-
...dd_observable_field_to_custom_workflows.rb | 2 +-
...ional_script_fields_to_custom_workflows.rb | 2 +-
...e_and_after_destroy_to_custom_workflows.rb | 2 +-
init.rb | 2 +
lib/redmine_custom_workflows/mailer_patch.rb | 2 +-
25 files changed, 155 insertions(+), 110 deletions(-)
create mode 100644 Gemfile
delete mode 100644 app/views/layouts/_collapsible.html.erb
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..13946ec
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,4 @@
+source 'https://rubygems.org'
+
+gem 'acts_as_list'
+gem 'activemodel-serializers-xml'
\ No newline at end of file
diff --git a/app/controllers/custom_workflows_controller.rb b/app/controllers/custom_workflows_controller.rb
index 592f56a..e17bd6d 100644
--- a/app/controllers/custom_workflows_controller.rb
+++ b/app/controllers/custom_workflows_controller.rb
@@ -1,8 +1,32 @@
class CustomWorkflowsController < ApplicationController
layout 'admin'
- before_filter :require_admin
- before_filter :find_workflow, :only => [:show, :edit, :update, :destroy, :export, :change_status]
+ before_action :require_admin
+ before_action :find_workflow, only: [:show, :edit, :update, :destroy, :export, :change_status, :reorder]
+
+ def reorder
+ from = @workflow.position
+ to = params[:custom_workflow][:position].to_i
+ CustomWorkflow.transaction do
+ CustomWorkflow.find_each do |wf|
+ if wf.position == from
+ wf.update_attribute :position, to
+ elsif wf.position >= to && wf.position < from
+ # Move up
+ wf.update_attribute :position, wf.position + 1
+ elsif wf.position <= to && wf.position > from
+ # Move down
+ wf.update_attribute :position, wf.position - 1
+ end
+ end
+ end
+ respond_to do |format|
+ format.html
+ format.js {
+ render inline: "location.replace('#{custom_workflows_path}');"
+ }
+ end
+ end
def index
@workflows = CustomWorkflow.includes(:projects).all
@@ -52,14 +76,30 @@ class CustomWorkflowsController < ApplicationController
end
def create
- @workflow = CustomWorkflow.new(params[:custom_workflow])
+ @workflow = CustomWorkflow.new
+ @workflow.before_save = params[:custom_workflow][:before_save]
+ @workflow.after_save = params[:custom_workflow][:after_save]
+ @workflow.name = params[:custom_workflow][:name]
+ @workflow.description = params[:custom_workflow][:description]
+ @workflow.position = CustomWorkflow.count + 1
+ @workflow.is_for_all = params[:custom_workflow][:is_for_all].present?
+ @workflow.author = params[:custom_workflow][:author]
+ @workflow.active = params[:custom_workflow][:active]
+ @workflow.observable = params[:custom_workflow][:observable]
+ @workflow.shared_code = params[:custom_workflow][:shared_code]
+ @workflow.before_add = params[:custom_workflow][:before_add]
+ @workflow.after_add = params[:custom_workflow][:after_add]
+ @workflow.before_remove = params[:custom_workflow][:before_remove]
+ @workflow.after_remove = params[:custom_workflow][:after_remove]
+ @workflow.before_destroy = params[:custom_workflow][:before_destroy]
+ @workflow.after_destroy = params[:custom_workflow][:after_destroy]
respond_to do |format|
if params.has_key?(:commit) && @workflow.save
flash[:notice] = l(:notice_successful_create)
cookies[:custom_workflows_author] = @workflow.author
format.html { redirect_to(custom_workflows_path) }
else
- format.html { render :action => "new" }
+ format.html { render action: :new }
end
end
end
@@ -70,26 +110,38 @@ class CustomWorkflowsController < ApplicationController
flash[:notice] = l(:notice_successful_status_change)
format.html { redirect_to(custom_workflows_path) }
else
- format.html { render :action => :edit }
+ format.html { render action: :edit }
end
end
end
def update
respond_to do |format|
- @workflow.assign_attributes(params[:custom_workflow])
+ @workflow.before_save = params[:custom_workflow][:before_save]
+ @workflow.after_save = params[:custom_workflow][:after_save]
+ @workflow.name = params[:custom_workflow][:name]
+ @workflow.description = params[:custom_workflow][:description]
+ @workflow.is_for_all = params[:custom_workflow][:is_for_all].present?
+ @workflow.author = params[:custom_workflow][:author]
+ @workflow.active = params[:custom_workflow][:active]
+ @workflow.shared_code = params[:custom_workflow][:shared_code]
+ @workflow.before_add = params[:custom_workflow][:before_add]
+ @workflow.after_add = params[:custom_workflow][:after_add]
+ @workflow.before_remove = params[:custom_workflow][:before_remove]
+ @workflow.after_remove = params[:custom_workflow][:after_remove]
+ @workflow.before_destroy = params[:custom_workflow][:before_destroy]
+ @workflow.after_destroy = params[:custom_workflow][:after_destroy]
if params.has_key?(:commit) && @workflow.save
flash[:notice] = l(:notice_successful_update)
format.html { redirect_to(custom_workflows_path) }
else
- format.html { render :action => :edit }
+ format.html { render action: :edit }
end
end
end
def destroy
@workflow.destroy
-
respond_to do |format|
flash[:notice] = l(:notice_successful_delete)
format.html { redirect_to(custom_workflows_path) }
diff --git a/app/models/custom_workflow.rb b/app/models/custom_workflow.rb
index 52c1586..45383a1 100644
--- a/app/models/custom_workflow.rb
+++ b/app/models/custom_workflow.rb
@@ -14,7 +14,6 @@ class CustomWorkflow < ActiveRecord::Base
COLLECTION_OBSERVABLES = [:group_users, :issue_attachments, :project_attachments, :wiki_page_attachments]
SINGLE_OBSERVABLES = [:issue, :user, :group, :attachment, :project, :wiki_content, :time_entry, :version]
- attr_protected :id
has_and_belongs_to_many :projects
acts_as_list
@@ -105,6 +104,7 @@ class CustomWorkflow < ActiveRecord::Base
def validate_syntax_for(object, event)
object.instance_eval(read_attribute(event)) if respond_to?(event) && read_attribute(event)
rescue WorkflowError => e
+ errors.add event, :invalid_script, :error => e
rescue Exception => e
errors.add event, :invalid_script, :error => e
end
diff --git a/app/views/custom_workflows/_form.html.erb b/app/views/custom_workflows/_form.html.erb
index 6c8b84a..3ee7cfe 100644
--- a/app/views/custom_workflows/_form.html.erb
+++ b/app/views/custom_workflows/_form.html.erb
@@ -9,7 +9,7 @@
CustomWorkflow::OBSERVABLES.collect {|o| [l("custom_workflow_observable_#{o}"), o]}, {},
:onchange => 'this.form.submit()',
:disabled => !@workflow.new_record? %>