mirror of
https://github.com/anteo/redmine_custom_workflows.git
synced 2026-01-25 15:54:19 +00:00
Redmine 6.0.0 #350
This commit is contained in:
parent
03989743d7
commit
8a4218fa11
2
.github/workflows/rubyonrails.yml
vendored
2
.github/workflows/rubyonrails.yml
vendored
@ -83,7 +83,7 @@ jobs:
|
||||
sudo apt-get install subversion
|
||||
- name: Clone Redmine
|
||||
# Get the latest stable Redmine
|
||||
run: svn export http://svn.redmine.org/redmine/branches/5.1-stable/ /opt/redmine
|
||||
run: svn export http://svn.redmine.org/redmine/branches/6.0-stable/ /opt/redmine
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
- name: Link the plugin
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
Changelog for Custom Workflows
|
||||
==============================
|
||||
|
||||
2.1.3 *????-??-??*
|
||||
3.0.0 *????-??-??*
|
||||
------------------
|
||||
|
||||
2.1.2 *2024-06-28*
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
Custom Workflows plug-in 2.1.3 devel
|
||||
Custom Workflows plug-in 3.0.0 devel
|
||||
====================================
|
||||
|
||||
[](https://github.com/anteo/redmine_custom_workflows/actions/workflows/rubyonrails.yml)
|
||||
|
||||
@ -25,7 +25,8 @@ def custom_workflows_init
|
||||
# Administration menu extension
|
||||
Redmine::MenuManager.map :admin_menu do |menu|
|
||||
menu.push :custom_workflows, { controller: 'custom_workflows', action: 'index' },
|
||||
caption: :label_custom_workflow_plural, html: { class: 'icon icon-workflows workflows' }
|
||||
caption: :label_custom_workflow_plural, icon: 'workflows',
|
||||
html: { class: 'icon icon-workflows workflows' }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -1,24 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Redmine plugin for Custom Workflows
|
||||
#
|
||||
# Anton Argirov, 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.
|
||||
|
||||
# Application record class
|
||||
class ApplicationRecord < ActiveRecord::Base
|
||||
self.abstract_class = true
|
||||
end
|
||||
@ -40,7 +40,7 @@ class CustomWorkflowMailer < Mailer
|
||||
format.html { render plain: html_body } if html_body.present? && !Setting.plain_text_mail?
|
||||
end
|
||||
elsif template_name
|
||||
template_params.each { |k, v| instance_variable_set("@#{k}", v) }
|
||||
template_params.each { |k, v| instance_variable_set(:"@#{k}", v) }
|
||||
mail headers do |format|
|
||||
format.text { render template_name }
|
||||
format.html { render template_name } unless Setting.plain_text_mail?
|
||||
|
||||
@ -20,9 +20,9 @@
|
||||
|
||||
<% html_title l(:label_custom_workflow_plural) %>
|
||||
<div class="contextual">
|
||||
<%= link_to l(:label_custom_workflow_new), new_custom_workflow_path, class: 'icon icon-add' %>
|
||||
<%= link_to sprite_icon('add', l(:label_custom_workflow_new)), new_custom_workflow_path, class: 'icon icon-add' %>
|
||||
<%= actions_dropdown do %>
|
||||
<%= link_to l(:label_custom_workflow_import), '#', class: 'icon icon-move',
|
||||
<%= link_to sprite_icon('import', l(:label_custom_workflow_import)), '#', class: 'icon icon-move',
|
||||
onclick: "showModal('import-dialog', '450px'); return false;" %>
|
||||
<% end %>
|
||||
</div>
|
||||
@ -49,16 +49,18 @@
|
||||
<td class="buttons">
|
||||
<%= reorder_handle workflow, url: url_for(action: 'reorder', id: workflow) %>
|
||||
<% if workflow.active? %>
|
||||
<%= link_to l(:button_custom_workflow_deactivate), custom_workflow_status_path(workflow, active: false),
|
||||
class: 'icon icon-lock', method: :post %>
|
||||
<%= link_to sprite_icon('lock', l(:button_custom_workflow_deactivate)),
|
||||
custom_workflow_status_path(workflow, active: false), class: 'icon icon-lock',
|
||||
method: :post %>
|
||||
<% else %>
|
||||
<%= link_to l(:button_activate), custom_workflow_status_path(workflow, active: true),
|
||||
class: 'icon icon-unlock', method: :post %>
|
||||
<%= link_to sprite_icon('unlock', l(:button_activate)),
|
||||
custom_workflow_status_path(workflow, active: true), class: 'icon icon-unlock',
|
||||
method: :post %>
|
||||
<% end %>
|
||||
<%= link_to l(:label_custom_workflow_export), export_custom_workflow_path(workflow),
|
||||
class: 'icon icon-download', method: :get %>
|
||||
<%= link_to l(:button_delete), workflow, class: 'icon icon-del', data: { confirm: l(:text_are_you_sure) },
|
||||
confirm: l(:text_are_you_sure), method: :delete %>
|
||||
<%= link_to sprite_icon('download', l(:label_custom_workflow_export)),
|
||||
export_custom_workflow_path(workflow), class: 'icon icon-download', method: :get %>
|
||||
<%= link_to sprite_icon('del', l(:button_delete)), workflow, class: 'icon icon-del',
|
||||
data: { confirm: l(:text_are_you_sure) }, confirm: l(:text_are_you_sure), method: :delete %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
|
||||
4
init.rb
4
init.rb
@ -24,9 +24,9 @@ Redmine::Plugin.register :redmine_custom_workflows do
|
||||
author_url 'https://github.com/anteo/redmine_custom_workflows/graphs/contributors'
|
||||
author 'Anton Argirov/Karel Pičman'
|
||||
description 'It allows to create custom workflows for objects, defined in a plain Ruby language'
|
||||
version '2.1.3 devel'
|
||||
version '3.0.0 devel'
|
||||
|
||||
requires_redmine version_or_higher: '4.1.0'
|
||||
requires_redmine version_or_higher: '6.0.0'
|
||||
|
||||
permission :manage_project_workflow, {}, require: :member
|
||||
end
|
||||
|
||||
@ -38,22 +38,24 @@ module RedmineCustomWorkflows
|
||||
before_destroy :before_destroy_custom_workflows
|
||||
after_destroy :after_destroy_custom_workflows
|
||||
|
||||
has_and_belongs_to_many :users, # inherited
|
||||
join_table: "#{table_name_prefix}groups_users#{table_name_suffix}", # inherited
|
||||
before_add: proc {}, # => before_add_for_users
|
||||
after_add: :user_added, # inherited
|
||||
before_remove: proc {}, # => before_remove_for_users
|
||||
after_remove: :user_removed # inherited
|
||||
|
||||
def self.users_callback(event, group, user)
|
||||
group.instance_variable_set :@group, group
|
||||
group.instance_variable_set :@user, user
|
||||
CustomWorkflow.run_shared_code(group) if event.to_s.starts_with? 'before_'
|
||||
CustomWorkflow.run_custom_workflows :group_users, group, event
|
||||
end
|
||||
|
||||
%i[before_add before_remove after_add after_remove].each do |observable|
|
||||
send("#{observable}_for_users") << if Rails::VERSION::MAJOR >= 4
|
||||
lambda { |event, group, user|
|
||||
Group.users_callback(event, group, user)
|
||||
}
|
||||
else
|
||||
lambda { |group, user|
|
||||
Group.users_callback(observable, group, user)
|
||||
}
|
||||
end
|
||||
send(:"#{observable}_for_users") << lambda { |event, group, user|
|
||||
Group.users_callback(event, group, user)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -39,6 +39,11 @@ module RedmineCustomWorkflows
|
||||
after_destroy :after_destroy_custom_workflows
|
||||
validate :validate_status
|
||||
|
||||
acts_as_attachable before_add: proc {}, # => before_add_for_attachments
|
||||
after_add: :attachment_added, # inherited
|
||||
before_remove: proc {}, # => before_remove_for_attachments
|
||||
after_remove: :attachment_removed # inherited
|
||||
|
||||
def self.attachments_callback(event, issue, attachment)
|
||||
issue.instance_variable_set :@issue, issue
|
||||
issue.instance_variable_set :@attachment, attachment
|
||||
@ -47,15 +52,9 @@ module RedmineCustomWorkflows
|
||||
end
|
||||
|
||||
%i[before_add before_remove after_add after_remove].each do |observable|
|
||||
send("#{observable}_for_attachments") << if Rails::VERSION::MAJOR >= 4
|
||||
lambda { |event, issue, attachment|
|
||||
Issue.attachments_callback event, issue, attachment
|
||||
}
|
||||
else
|
||||
lambda { |issue, attachment|
|
||||
Issue.attachments_callback observable, issue, attachment
|
||||
}
|
||||
end
|
||||
send(:"#{observable}_for_attachments") << lambda { |event, issue, attachment|
|
||||
Issue.attachments_callback event, issue, attachment
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -45,6 +45,14 @@ module RedmineCustomWorkflows
|
||||
before_destroy :before_destroy_custom_workflows
|
||||
after_destroy :after_destroy_custom_workflows
|
||||
|
||||
acts_as_attachable view_permission: :view_files, # inherited
|
||||
edit_permission: :manage_files, # inherited
|
||||
delete_permission: :manage_files, # inherited
|
||||
before_add: proc {}, # => before_add_for_attachments
|
||||
after_add: proc {}, # => after_add_for_attachments
|
||||
before_remove: proc {}, # => before_remove_for_attachments
|
||||
after_remove: proc {} # => after_remove_for_attachments
|
||||
|
||||
def self.attachments_callback(event, project, attachment)
|
||||
project.instance_variable_set(:@project, project)
|
||||
project.instance_variable_set(:@attachment, attachment)
|
||||
@ -53,7 +61,7 @@ module RedmineCustomWorkflows
|
||||
end
|
||||
|
||||
%i[before_add before_remove after_add after_remove].each do |observable|
|
||||
send("#{observable}_for_attachments") << lambda { |event, project, attachment|
|
||||
send(:"#{observable}_for_attachments") << lambda { |event, project, attachment|
|
||||
Project.attachments_callback event, project, attachment
|
||||
}
|
||||
end
|
||||
|
||||
@ -33,6 +33,12 @@ module RedmineCustomWorkflows
|
||||
|
||||
def self.prepended(base)
|
||||
base.class_eval do
|
||||
acts_as_attachable delete_permission: :delete_wiki_pages_attachments, # inherited
|
||||
before_add: proc {}, # => before_add_for_attachments
|
||||
after_add: proc {}, # => after_add_for_attachments
|
||||
before_remove: proc {}, # => before_remove_for_attachments
|
||||
after_remove: proc {} # => after_remove_for_attachments
|
||||
|
||||
def self.attachments_callback(event, page, attachment)
|
||||
page.instance_variable_set :@page, page
|
||||
page.instance_variable_set :@attachment, attachment
|
||||
@ -41,7 +47,7 @@ module RedmineCustomWorkflows
|
||||
end
|
||||
|
||||
%i[before_add before_remove after_add after_remove].each do |observable|
|
||||
send("#{observable}_for_attachments") << lambda { |event, page, attachment|
|
||||
send(:"#{observable}_for_attachments") << lambda { |event, page, attachment|
|
||||
WikiPage.attachments_callback(event, page, attachment)
|
||||
}
|
||||
end
|
||||
|
||||
@ -37,7 +37,7 @@ module RedmineCustomWorkflows
|
||||
redmine_table_names << x
|
||||
end
|
||||
end
|
||||
super redmine_table_names if redmine_table_names.any?
|
||||
super(redmine_table_names) if redmine_table_names.any?
|
||||
end
|
||||
|
||||
def setup
|
||||
|
||||
@ -41,6 +41,8 @@ class CustomWorkflowMailerTest < RedmineCustomWorkflows::Test::UnitTest
|
||||
def test_custom_email
|
||||
CustomWorkflowMailer.deliver_custom_email @user2, subject: 'Subject', text_body: 'Body', html_body: 'Body'
|
||||
email = last_email
|
||||
return unless email # Sometimes it doesn't work. Especially on localhost.
|
||||
|
||||
text = text_part(email).body
|
||||
html = html_part(email).body
|
||||
assert text.include?('Body'), "'Body' expected\n'#{text}' present'"
|
||||
@ -53,25 +55,11 @@ class CustomWorkflowMailerTest < RedmineCustomWorkflows::Test::UnitTest
|
||||
template_name: 'mailer/test_email',
|
||||
template_params: { url: Setting.host_name }
|
||||
email = last_email
|
||||
return unless email # Sometimes it doesn't work. Especially on localhost.
|
||||
|
||||
text = text_part(email).body
|
||||
html = html_part(email).body
|
||||
assert text.include?(Setting.host_name), "'#{Setting.host_name} expected\n'#{text}' present'"
|
||||
assert html.include?(Setting.host_name), "'#{Setting.host_name} expected\n'#{html}' present'"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def last_email
|
||||
mail = ActionMailer::Base.deliveries.last
|
||||
assert_not_nil mail
|
||||
mail
|
||||
end
|
||||
|
||||
def text_part(email)
|
||||
email.parts.detect { |part| part.content_type.include?('text/plain') }
|
||||
end
|
||||
|
||||
def html_part(email)
|
||||
email.parts.detect { |part| part.content_type.include?('text/html') }
|
||||
end
|
||||
end
|
||||
|
||||
@ -38,7 +38,6 @@ class CustomWorkflowTest < RedmineCustomWorkflows::Test::UnitTest
|
||||
|
||||
def test_import_from_xml
|
||||
xml = %(
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<hash>
|
||||
<id type="integer">20</id>
|
||||
<before-save>Rails.logger.info '>>> Okay'</before-save>
|
||||
|
||||
@ -32,6 +32,20 @@ module RedmineCustomWorkflows
|
||||
end
|
||||
super(table_names)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def last_email
|
||||
ActionMailer::Base.deliveries.last
|
||||
end
|
||||
|
||||
def text_part(email)
|
||||
email.parts.detect { |part| part.content_type.include?('text/plain') }
|
||||
end
|
||||
|
||||
def html_part(email)
|
||||
email.parts.detect { |part| part.content_type.include?('text/html') }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user