mirror of
https://github.com/anteo/redmine_custom_workflows.git
synced 2026-01-26 00:04:20 +00:00
Merge branch 'devel-1.0.0' into master
This commit is contained in:
commit
0bc5179686
4
Gemfile
Normal file
4
Gemfile
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
|
gem 'acts_as_list'
|
||||||
|
gem 'activemodel-serializers-xml'
|
||||||
@ -1,8 +1,32 @@
|
|||||||
class CustomWorkflowsController < ApplicationController
|
class CustomWorkflowsController < ApplicationController
|
||||||
|
|
||||||
layout 'admin'
|
layout 'admin'
|
||||||
before_filter :require_admin
|
before_action :require_admin
|
||||||
before_filter :find_workflow, :only => [:show, :edit, :update, :destroy, :export, :change_status]
|
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
|
def index
|
||||||
@workflows = CustomWorkflow.includes(:projects).all
|
@workflows = CustomWorkflow.includes(:projects).all
|
||||||
@ -52,14 +76,30 @@ class CustomWorkflowsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def create
|
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|
|
respond_to do |format|
|
||||||
if params.has_key?(:commit) && @workflow.save
|
if params.has_key?(:commit) && @workflow.save
|
||||||
flash[:notice] = l(:notice_successful_create)
|
flash[:notice] = l(:notice_successful_create)
|
||||||
cookies[:custom_workflows_author] = @workflow.author
|
cookies[:custom_workflows_author] = @workflow.author
|
||||||
format.html { redirect_to(custom_workflows_path) }
|
format.html { redirect_to(custom_workflows_path) }
|
||||||
else
|
else
|
||||||
format.html { render :action => "new" }
|
format.html { render action: :new }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -70,26 +110,38 @@ class CustomWorkflowsController < ApplicationController
|
|||||||
flash[:notice] = l(:notice_successful_status_change)
|
flash[:notice] = l(:notice_successful_status_change)
|
||||||
format.html { redirect_to(custom_workflows_path) }
|
format.html { redirect_to(custom_workflows_path) }
|
||||||
else
|
else
|
||||||
format.html { render :action => :edit }
|
format.html { render action: :edit }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
respond_to do |format|
|
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
|
if params.has_key?(:commit) && @workflow.save
|
||||||
flash[:notice] = l(:notice_successful_update)
|
flash[:notice] = l(:notice_successful_update)
|
||||||
format.html { redirect_to(custom_workflows_path) }
|
format.html { redirect_to(custom_workflows_path) }
|
||||||
else
|
else
|
||||||
format.html { render :action => :edit }
|
format.html { render action: :edit }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@workflow.destroy
|
@workflow.destroy
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
flash[:notice] = l(:notice_successful_delete)
|
flash[:notice] = l(:notice_successful_delete)
|
||||||
format.html { redirect_to(custom_workflows_path) }
|
format.html { redirect_to(custom_workflows_path) }
|
||||||
|
|||||||
@ -14,7 +14,6 @@ class CustomWorkflow < ActiveRecord::Base
|
|||||||
COLLECTION_OBSERVABLES = [:group_users, :issue_attachments, :project_attachments, :wiki_page_attachments]
|
COLLECTION_OBSERVABLES = [:group_users, :issue_attachments, :project_attachments, :wiki_page_attachments]
|
||||||
SINGLE_OBSERVABLES = [:issue, :user, :group, :attachment, :project, :wiki_content, :time_entry, :version]
|
SINGLE_OBSERVABLES = [:issue, :user, :group, :attachment, :project, :wiki_content, :time_entry, :version]
|
||||||
|
|
||||||
attr_protected :id
|
|
||||||
has_and_belongs_to_many :projects
|
has_and_belongs_to_many :projects
|
||||||
acts_as_list
|
acts_as_list
|
||||||
|
|
||||||
@ -33,7 +32,8 @@ class CustomWorkflow < ActiveRecord::Base
|
|||||||
|
|
||||||
scope :active, lambda { where(:active => true) }
|
scope :active, lambda { where(:active => true) }
|
||||||
scope :for_project, (lambda do |project|
|
scope :for_project, (lambda do |project|
|
||||||
where("is_for_all OR EXISTS (SELECT * FROM #{projects_join_table} WHERE project_id=? AND custom_workflow_id=id)", project.id)
|
where("is_for_all=? OR EXISTS (SELECT * FROM #{projects_join_table} WHERE project_id=? AND custom_workflow_id=id)",
|
||||||
|
1, project.id)
|
||||||
end)
|
end)
|
||||||
scope :observing, lambda { |observable| where(:observable => observable) }
|
scope :observing, lambda { |observable| where(:observable => observable) }
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ class CustomWorkflow < ActiveRecord::Base
|
|||||||
|
|
||||||
def validate_syntax_for(object, event)
|
def validate_syntax_for(object, event)
|
||||||
object.instance_eval(read_attribute(event)) if respond_to?(event) && read_attribute(event)
|
object.instance_eval(read_attribute(event)) if respond_to?(event) && read_attribute(event)
|
||||||
rescue WorkflowError => e
|
rescue WorkflowError => _
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
errors.add event, :invalid_script, :error => e
|
errors.add event, :invalid_script, :error => e
|
||||||
end
|
end
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
CustomWorkflow::OBSERVABLES.collect {|o| [l("custom_workflow_observable_#{o}"), o]}, {},
|
CustomWorkflow::OBSERVABLES.collect {|o| [l("custom_workflow_observable_#{o}"), o]}, {},
|
||||||
:onchange => 'this.form.submit()',
|
:onchange => 'this.form.submit()',
|
||||||
:disabled => !@workflow.new_record? %></p>
|
:disabled => !@workflow.new_record? %></p>
|
||||||
<p><%= f.text_area :description, :cols => 40, :rows => 5 %></p>
|
<p><%= f.text_area :description, cols: 40, rows: 5 , class: 'wiki-edit' %></p>
|
||||||
<% if @workflow.has_projects_association? %>
|
<% if @workflow.has_projects_association? %>
|
||||||
<p><%= f.check_box :is_for_all, :onclick => "checkAndDisable('custom_workflow_enabled_projects', this.checked);", :label => :field_enabled_for_all_projects %></p>
|
<p><%= f.check_box :is_for_all, :onclick => "checkAndDisable('custom_workflow_enabled_projects', this.checked);", :label => :field_enabled_for_all_projects %></p>
|
||||||
<% end %>
|
<% end %>
|
||||||
@ -44,10 +44,10 @@
|
|||||||
<% when :shared %>
|
<% when :shared %>
|
||||||
<%= f.text_area :shared_code, :cols => 40, :rows => 20, :wrap => 'off', :class => 'custom_workflow_script' %>
|
<%= f.text_area :shared_code, :cols => 40, :rows => 20, :wrap => 'off', :class => 'custom_workflow_script' %>
|
||||||
<% when *CustomWorkflow::COLLECTION_OBSERVABLES %>
|
<% when *CustomWorkflow::COLLECTION_OBSERVABLES %>
|
||||||
<%= render :layout => 'layouts/collapsible',
|
<% collapsed = (not (@workflow.before_add.present? or @workflow.after_add.present? or @workflow.errors[:base].present?)) %>
|
||||||
:locals => {
|
<fieldset class="collapsible <%= collapsed ? 'collapsed' : '' %>">
|
||||||
:collapsed => (not (@workflow.before_add.present? or @workflow.after_add.present? or @workflow.errors[:base].present?)),
|
<legend onclick="toggleFieldset(this);"><%= l(:label_add_workflows) %></legend>
|
||||||
:label => l(:label_add_workflows)} do %>
|
<div style="<%= collapsed ? 'display: none' : '' %>">
|
||||||
<div class="splitcontent">
|
<div class="splitcontent">
|
||||||
<div class="splitcontentleft">
|
<div class="splitcontentleft">
|
||||||
<%= f.text_area :before_add, :cols => 40, :rows => 20, :wrap => 'off', :class => 'custom_workflow_script' %>
|
<%= f.text_area :before_add, :cols => 40, :rows => 20, :wrap => 'off', :class => 'custom_workflow_script' %>
|
||||||
@ -56,11 +56,12 @@
|
|||||||
<%= f.text_area :after_add, :cols => 40, :rows => 20, :wrap => 'off', :class => 'custom_workflow_script' %>
|
<%= f.text_area :after_add, :cols => 40, :rows => 20, :wrap => 'off', :class => 'custom_workflow_script' %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
</div>
|
||||||
<%= render :layout => 'layouts/collapsible',
|
</fieldset>
|
||||||
:locals => {
|
<% collapsed = (not (@workflow.before_remove.present? or @workflow.after_remove.present?)) %>
|
||||||
:collapsed => (not (@workflow.before_remove.present? or @workflow.after_remove.present?)),
|
<fieldset class="collapsible <%= collapsed ? 'collapsed' : '' %>">
|
||||||
:label => l(:label_remove_workflows)} do %>
|
<legend onclick="toggleFieldset(this);"><%= l(:label_remove_workflows) %></legend>
|
||||||
|
<div style="<%= collapsed ? 'display: none' : '' %>">
|
||||||
<div class="splitcontent">
|
<div class="splitcontent">
|
||||||
<div class="splitcontentleft">
|
<div class="splitcontentleft">
|
||||||
<%= f.text_area :before_remove, :cols => 40, :rows => 20, :wrap => 'off', :class => 'custom_workflow_script' %>
|
<%= f.text_area :before_remove, :cols => 40, :rows => 20, :wrap => 'off', :class => 'custom_workflow_script' %>
|
||||||
@ -69,12 +70,13 @@
|
|||||||
<%= f.text_area :after_remove, :cols => 40, :rows => 20, :wrap => 'off', :class => 'custom_workflow_script' %>
|
<%= f.text_area :after_remove, :cols => 40, :rows => 20, :wrap => 'off', :class => 'custom_workflow_script' %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
</div>
|
||||||
|
</fieldset>
|
||||||
<% when *CustomWorkflow::SINGLE_OBSERVABLES %>
|
<% when *CustomWorkflow::SINGLE_OBSERVABLES %>
|
||||||
<%= render :layout => 'layouts/collapsible',
|
<% collapsed = (not (@workflow.before_save.present? or @workflow.after_save.present? or @workflow.errors[:base].present?)) %>
|
||||||
:locals => {
|
<fieldset class="collapsible <%= collapsed ? 'collapsed' : '' %>">
|
||||||
:collapsed => (not (@workflow.before_save.present? or @workflow.after_save.present? or @workflow.errors[:base].present?)),
|
<legend onclick="toggleFieldset(this);"><%= l(:label_save_workflows) %></legend>
|
||||||
:label => l(:label_save_workflows)} do %>
|
<div style="<%= collapsed ? 'display: none' : '' %>">
|
||||||
<div class="splitcontent">
|
<div class="splitcontent">
|
||||||
<div class="splitcontentleft">
|
<div class="splitcontentleft">
|
||||||
<%= f.text_area :before_save, :cols => 40, :rows => 20, :wrap => 'off', :class => 'custom_workflow_script' %>
|
<%= f.text_area :before_save, :cols => 40, :rows => 20, :wrap => 'off', :class => 'custom_workflow_script' %>
|
||||||
@ -89,11 +91,12 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
</div>
|
||||||
<%= render :layout => 'layouts/collapsible',
|
</fieldset>
|
||||||
:locals => {
|
<% collapsed = (not (@workflow.before_destroy.present? or @workflow.after_destroy.present?)) %>
|
||||||
:collapsed => (not (@workflow.before_destroy.present? or @workflow.after_destroy.present?)),
|
<fieldset class="collapsible <%= collapsed ? 'collapsed' : '' %>">
|
||||||
:label => l(:label_destroy_workflows)} do %>
|
<legend onclick="toggleFieldset(this);"><%= l(:label_destroy_workflows) %></legend>
|
||||||
|
<div style="<%= collapsed ? 'display: none' : '' %>">
|
||||||
<div class="splitcontent">
|
<div class="splitcontent">
|
||||||
<div class="splitcontentleft">
|
<div class="splitcontentleft">
|
||||||
<%= f.text_area :before_destroy, :cols => 40, :rows => 20, :wrap => 'off', :class => 'custom_workflow_script' %>
|
<%= f.text_area :before_destroy, :cols => 40, :rows => 20, :wrap => 'off', :class => 'custom_workflow_script' %>
|
||||||
@ -102,11 +105,12 @@
|
|||||||
<%= f.text_area :after_destroy, :cols => 40, :rows => 20, :wrap => 'off', :class => 'custom_workflow_script' %>
|
<%= f.text_area :after_destroy, :cols => 40, :rows => 20, :wrap => 'off', :class => 'custom_workflow_script' %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
</div>
|
||||||
|
</fieldset>
|
||||||
<% end %>
|
<% end %>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script>
|
||||||
jQuery('.custom_workflow_script').taboverride(2, true);
|
jQuery('.custom_workflow_script').taboverride(2, true);
|
||||||
function checkAndDisable(id, checked) {
|
function checkAndDisable(id, checked) {
|
||||||
if (checked) {
|
if (checked) {
|
||||||
|
|||||||
@ -38,7 +38,9 @@
|
|||||||
<%= workflow.projects.map(&:name).join(", ") %>
|
<%= workflow.projects.map(&:name).join(", ") %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</td>
|
</td>
|
||||||
<td align="center" nowrap><%= reorder_links("custom_workflow", {:action => 'update', :id => workflow, :commit => true}) %></td>
|
<td align="center" nowrap>
|
||||||
|
<%= reorder_handle(workflow, url: url_for(action: 'reorder', id: workflow) ) %>
|
||||||
|
</td>
|
||||||
<td class="buttons">
|
<td class="buttons">
|
||||||
<% if workflow.active? %>
|
<% if workflow.active? %>
|
||||||
<%= link_to(l(:button_custom_workflow_deactivate), custom_workflow_status_path(workflow, :active => false), :class => 'icon icon-inactive', :method => :post) %>
|
<%= link_to(l(:button_custom_workflow_deactivate), custom_workflow_status_path(workflow, :active => false), :class => 'icon icon-inactive', :method => :post) %>
|
||||||
@ -74,3 +76,7 @@
|
|||||||
</p>
|
</p>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<%= javascript_tag do %>
|
||||||
|
$(function() { $("table.custom-workflows tbody").positionedItems(); });
|
||||||
|
<% end %>
|
||||||
|
|||||||
@ -1,6 +0,0 @@
|
|||||||
<fieldset class="collapsible <%= collapsed ? 'collapsed' : '' %>">
|
|
||||||
<legend onclick="toggleFieldset(this);"><%= label %></legend>
|
|
||||||
<div style="<%= collapsed ? 'display: none' : '' %>">
|
|
||||||
<%= yield %>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
<%= form_for @project do |f| %>
|
<%= form_for @project do %>
|
||||||
<%= hidden_field_tag :tab, 'custom_workflow' %>
|
<%= hidden_field_tag :tab, 'custom_workflow' %>
|
||||||
<%= hidden_field_tag 'project[custom_workflow_ids][]', '' %>
|
<%= hidden_field_tag 'project[custom_workflow_ids][]', '' %>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
function TabOverride(element, tabSize, autoIndent) {
|
function TabOverride(element, tabSize, autoIndent) {
|
||||||
var ta = document.createElement('textarea');
|
let ta = document.createElement('textarea');
|
||||||
ta.value = '\n';
|
ta.value = '\n';
|
||||||
|
|
||||||
this.newline = ta.value;
|
this.newline = ta.value;
|
||||||
@ -43,12 +43,11 @@
|
|||||||
* @function
|
* @function
|
||||||
*/
|
*/
|
||||||
setTabSize:function (size) {
|
setTabSize:function (size) {
|
||||||
var i;
|
|
||||||
if (!size) { // size is 0 or not specified (or falsy)
|
if (!size) { // size is 0 or not specified (or falsy)
|
||||||
this.aTab = '\t';
|
this.aTab = '\t';
|
||||||
} else if (typeof size === 'number' && size > 0) {
|
} else if (typeof size === 'number' && size > 0) {
|
||||||
this.aTab = '';
|
this.aTab = '';
|
||||||
for (i = 0; i < size; i += 1) {
|
for (let i = 0; i < size; i += 1) {
|
||||||
this.aTab += ' ';
|
this.aTab += ' ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -64,7 +63,7 @@
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
overrideKeyPress:function (e) {
|
overrideKeyPress:function (e) {
|
||||||
var key = e.keyCode;
|
let key = e.keyCode;
|
||||||
if ((key === 9 || (key === 13 && this.autoIndent && !this.inWhitespace)) && !e.ctrlKey && !e.altKey) {
|
if ((key === 9 || (key === 13 && this.autoIndent && !this.inWhitespace)) && !e.ctrlKey && !e.altKey) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
@ -78,7 +77,7 @@
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
overrideKeyDown:function (e) {
|
overrideKeyDown:function (e) {
|
||||||
var key = e.keyCode, // the key code for the key that was pressed
|
let key = e.keyCode, // the key code for the key that was pressed
|
||||||
tab, // the string representing a tab
|
tab, // the string representing a tab
|
||||||
tabLen, // the length of a tab
|
tabLen, // the length of a tab
|
||||||
text, // initial text in the textarea
|
text, // initial text in the textarea
|
||||||
|
|||||||
104
config/locales/cs.yml
Normal file
104
config/locales/cs.yml
Normal file
@ -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: <sdílený kód>
|
||||||
|
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
|
||||||
@ -4,4 +4,5 @@ RedmineApp::Application.routes.draw do
|
|||||||
post '/custom_workflows/:id', :to => 'custom_workflows#update'
|
post '/custom_workflows/:id', :to => 'custom_workflows#update'
|
||||||
get '/custom_workflows/:id/export', :to => 'custom_workflows#export', :as => 'export_custom_workflow'
|
get '/custom_workflows/:id/export', :to => 'custom_workflows#export', :as => 'export_custom_workflow'
|
||||||
post '/custom_workflows/:id/change_status', :to => 'custom_workflows#change_status', :as => 'custom_workflow_status'
|
post '/custom_workflows/:id/change_status', :to => 'custom_workflows#change_status', :as => 'custom_workflow_status'
|
||||||
|
put '/custom_workflows/:id/reorder', :to => 'custom_workflows#reorder'
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
class CreateCustomWorkflows < ActiveRecord::Migration
|
class CreateCustomWorkflows < ActiveRecord::Migration[4.2]
|
||||||
def self.up
|
def change
|
||||||
create_table :custom_workflows, :force => true do |t|
|
create_table :custom_workflows, :force => true do |t|
|
||||||
t.references :project
|
t.references :project
|
||||||
t.text :script, :null => true, :default => nil
|
t.text :script, :null => true, :default => nil
|
||||||
@ -8,7 +8,4 @@ class CreateCustomWorkflows < ActiveRecord::Migration
|
|||||||
add_index :custom_workflows, [:project_id], :unique => true
|
add_index :custom_workflows, [:project_id], :unique => true
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.down
|
|
||||||
drop_table :custom_workflows
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
class AlterCustomWorkflows < ActiveRecord::Migration
|
class AlterCustomWorkflows < ActiveRecord::Migration[4.2]
|
||||||
def self.up
|
def self.up
|
||||||
remove_column :custom_workflows, :project_id
|
remove_column :custom_workflows, :project_id
|
||||||
remove_column :custom_workflows, :is_enabled
|
remove_column :custom_workflows, :is_enabled
|
||||||
@ -7,6 +7,4 @@ class AlterCustomWorkflows < ActiveRecord::Migration
|
|||||||
add_column :custom_workflows, :position, :integer, :null => false, :default => 1
|
add_column :custom_workflows, :position, :integer, :null => false, :default => 1
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.down
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
class CreateCustomWorkflowsProjects < ActiveRecord::Migration
|
class CreateCustomWorkflowsProjects < ActiveRecord::Migration[4.2]
|
||||||
def self.up
|
def change
|
||||||
create_table :custom_workflows_projects, :force => true, :id => false do |t|
|
create_table :custom_workflows_projects, :force => true, :id => false do |t|
|
||||||
t.references :project
|
t.references :project
|
||||||
t.references :custom_workflow
|
t.references :custom_workflow
|
||||||
@ -8,7 +8,4 @@ class CreateCustomWorkflowsProjects < ActiveRecord::Migration
|
|||||||
add_index :custom_workflows_projects, [:custom_workflow_id]
|
add_index :custom_workflows_projects, [:custom_workflow_id]
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.down
|
|
||||||
drop_table :custom_workflows_projects
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
class ChangeCustomWorkflowsDescriptionType < ActiveRecord::Migration
|
class ChangeCustomWorkflowsDescriptionType < ActiveRecord::Migration[4.2]
|
||||||
def self.up
|
def self.up
|
||||||
change_column :custom_workflows, :description, :text, :null => true, :default => nil
|
change_column :custom_workflows, :description, :text, :null => true, :default => nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.down
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
class AddAfterSaveToCustomWorkflows < ActiveRecord::Migration
|
class AddAfterSaveToCustomWorkflows < ActiveRecord::Migration[4.2]
|
||||||
def self.up
|
def self.up
|
||||||
rename_column :custom_workflows, :script, :before_save
|
rename_column :custom_workflows, :script, :before_save
|
||||||
change_column :custom_workflows, :before_save, :text, :null => true
|
change_column :custom_workflows, :before_save, :text, :null => true
|
||||||
|
|||||||
@ -1,8 +1,5 @@
|
|||||||
class AddIsForAllToCustomWorkflows < ActiveRecord::Migration
|
class AddIsForAllToCustomWorkflows < ActiveRecord::Migration[4.2]
|
||||||
def self.up
|
def change
|
||||||
add_column :custom_workflows, :is_for_all, :boolean, :null => false, :default => false
|
add_column :custom_workflows, :is_for_all, :boolean, :null => false, :default => false
|
||||||
end
|
end
|
||||||
def self.down
|
|
||||||
remove_column :custom_workflows, :is_for_all
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
class MakeAfterSaveAndBeforeSaveNullable < ActiveRecord::Migration
|
class MakeAfterSaveAndBeforeSaveNullable < ActiveRecord::Migration[4.2]
|
||||||
def up
|
def up
|
||||||
change_column :custom_workflows, :before_save, :text, :null => true, :default => nil
|
change_column :custom_workflows, :before_save, :text, :null => true, :default => nil
|
||||||
change_column :custom_workflows, :after_save, :text, :null => true, :default => nil
|
change_column :custom_workflows, :after_save, :text, :null => true, :default => nil
|
||||||
end
|
end
|
||||||
def down
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
class SetPositionFieldNullable < ActiveRecord::Migration
|
class SetPositionFieldNullable < ActiveRecord::Migration[4.2]
|
||||||
def up
|
def up
|
||||||
change_column :custom_workflows, :position, :integer, :null => true
|
change_column :custom_workflows, :position, :integer, :null => true
|
||||||
end
|
end
|
||||||
def down
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
class AddAuthorAndTimestampsToCustomWorkflows < ActiveRecord::Migration
|
class AddAuthorAndTimestampsToCustomWorkflows < ActiveRecord::Migration[4.2]
|
||||||
def change
|
def change
|
||||||
add_column :custom_workflows, :author, :string, :null => true
|
add_column :custom_workflows, :author, :string, :null => true
|
||||||
add_timestamps :custom_workflows
|
add_timestamps :custom_workflows
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
class CreateExampleWorkflow < ActiveRecord::Migration
|
class CreateExampleWorkflow < ActiveRecord::Migration[4.2]
|
||||||
def self.up
|
def self.up
|
||||||
CustomWorkflow.reset_column_information
|
CustomWorkflow.reset_column_information
|
||||||
old = CustomWorkflow.where(:name => 'Duration/Done Ratio/Status correlation').first
|
old = CustomWorkflow.where(:name => 'Duration/Done Ratio/Status correlation').first
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
class AddActiveFieldToCustomWorkflows < ActiveRecord::Migration
|
class AddActiveFieldToCustomWorkflows < ActiveRecord::Migration[4.2]
|
||||||
def change
|
def change
|
||||||
add_column :custom_workflows, :active, :boolean, :null => false, :default => true
|
add_column :custom_workflows, :active, :boolean, :null => false, :default => true
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
class AddObservableFieldToCustomWorkflows < ActiveRecord::Migration
|
class AddObservableFieldToCustomWorkflows < ActiveRecord::Migration[4.2]
|
||||||
def change
|
def change
|
||||||
add_column :custom_workflows, :observable, :string, :null => false, :default => 'issue'
|
add_column :custom_workflows, :observable, :string, :null => false, :default => 'issue'
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
class AddAdditionalScriptFieldsToCustomWorkflows < ActiveRecord::Migration
|
class AddAdditionalScriptFieldsToCustomWorkflows < ActiveRecord::Migration[4.2]
|
||||||
def change
|
def change
|
||||||
add_column :custom_workflows, :shared_code, :text, :null => true
|
add_column :custom_workflows, :shared_code, :text, :null => true
|
||||||
add_column :custom_workflows, :before_add, :text, :null => true
|
add_column :custom_workflows, :before_add, :text, :null => true
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
class AddBeforeAndAfterDestroyToCustomWorkflows < ActiveRecord::Migration
|
class AddBeforeAndAfterDestroyToCustomWorkflows < ActiveRecord::Migration[4.2]
|
||||||
def change
|
def change
|
||||||
add_column :custom_workflows, :before_destroy, :text, :null => true
|
add_column :custom_workflows, :before_destroy, :text, :null => true
|
||||||
add_column :custom_workflows, :after_destroy, :text, :null => true
|
add_column :custom_workflows, :after_destroy, :text, :null => true
|
||||||
|
|||||||
10
init.rb
10
init.rb
@ -7,21 +7,23 @@ Redmine::Plugin.register :redmine_custom_workflows do
|
|||||||
version '0.1.6'
|
version '0.1.6'
|
||||||
url 'http://www.redmine.org/plugins/custom-workflows'
|
url 'http://www.redmine.org/plugins/custom-workflows'
|
||||||
|
|
||||||
|
requires_redmine version_or_higher: '4.0.0'
|
||||||
|
|
||||||
menu :admin_menu, :custom_workflows, {:controller => 'custom_workflows', :action => 'index'},
|
menu :admin_menu, :custom_workflows, {:controller => 'custom_workflows', :action => 'index'},
|
||||||
:if => Proc.new { User.current.admin? }, :caption => :label_custom_workflow_plural, :html => {:class => 'icon'}
|
:if => Proc.new { User.current.admin? }, :caption => :label_custom_workflow_plural,
|
||||||
|
:html => {:class => 'icon icon-workflows'}
|
||||||
|
|
||||||
permission :manage_project_workflow, {}, :require => :member
|
permission :manage_project_workflow, {}, :require => :member
|
||||||
end
|
end
|
||||||
|
|
||||||
require 'redmine_custom_workflows/hooks'
|
require 'redmine_custom_workflows/hooks'
|
||||||
|
|
||||||
|
require File.dirname(__FILE__) + '/lib/redmine_custom_workflows/projects_helper_patch'
|
||||||
|
|
||||||
Rails.application.config.to_prepare do
|
Rails.application.config.to_prepare do
|
||||||
unless Project.include?(RedmineCustomWorkflows::ProjectPatch)
|
unless Project.include?(RedmineCustomWorkflows::ProjectPatch)
|
||||||
Project.send(:include, RedmineCustomWorkflows::ProjectPatch)
|
Project.send(:include, RedmineCustomWorkflows::ProjectPatch)
|
||||||
end
|
end
|
||||||
unless ProjectsHelper.include?(RedmineCustomWorkflows::ProjectsHelperPatch)
|
|
||||||
ProjectsHelper.send(:include, RedmineCustomWorkflows::ProjectsHelperPatch)
|
|
||||||
end
|
|
||||||
unless Attachment.include?(RedmineCustomWorkflows::AttachmentPatch)
|
unless Attachment.include?(RedmineCustomWorkflows::AttachmentPatch)
|
||||||
Attachment.send(:include, RedmineCustomWorkflows::AttachmentPatch)
|
Attachment.send(:include, RedmineCustomWorkflows::AttachmentPatch)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -8,7 +8,7 @@ module RedmineCustomWorkflows
|
|||||||
end
|
end
|
||||||
|
|
||||||
module InstanceMethods
|
module InstanceMethods
|
||||||
def custom_email(headers={})
|
def self.deliver_custom_email(headers={})
|
||||||
user = headers.delete :user
|
user = headers.delete :user
|
||||||
headers[:to] = user.mail if user
|
headers[:to] = user.mail if user
|
||||||
text_body = headers.delete :text_body
|
text_body = headers.delete :text_body
|
||||||
@ -27,7 +27,7 @@ module RedmineCustomWorkflows
|
|||||||
format.html { render template_name } unless Setting.plain_text_mail?
|
format.html { render template_name } unless Setting.plain_text_mail?
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
raise 'Nor :text_body, :html_body or :template_name specified'
|
raise 'Not :text_body, :html_body or :template_name specified'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,20 +1,14 @@
|
|||||||
module RedmineCustomWorkflows
|
module RedmineCustomWorkflows
|
||||||
module ProjectsHelperPatch
|
module ProjectsHelperPatch
|
||||||
|
|
||||||
def self.included(base)
|
def project_settings_tabs
|
||||||
base.send(:include, InstanceMethods)
|
tabs = super
|
||||||
base.class_eval do
|
|
||||||
alias_method_chain :project_settings_tabs, :custom_workflows
|
|
||||||
end
|
|
||||||
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',
|
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)
|
:label => :label_custom_workflow_plural} if User.current.allowed_to?(:manage_project_workflow, @project)
|
||||||
tabs
|
tabs
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
ProjectsHelper.send(:prepend, RedmineCustomWorkflows::ProjectsHelperPatch)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user