Issue relations first commit (not thoroughly tested). 4 kinds of relation are available:
* relates to: do nothing special. Just to know that the 2 issues are related... * duplicates: will close the related issue with the same status when closing the issue (not implemented yet) * blocks: will require to close the blocking issue before closing the blocked issue (not implemented yet) * precedes (end to start relation): start date of the related issue depends on the due date of the preceding issue (implemented). A delay can be set so that the related issue can only start n days after the end of the preceding issue. When setting dates for an issue, dates of all downstream issues are set according to these relations. To set a relation, the 2 issues have to belong to the same project (may change in the future). So if an issue is moved to another project, all its relations are removed. Circular dependencies are checked when creating a relation. git-svn-id: http://redmine.rubyforge.org/svn/trunk@506 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
987e843cd1
commit
92b02014d2
|
@ -0,0 +1,59 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006-2007 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# 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 IssueRelationsController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
|
before_filter :find_project, :authorize
|
||||||
|
|
||||||
|
def new
|
||||||
|
@relation = IssueRelation.new(params[:relation])
|
||||||
|
@relation.issue_from = @issue
|
||||||
|
@relation.save if request.post?
|
||||||
|
respond_to do |format|
|
||||||
|
format.html { redirect_to :controller => 'issues', :action => 'show', :id => @issue }
|
||||||
|
format.js do
|
||||||
|
render :update do |page|
|
||||||
|
page.replace_html "relations", :partial => 'issues/relations'
|
||||||
|
if @relation.errors.empty?
|
||||||
|
page << "$('relation_delay').value = ''"
|
||||||
|
page << "$('relation_issue_to_id').value = ''"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
relation = IssueRelation.find(params[:id])
|
||||||
|
if request.post? && @issue.relations.include?(relation)
|
||||||
|
relation.destroy
|
||||||
|
@issue.reload
|
||||||
|
end
|
||||||
|
respond_to do |format|
|
||||||
|
format.html { redirect_to :controller => 'issues', :action => 'show', :id => @issue }
|
||||||
|
format.js { render(:update) {|page| page.replace_html "relations", :partial => 'issues/relations'} }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def find_project
|
||||||
|
@issue = Issue.find(params[:issue_id])
|
||||||
|
@project = @issue.project
|
||||||
|
rescue ActiveRecord::RecordNotFound
|
||||||
|
render_404
|
||||||
|
end
|
||||||
|
end
|
|
@ -23,6 +23,8 @@ class IssuesController < ApplicationController
|
||||||
include CustomFieldsHelper
|
include CustomFieldsHelper
|
||||||
helper :ifpdf
|
helper :ifpdf
|
||||||
include IfpdfHelper
|
include IfpdfHelper
|
||||||
|
helper :issue_relations
|
||||||
|
include IssueRelationsHelper
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@status_options = @issue.status.find_new_statuses_allowed_to(logged_in_user.role_for_project(@project), @issue.tracker) if logged_in_user
|
@status_options = @issue.status.find_new_statuses_allowed_to(logged_in_user.role_for_project(@project), @issue.tracker) if logged_in_user
|
||||||
|
|
|
@ -364,6 +364,9 @@ class ProjectsController < ApplicationController
|
||||||
unless i.project_id == new_project.id
|
unless i.project_id == new_project.id
|
||||||
i.category = nil
|
i.category = nil
|
||||||
i.fixed_version = nil
|
i.fixed_version = nil
|
||||||
|
# delete issue relations
|
||||||
|
i.relations_from.clear
|
||||||
|
i.relations_to.clear
|
||||||
end
|
end
|
||||||
# move the issue
|
# move the issue
|
||||||
i.project = new_project
|
i.project = new_project
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006-2007 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# 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 IssueRelationsHelper
|
||||||
|
def collection_for_relation_type_select
|
||||||
|
values = IssueRelation::TYPES
|
||||||
|
values.keys.sort{|x,y| values[x][:order] <=> values[y][:order]}.collect{|k| [l(values[k][:name]), k]}
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,5 +1,5 @@
|
||||||
# redMine - project management software
|
# redMine - project management software
|
||||||
# Copyright (C) 2006 Jean-Philippe Lang
|
# Copyright (C) 2006-2007 Jean-Philippe Lang
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or
|
# This program is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU General Public License
|
# modify it under the terms of the GNU General Public License
|
||||||
|
@ -16,7 +16,6 @@
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class Issue < ActiveRecord::Base
|
class Issue < ActiveRecord::Base
|
||||||
|
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
belongs_to :tracker
|
belongs_to :tracker
|
||||||
belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_id'
|
belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_id'
|
||||||
|
@ -33,6 +32,9 @@ class Issue < ActiveRecord::Base
|
||||||
has_many :custom_fields, :through => :custom_values
|
has_many :custom_fields, :through => :custom_values
|
||||||
has_and_belongs_to_many :changesets, :order => "revision ASC"
|
has_and_belongs_to_many :changesets, :order => "revision ASC"
|
||||||
|
|
||||||
|
has_many :relations_from, :class_name => 'IssueRelation', :foreign_key => 'issue_from_id', :dependent => :delete_all
|
||||||
|
has_many :relations_to, :class_name => 'IssueRelation', :foreign_key => 'issue_to_id', :dependent => :delete_all
|
||||||
|
|
||||||
acts_as_watchable
|
acts_as_watchable
|
||||||
|
|
||||||
validates_presence_of :subject, :description, :priority, :tracker, :author, :status
|
validates_presence_of :subject, :description, :priority, :tracker, :author, :status
|
||||||
|
@ -52,11 +54,11 @@ class Issue < ActiveRecord::Base
|
||||||
if self.due_date and self.start_date and self.due_date < self.start_date
|
if self.due_date and self.start_date and self.due_date < self.start_date
|
||||||
errors.add :due_date, :activerecord_error_greater_than_start_date
|
errors.add :due_date, :activerecord_error_greater_than_start_date
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
#def before_create
|
if start_date && soonest_start && start_date < soonest_start
|
||||||
# build_history
|
errors.add :start_date, :activerecord_error_invalid
|
||||||
#end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def before_save
|
def before_save
|
||||||
if @current_journal
|
if @current_journal
|
||||||
|
@ -78,6 +80,10 @@ class Issue < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def after_save
|
||||||
|
relations_from.each(&:set_issue_to_dates)
|
||||||
|
end
|
||||||
|
|
||||||
def long_id
|
def long_id
|
||||||
"%05d" % self.id
|
"%05d" % self.id
|
||||||
end
|
end
|
||||||
|
@ -99,11 +105,24 @@ class Issue < ActiveRecord::Base
|
||||||
@spent_hours ||= time_entries.sum(:hours) || 0
|
@spent_hours ||= time_entries.sum(:hours) || 0
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
def relations
|
||||||
# Creates an history for the issue
|
(relations_from + relations_to).sort
|
||||||
#def build_history
|
end
|
||||||
# @history = self.histories.build
|
|
||||||
# @history.status = self.status
|
def all_dependent_issues
|
||||||
# @history.author = self.author
|
dependencies = []
|
||||||
#end
|
relations_from.each do |relation|
|
||||||
|
dependencies << relation.issue_to
|
||||||
|
dependencies += relation.issue_to.all_dependent_issues
|
||||||
|
end
|
||||||
|
dependencies
|
||||||
|
end
|
||||||
|
|
||||||
|
def duration
|
||||||
|
(start_date && due_date) ? due_date - start_date : 0
|
||||||
|
end
|
||||||
|
|
||||||
|
def soonest_start
|
||||||
|
@soonest_start ||= relations_to.collect{|relation| relation.successor_soonest_start}.compact.min
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006-2007 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# 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 IssueRelation < ActiveRecord::Base
|
||||||
|
belongs_to :issue_from, :class_name => 'Issue', :foreign_key => 'issue_from_id'
|
||||||
|
belongs_to :issue_to, :class_name => 'Issue', :foreign_key => 'issue_to_id'
|
||||||
|
|
||||||
|
TYPE_RELATES = "relates"
|
||||||
|
TYPE_DUPLICATES = "duplicates"
|
||||||
|
TYPE_BLOCKS = "blocks"
|
||||||
|
TYPE_PRECEDES = "precedes"
|
||||||
|
|
||||||
|
TYPES = { TYPE_RELATES => { :name => :label_relates_to, :sym_name => :label_relates_to, :order => 1 },
|
||||||
|
TYPE_DUPLICATES => { :name => :label_duplicates, :sym_name => :label_duplicates, :order => 2 },
|
||||||
|
TYPE_BLOCKS => { :name => :label_blocks, :sym_name => :label_blocked_by, :order => 3 },
|
||||||
|
TYPE_PRECEDES => { :name => :label_precedes, :sym_name => :label_follows, :order => 4 },
|
||||||
|
}.freeze
|
||||||
|
|
||||||
|
validates_presence_of :issue_from, :issue_to, :relation_type
|
||||||
|
validates_inclusion_of :relation_type, :in => TYPES.keys
|
||||||
|
validates_numericality_of :delay, :allow_nil => true
|
||||||
|
validates_uniqueness_of :issue_to_id, :scope => :issue_from_id
|
||||||
|
|
||||||
|
def validate
|
||||||
|
if issue_from && issue_to
|
||||||
|
errors.add :issue_to_id, :activerecord_error_invalid if issue_from_id == issue_to_id
|
||||||
|
errors.add :issue_to_id, :activerecord_error_not_same_project unless issue_from.project_id == issue_to.project_id
|
||||||
|
errors.add_to_base :activerecord_error_circular_dependency if issue_to.all_dependent_issues.include? issue_from
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def other_issue(issue)
|
||||||
|
(self.issue_from_id == issue.id) ? issue_to : issue_from
|
||||||
|
end
|
||||||
|
|
||||||
|
def label_for(issue)
|
||||||
|
TYPES[relation_type] ? TYPES[relation_type][(self.issue_from_id == issue.id) ? :name : :sym_name] : :unknow
|
||||||
|
end
|
||||||
|
|
||||||
|
def before_save
|
||||||
|
if TYPE_PRECEDES == relation_type
|
||||||
|
self.delay ||= 0
|
||||||
|
else
|
||||||
|
self.delay = nil
|
||||||
|
end
|
||||||
|
set_issue_to_dates
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_issue_to_dates
|
||||||
|
soonest_start = self.successor_soonest_start
|
||||||
|
if soonest_start && (!issue_to.start_date || issue_to.start_date < soonest_start)
|
||||||
|
issue_to.start_date, issue_to.due_date = successor_soonest_start, successor_soonest_start + issue_to.duration
|
||||||
|
issue_to.save
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def successor_soonest_start
|
||||||
|
return nil unless (TYPE_PRECEDES == self.relation_type) && (issue_from.start_date || issue_from.due_date)
|
||||||
|
(issue_from.due_date || issue_from.start_date) + 1 + delay
|
||||||
|
end
|
||||||
|
|
||||||
|
def <=>(relation)
|
||||||
|
TYPES[self.relation_type][:order] <=> TYPES[relation.relation_type][:order]
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,10 @@
|
||||||
|
<%= error_messages_for 'relation' %>
|
||||||
|
|
||||||
|
<p><%= f.select :relation_type, collection_for_relation_type_select, {}, :onchange => "setPredecessorFieldsVisibility();" %>
|
||||||
|
<%= l(:label_issue) %> #<%= f.text_field :issue_to_id, :size => 6 %>
|
||||||
|
<span id="predecessor_fields" style="display:none;">
|
||||||
|
<%= l(:field_delay) %>: <%= f.text_field :delay, :size => 3 %> <%= l(:label_day_plural) %>
|
||||||
|
</span>
|
||||||
|
<%= submit_tag l(:button_add) %></p>
|
||||||
|
|
||||||
|
<%= javascript_tag "setPredecessorFieldsVisibility();" %>
|
|
@ -0,0 +1,22 @@
|
||||||
|
<h3><%=l(:label_related_issues)%></h3>
|
||||||
|
|
||||||
|
<table style="width:100%">
|
||||||
|
<% @issue.relations.each do |relation| %>
|
||||||
|
<tr>
|
||||||
|
<td><%= l(relation.label_for(@issue)) %> <%= "(#{lwr(:actionview_datehelper_time_in_words_day, relation.delay)})" if relation.delay && relation.delay != 0 %> <%= link_to_issue relation.other_issue(@issue) %></td>
|
||||||
|
<td><%=h relation.other_issue(@issue).subject %></td>
|
||||||
|
<td><div class="square" style="background:#<%= relation.other_issue(@issue).status.html_color %>;"></div> <%= relation.other_issue(@issue).status.name %></td>
|
||||||
|
<td><%= format_date(relation.other_issue(@issue).start_date) %></td>
|
||||||
|
<td><%= format_date(relation.other_issue(@issue).due_date) %></td>
|
||||||
|
<td><%= link_to_remote image_tag('delete.png'), { :url => {:controller => 'issue_relations', :action => 'destroy', :issue_id => @issue, :id => relation},
|
||||||
|
:method => :post
|
||||||
|
}, :title => l(:label_relation_delete) %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<% if authorize_for('issue_relations', 'new') %>
|
||||||
|
<% remote_form_for(:relation, @relation, :url => {:controller => 'issue_relations', :action => 'new', :issue_id => @issue}, :method => :post) do |f| %>
|
||||||
|
<%= render :partial => 'issue_relations/form', :locals => {:f => f}%>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
|
@ -81,6 +81,12 @@ end %>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<% if authorize_for('issue_relations', 'new') || @issue.relations.any? %>
|
||||||
|
<div id="relations" class="box">
|
||||||
|
<%= render :partial => 'relations' %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<div id="history" class="box">
|
<div id="history" class="box">
|
||||||
<h3><%=l(:label_history)%>
|
<h3><%=l(:label_history)%>
|
||||||
<% if @journals_count > @journals.length %>(<%= l(:label_last_changes, @journals.length) %>)<% end %></h3>
|
<% if @journals_count > @journals.length %>(<%= l(:label_last_changes, @journals.length) %>)<% end %></h3>
|
||||||
|
|
|
@ -15,6 +15,8 @@ ActionController::Routing::Routes.draw do |map|
|
||||||
map.connect 'help/:ctrl/:page', :controller => 'help'
|
map.connect 'help/:ctrl/:page', :controller => 'help'
|
||||||
#map.connect ':controller/:action/:id/:sort_key/:sort_order'
|
#map.connect ':controller/:action/:id/:sort_key/:sort_order'
|
||||||
|
|
||||||
|
map.connect 'issues/:issue_id/relations/:action/:id', :controller => 'issue_relations'
|
||||||
|
|
||||||
# Allow downloading Web Service WSDL as a file with an extension
|
# Allow downloading Web Service WSDL as a file with an extension
|
||||||
# instead of a file named 'wsdl'
|
# instead of a file named 'wsdl'
|
||||||
map.connect ':controller/service.wsdl', :action => 'wsdl'
|
map.connect ':controller/service.wsdl', :action => 'wsdl'
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
class CreateIssueRelations < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
create_table :issue_relations do |t|
|
||||||
|
t.column :issue_from_id, :integer, :null => false
|
||||||
|
t.column :issue_to_id, :integer, :null => false
|
||||||
|
t.column :relation_type, :string, :default => "", :null => false
|
||||||
|
t.column :delay, :integer
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
drop_table :issue_relations
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,11 @@
|
||||||
|
class AddRelationsPermissions < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
Permission.create :controller => "issue_relations", :action => "new", :description => "label_relation_new", :sort => 1080, :is_public => false, :mail_option => 0, :mail_enabled => 0
|
||||||
|
Permission.create :controller => "issue_relations", :action => "destroy", :description => "label_relation_delete", :sort => 1085, :is_public => false, :mail_option => 0, :mail_enabled => 0
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
Permission.find_by_controller_and_action("issue_relations", "new").destroy
|
||||||
|
Permission.find_by_controller_and_action("issue_relations", "destroy").destroy
|
||||||
|
end
|
||||||
|
end
|
16
lang/bg.yml
16
lang/bg.yml
|
@ -33,6 +33,8 @@ activerecord_error_taken: вече съществува
|
||||||
activerecord_error_not_a_number: не е число
|
activerecord_error_not_a_number: не е число
|
||||||
activerecord_error_not_a_date: е невалидна дата
|
activerecord_error_not_a_date: е невалидна дата
|
||||||
activerecord_error_greater_than_start_date: трябва да е след началната дата
|
activerecord_error_greater_than_start_date: трябва да е след началната дата
|
||||||
|
activerecord_error_not_same_project: doesn't belong to the same project
|
||||||
|
activerecord_error_circular_dependency: This relation would create a circular dependency
|
||||||
|
|
||||||
general_fmt_age: %d yr
|
general_fmt_age: %d yr
|
||||||
general_fmt_age_plural: %d yrs
|
general_fmt_age_plural: %d yrs
|
||||||
|
@ -149,6 +151,8 @@ field_activity: Дейност
|
||||||
field_spent_on: Дата
|
field_spent_on: Дата
|
||||||
field_identifier: Идентификатор
|
field_identifier: Идентификатор
|
||||||
field_is_filter: Използва се за филтър
|
field_is_filter: Използва се за филтър
|
||||||
|
field_issue_to_id: Related issue
|
||||||
|
field_delay: Delay
|
||||||
|
|
||||||
setting_app_title: Заглавие
|
setting_app_title: Заглавие
|
||||||
setting_app_subtitle: Описание
|
setting_app_subtitle: Описание
|
||||||
|
@ -364,6 +368,18 @@ label_watched_issues: Наблюдавани задачи
|
||||||
label_related_issues: Свързани задачи
|
label_related_issues: Свързани задачи
|
||||||
label_applied_status: Промени статуса на
|
label_applied_status: Промени статуса на
|
||||||
label_loading: Зареждане...
|
label_loading: Зареждане...
|
||||||
|
label_relation_new: New relation
|
||||||
|
label_relation_delete: Delete relation
|
||||||
|
label_relates_to: related tp
|
||||||
|
label_duplicates: duplicates
|
||||||
|
label_blocks: blocks
|
||||||
|
label_blocked_by: blocked by
|
||||||
|
label_precedes: precedes
|
||||||
|
label_follows: follows
|
||||||
|
label_end_to_start: start to end
|
||||||
|
label_end_to_end: end to end
|
||||||
|
label_start_to_start: start to start
|
||||||
|
label_start_to_end: start to end
|
||||||
|
|
||||||
button_login: Вход
|
button_login: Вход
|
||||||
button_submit: Изпращане
|
button_submit: Изпращане
|
||||||
|
|
16
lang/de.yml
16
lang/de.yml
|
@ -33,6 +33,8 @@ activerecord_error_taken: ist bereits vergeben
|
||||||
activerecord_error_not_a_number: ist keine Zahl
|
activerecord_error_not_a_number: ist keine Zahl
|
||||||
activerecord_error_not_a_date: ist kein gültiges Datum
|
activerecord_error_not_a_date: ist kein gültiges Datum
|
||||||
activerecord_error_greater_than_start_date: muss größer als Anfangsdatum sein
|
activerecord_error_greater_than_start_date: muss größer als Anfangsdatum sein
|
||||||
|
activerecord_error_not_same_project: doesn't belong to the same project
|
||||||
|
activerecord_error_circular_dependency: This relation would create a circular dependency
|
||||||
|
|
||||||
general_fmt_age: %d Jahr
|
general_fmt_age: %d Jahr
|
||||||
general_fmt_age_plural: %d Jahre
|
general_fmt_age_plural: %d Jahre
|
||||||
|
@ -149,6 +151,8 @@ field_activity: Aktivität
|
||||||
field_spent_on: Datum
|
field_spent_on: Datum
|
||||||
field_identifier: Identifier
|
field_identifier: Identifier
|
||||||
field_is_filter: Used as a filter
|
field_is_filter: Used as a filter
|
||||||
|
field_issue_to_id: Related issue
|
||||||
|
field_delay: Delay
|
||||||
|
|
||||||
setting_app_title: Applikation Titel
|
setting_app_title: Applikation Titel
|
||||||
setting_app_subtitle: Applikation Untertitel
|
setting_app_subtitle: Applikation Untertitel
|
||||||
|
@ -364,6 +368,18 @@ label_watched_issues: Watched issues
|
||||||
label_related_issues: Related issues
|
label_related_issues: Related issues
|
||||||
label_applied_status: Applied status
|
label_applied_status: Applied status
|
||||||
label_loading: Loading...
|
label_loading: Loading...
|
||||||
|
label_relation_new: New relation
|
||||||
|
label_relation_delete: Delete relation
|
||||||
|
label_relates_to: related tp
|
||||||
|
label_duplicates: duplicates
|
||||||
|
label_blocks: blocks
|
||||||
|
label_blocked_by: blocked by
|
||||||
|
label_precedes: precedes
|
||||||
|
label_follows: follows
|
||||||
|
label_end_to_start: start to end
|
||||||
|
label_end_to_end: end to end
|
||||||
|
label_start_to_start: start to start
|
||||||
|
label_start_to_end: start to end
|
||||||
|
|
||||||
button_login: Einloggen
|
button_login: Einloggen
|
||||||
button_submit: OK
|
button_submit: OK
|
||||||
|
|
16
lang/en.yml
16
lang/en.yml
|
@ -33,6 +33,8 @@ activerecord_error_taken: has already been taken
|
||||||
activerecord_error_not_a_number: is not a number
|
activerecord_error_not_a_number: is not a number
|
||||||
activerecord_error_not_a_date: is not a valid date
|
activerecord_error_not_a_date: is not a valid date
|
||||||
activerecord_error_greater_than_start_date: must be greater than start date
|
activerecord_error_greater_than_start_date: must be greater than start date
|
||||||
|
activerecord_error_not_same_project: doesn't belong to the same project
|
||||||
|
activerecord_error_circular_dependency: This relation would create a circular dependency
|
||||||
|
|
||||||
general_fmt_age: %d yr
|
general_fmt_age: %d yr
|
||||||
general_fmt_age_plural: %d yrs
|
general_fmt_age_plural: %d yrs
|
||||||
|
@ -149,6 +151,8 @@ field_activity: Activity
|
||||||
field_spent_on: Date
|
field_spent_on: Date
|
||||||
field_identifier: Identifier
|
field_identifier: Identifier
|
||||||
field_is_filter: Used as a filter
|
field_is_filter: Used as a filter
|
||||||
|
field_issue_to_id: Related issue
|
||||||
|
field_delay: Delay
|
||||||
|
|
||||||
setting_app_title: Application title
|
setting_app_title: Application title
|
||||||
setting_app_subtitle: Application subtitle
|
setting_app_subtitle: Application subtitle
|
||||||
|
@ -364,6 +368,18 @@ label_watched_issues: Watched issues
|
||||||
label_related_issues: Related issues
|
label_related_issues: Related issues
|
||||||
label_applied_status: Applied status
|
label_applied_status: Applied status
|
||||||
label_loading: Loading...
|
label_loading: Loading...
|
||||||
|
label_relation_new: New relation
|
||||||
|
label_relation_delete: Delete relation
|
||||||
|
label_relates_to: related tp
|
||||||
|
label_duplicates: duplicates
|
||||||
|
label_blocks: blocks
|
||||||
|
label_blocked_by: blocked by
|
||||||
|
label_precedes: precedes
|
||||||
|
label_follows: follows
|
||||||
|
label_end_to_start: start to end
|
||||||
|
label_end_to_end: end to end
|
||||||
|
label_start_to_start: start to start
|
||||||
|
label_start_to_end: start to end
|
||||||
|
|
||||||
button_login: Login
|
button_login: Login
|
||||||
button_submit: Submit
|
button_submit: Submit
|
||||||
|
|
16
lang/es.yml
16
lang/es.yml
|
@ -33,6 +33,8 @@ activerecord_error_taken: has already been taken
|
||||||
activerecord_error_not_a_number: is not a number
|
activerecord_error_not_a_number: is not a number
|
||||||
activerecord_error_not_a_date: no es una fecha válida
|
activerecord_error_not_a_date: no es una fecha válida
|
||||||
activerecord_error_greater_than_start_date: debe ser la fecha mayor que del comienzo
|
activerecord_error_greater_than_start_date: debe ser la fecha mayor que del comienzo
|
||||||
|
activerecord_error_not_same_project: doesn't belong to the same project
|
||||||
|
activerecord_error_circular_dependency: This relation would create a circular dependency
|
||||||
|
|
||||||
general_fmt_age: %d año
|
general_fmt_age: %d año
|
||||||
general_fmt_age_plural: %d años
|
general_fmt_age_plural: %d años
|
||||||
|
@ -149,6 +151,8 @@ field_activity: Activity
|
||||||
field_spent_on: Fecha
|
field_spent_on: Fecha
|
||||||
field_identifier: Identifier
|
field_identifier: Identifier
|
||||||
field_is_filter: Used as a filter
|
field_is_filter: Used as a filter
|
||||||
|
field_issue_to_id: Related issue
|
||||||
|
field_delay: Delay
|
||||||
|
|
||||||
setting_app_title: Título del aplicación
|
setting_app_title: Título del aplicación
|
||||||
setting_app_subtitle: Subtítulo del aplicación
|
setting_app_subtitle: Subtítulo del aplicación
|
||||||
|
@ -364,6 +368,18 @@ label_watched_issues: Watched issues
|
||||||
label_related_issues: Related issues
|
label_related_issues: Related issues
|
||||||
label_applied_status: Applied status
|
label_applied_status: Applied status
|
||||||
label_loading: Loading...
|
label_loading: Loading...
|
||||||
|
label_relation_new: New relation
|
||||||
|
label_relation_delete: Delete relation
|
||||||
|
label_relates_to: related tp
|
||||||
|
label_duplicates: duplicates
|
||||||
|
label_blocks: blocks
|
||||||
|
label_blocked_by: blocked by
|
||||||
|
label_precedes: precedes
|
||||||
|
label_follows: follows
|
||||||
|
label_end_to_start: start to end
|
||||||
|
label_end_to_end: end to end
|
||||||
|
label_start_to_start: start to start
|
||||||
|
label_start_to_end: start to end
|
||||||
|
|
||||||
button_login: Conexión
|
button_login: Conexión
|
||||||
button_submit: Someter
|
button_submit: Someter
|
||||||
|
|
18
lang/fr.yml
18
lang/fr.yml
|
@ -1,4 +1,4 @@
|
||||||
_gloc_rule_default: '|n| n<=1 ? "" : "_plural" '
|
_gloc_rule_default: '|n| n==1 ? "" : "_plural" '
|
||||||
|
|
||||||
actionview_datehelper_select_day_prefix:
|
actionview_datehelper_select_day_prefix:
|
||||||
actionview_datehelper_select_month_names: Janvier,Février,Mars,Avril,Mai,Juin,Juillet,Août,Septembre,Octobre,Novembre,Décembre
|
actionview_datehelper_select_month_names: Janvier,Février,Mars,Avril,Mai,Juin,Juillet,Août,Septembre,Octobre,Novembre,Décembre
|
||||||
|
@ -33,6 +33,8 @@ activerecord_error_taken: est déjà utilisé
|
||||||
activerecord_error_not_a_number: n'est pas un nombre
|
activerecord_error_not_a_number: n'est pas un nombre
|
||||||
activerecord_error_not_a_date: n'est pas une date valide
|
activerecord_error_not_a_date: n'est pas une date valide
|
||||||
activerecord_error_greater_than_start_date: doit être postérieur à la date de début
|
activerecord_error_greater_than_start_date: doit être postérieur à la date de début
|
||||||
|
activerecord_error_not_same_project: n'appartient pas au même projet
|
||||||
|
activerecord_error_circular_dependency: Cette relation créerait une dépendance circulaire
|
||||||
|
|
||||||
general_fmt_age: %d an
|
general_fmt_age: %d an
|
||||||
general_fmt_age_plural: %d ans
|
general_fmt_age_plural: %d ans
|
||||||
|
@ -149,6 +151,8 @@ field_activity: Activité
|
||||||
field_spent_on: Date
|
field_spent_on: Date
|
||||||
field_identifier: Identifiant
|
field_identifier: Identifiant
|
||||||
field_is_filter: Utilisé comme filtre
|
field_is_filter: Utilisé comme filtre
|
||||||
|
field_issue_to_id: Demande liée
|
||||||
|
field_delay: Retard
|
||||||
|
|
||||||
setting_app_title: Titre de l'application
|
setting_app_title: Titre de l'application
|
||||||
setting_app_subtitle: Sous-titre de l'application
|
setting_app_subtitle: Sous-titre de l'application
|
||||||
|
@ -364,6 +368,18 @@ label_watched_issues: Demandes surveillées
|
||||||
label_related_issues: Demandes liées
|
label_related_issues: Demandes liées
|
||||||
label_applied_status: Statut appliqué
|
label_applied_status: Statut appliqué
|
||||||
label_loading: Chargement...
|
label_loading: Chargement...
|
||||||
|
label_relation_new: Nouvelle relation
|
||||||
|
label_relation_delete: Supprimer la relation
|
||||||
|
label_relates_to: lié à
|
||||||
|
label_duplicates: doublon de
|
||||||
|
label_blocks: bloque
|
||||||
|
label_blocked_by: bloqué par
|
||||||
|
label_precedes: précède
|
||||||
|
label_follows: suit
|
||||||
|
label_end_to_start: début à fin
|
||||||
|
label_end_to_end: fin à fin
|
||||||
|
label_start_to_start: début à début
|
||||||
|
label_start_to_end: début à fin
|
||||||
|
|
||||||
button_login: Connexion
|
button_login: Connexion
|
||||||
button_submit: Soumettre
|
button_submit: Soumettre
|
||||||
|
|
16
lang/it.yml
16
lang/it.yml
|
@ -33,6 +33,8 @@ activerecord_error_taken: e' gia' stato/a preso/a
|
||||||
activerecord_error_not_a_number: non e' un numero
|
activerecord_error_not_a_number: non e' un numero
|
||||||
activerecord_error_not_a_date: non e' una data valida
|
activerecord_error_not_a_date: non e' una data valida
|
||||||
activerecord_error_greater_than_start_date: deve essere maggiore della data di partenza
|
activerecord_error_greater_than_start_date: deve essere maggiore della data di partenza
|
||||||
|
activerecord_error_not_same_project: doesn't belong to the same project
|
||||||
|
activerecord_error_circular_dependency: This relation would create a circular dependency
|
||||||
|
|
||||||
general_fmt_age: %d yr
|
general_fmt_age: %d yr
|
||||||
general_fmt_age_plural: %d yrs
|
general_fmt_age_plural: %d yrs
|
||||||
|
@ -149,6 +151,8 @@ field_activity: Activity
|
||||||
field_spent_on: Data
|
field_spent_on: Data
|
||||||
field_identifier: Identifier
|
field_identifier: Identifier
|
||||||
field_is_filter: Used as a filter
|
field_is_filter: Used as a filter
|
||||||
|
field_issue_to_id: Related issue
|
||||||
|
field_delay: Delay
|
||||||
|
|
||||||
setting_app_title: Titolo applicazione
|
setting_app_title: Titolo applicazione
|
||||||
setting_app_subtitle: Sottotitolo applicazione
|
setting_app_subtitle: Sottotitolo applicazione
|
||||||
|
@ -364,6 +368,18 @@ label_watched_issues: Watched issues
|
||||||
label_related_issues: Related issues
|
label_related_issues: Related issues
|
||||||
label_applied_status: Applied status
|
label_applied_status: Applied status
|
||||||
label_loading: Loading...
|
label_loading: Loading...
|
||||||
|
label_relation_new: New relation
|
||||||
|
label_relation_delete: Delete relation
|
||||||
|
label_relates_to: related tp
|
||||||
|
label_duplicates: duplicates
|
||||||
|
label_blocks: blocks
|
||||||
|
label_blocked_by: blocked by
|
||||||
|
label_precedes: precedes
|
||||||
|
label_follows: follows
|
||||||
|
label_end_to_start: start to end
|
||||||
|
label_end_to_end: end to end
|
||||||
|
label_start_to_start: start to start
|
||||||
|
label_start_to_end: start to end
|
||||||
|
|
||||||
button_login: Login
|
button_login: Login
|
||||||
button_submit: Invia
|
button_submit: Invia
|
||||||
|
|
16
lang/ja.yml
16
lang/ja.yml
|
@ -34,6 +34,8 @@ activerecord_error_taken: はすでに登録されています
|
||||||
activerecord_error_not_a_number: が数字ではありません
|
activerecord_error_not_a_number: が数字ではありません
|
||||||
activerecord_error_not_a_date: の日付が間違っています
|
activerecord_error_not_a_date: の日付が間違っています
|
||||||
activerecord_error_greater_than_start_date: を開始日より後にしてください
|
activerecord_error_greater_than_start_date: を開始日より後にしてください
|
||||||
|
activerecord_error_not_same_project: doesn't belong to the same project
|
||||||
|
activerecord_error_circular_dependency: This relation would create a circular dependency
|
||||||
|
|
||||||
general_fmt_age: %d歳
|
general_fmt_age: %d歳
|
||||||
general_fmt_age_plural: %d歳
|
general_fmt_age_plural: %d歳
|
||||||
|
@ -150,6 +152,8 @@ field_activity: 活動
|
||||||
field_spent_on: 日付
|
field_spent_on: 日付
|
||||||
field_identifier: 識別子
|
field_identifier: 識別子
|
||||||
field_is_filter: Used as a filter
|
field_is_filter: Used as a filter
|
||||||
|
field_issue_to_id: Related issue
|
||||||
|
field_delay: Delay
|
||||||
|
|
||||||
setting_app_title: アプリケーションのタイトル
|
setting_app_title: アプリケーションのタイトル
|
||||||
setting_app_subtitle: アプリケーションのサブタイトル
|
setting_app_subtitle: アプリケーションのサブタイトル
|
||||||
|
@ -365,6 +369,18 @@ label_watched_issues: Watched issues
|
||||||
label_related_issues: Related issues
|
label_related_issues: Related issues
|
||||||
label_applied_status: Applied status
|
label_applied_status: Applied status
|
||||||
label_loading: Loading...
|
label_loading: Loading...
|
||||||
|
label_relation_new: New relation
|
||||||
|
label_relation_delete: Delete relation
|
||||||
|
label_relates_to: related tp
|
||||||
|
label_duplicates: duplicates
|
||||||
|
label_blocks: blocks
|
||||||
|
label_blocked_by: blocked by
|
||||||
|
label_precedes: precedes
|
||||||
|
label_follows: follows
|
||||||
|
label_end_to_start: start to end
|
||||||
|
label_end_to_end: end to end
|
||||||
|
label_start_to_start: start to start
|
||||||
|
label_start_to_end: start to end
|
||||||
|
|
||||||
button_login: ログイン
|
button_login: ログイン
|
||||||
button_submit: 変更
|
button_submit: 変更
|
||||||
|
|
16
lang/pt.yml
16
lang/pt.yml
|
@ -33,6 +33,8 @@ activerecord_error_taken: ja esta examinado
|
||||||
activerecord_error_not_a_number: nao e um numero
|
activerecord_error_not_a_number: nao e um numero
|
||||||
activerecord_error_not_a_date: nao e uma data valida
|
activerecord_error_not_a_date: nao e uma data valida
|
||||||
activerecord_error_greater_than_start_date: deve ser maior que a data inicial
|
activerecord_error_greater_than_start_date: deve ser maior que a data inicial
|
||||||
|
activerecord_error_not_same_project: doesn't belong to the same project
|
||||||
|
activerecord_error_circular_dependency: This relation would create a circular dependency
|
||||||
|
|
||||||
general_fmt_age: %d yr
|
general_fmt_age: %d yr
|
||||||
general_fmt_age_plural: %d yrs
|
general_fmt_age_plural: %d yrs
|
||||||
|
@ -149,6 +151,8 @@ field_activity: Atividade
|
||||||
field_spent_on: Data
|
field_spent_on: Data
|
||||||
field_identifier: Identificador
|
field_identifier: Identificador
|
||||||
field_is_filter: Used as a filter
|
field_is_filter: Used as a filter
|
||||||
|
field_issue_to_id: Related issue
|
||||||
|
field_delay: Delay
|
||||||
|
|
||||||
setting_app_title: Titulo da aplicacao
|
setting_app_title: Titulo da aplicacao
|
||||||
setting_app_subtitle: Sub-titulo da aplicacao
|
setting_app_subtitle: Sub-titulo da aplicacao
|
||||||
|
@ -364,6 +368,18 @@ label_watched_issues: Watched issues
|
||||||
label_related_issues: Related issues
|
label_related_issues: Related issues
|
||||||
label_applied_status: Applied status
|
label_applied_status: Applied status
|
||||||
label_loading: Loading...
|
label_loading: Loading...
|
||||||
|
label_relation_new: New relation
|
||||||
|
label_relation_delete: Delete relation
|
||||||
|
label_relates_to: related tp
|
||||||
|
label_duplicates: duplicates
|
||||||
|
label_blocks: blocks
|
||||||
|
label_blocked_by: blocked by
|
||||||
|
label_precedes: precedes
|
||||||
|
label_follows: follows
|
||||||
|
label_end_to_start: start to end
|
||||||
|
label_end_to_end: end to end
|
||||||
|
label_start_to_start: start to start
|
||||||
|
label_start_to_end: start to end
|
||||||
|
|
||||||
button_login: Login
|
button_login: Login
|
||||||
button_submit: Enviar
|
button_submit: Enviar
|
||||||
|
|
16
lang/zh.yml
16
lang/zh.yml
|
@ -36,6 +36,8 @@ activerecord_error_taken: has already been taken
|
||||||
activerecord_error_not_a_number: 不是数字
|
activerecord_error_not_a_number: 不是数字
|
||||||
activerecord_error_not_a_date: 不是有效的日期
|
activerecord_error_not_a_date: 不是有效的日期
|
||||||
activerecord_error_greater_than_start_date: 必需大于开始日期
|
activerecord_error_greater_than_start_date: 必需大于开始日期
|
||||||
|
activerecord_error_not_same_project: doesn't belong to the same project
|
||||||
|
activerecord_error_circular_dependency: This relation would create a circular dependency
|
||||||
|
|
||||||
general_fmt_age: %d yr
|
general_fmt_age: %d yr
|
||||||
general_fmt_age_plural: %d yrs
|
general_fmt_age_plural: %d yrs
|
||||||
|
@ -152,6 +154,8 @@ field_activity: 活动
|
||||||
field_spent_on: 日期
|
field_spent_on: 日期
|
||||||
field_identifier: Identifier
|
field_identifier: Identifier
|
||||||
field_is_filter: Used as a filter
|
field_is_filter: Used as a filter
|
||||||
|
field_issue_to_id: Related issue
|
||||||
|
field_delay: Delay
|
||||||
|
|
||||||
setting_app_title: 应用程序标题
|
setting_app_title: 应用程序标题
|
||||||
setting_app_subtitle: 应用程序子标题
|
setting_app_subtitle: 应用程序子标题
|
||||||
|
@ -367,6 +371,18 @@ label_watched_issues: Watched issues
|
||||||
label_related_issues: Related issues
|
label_related_issues: Related issues
|
||||||
label_applied_status: Applied status
|
label_applied_status: Applied status
|
||||||
label_loading: Loading...
|
label_loading: Loading...
|
||||||
|
label_relation_new: New relation
|
||||||
|
label_relation_delete: Delete relation
|
||||||
|
label_relates_to: related tp
|
||||||
|
label_duplicates: duplicates
|
||||||
|
label_blocks: blocks
|
||||||
|
label_blocked_by: blocked by
|
||||||
|
label_precedes: precedes
|
||||||
|
label_follows: follows
|
||||||
|
label_end_to_start: start to end
|
||||||
|
label_end_to_end: end to end
|
||||||
|
label_start_to_start: start to start
|
||||||
|
label_start_to_end: start to end
|
||||||
|
|
||||||
button_login: 登录
|
button_login: 登录
|
||||||
button_submit: 提交
|
button_submit: 提交
|
||||||
|
|
|
@ -32,6 +32,15 @@ function showTab(name) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setPredecessorFieldsVisibility() {
|
||||||
|
relationType = $('relation_relation_type');
|
||||||
|
if (relationType && relationType.value == "precedes") {
|
||||||
|
Element.show('predecessor_fields');
|
||||||
|
} else {
|
||||||
|
Element.hide('predecessor_fields');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* shows and hides ajax indicator */
|
/* shows and hides ajax indicator */
|
||||||
Ajax.Responders.register({
|
Ajax.Responders.register({
|
||||||
onCreate: function(){
|
onCreate: function(){
|
||||||
|
|
Loading…
Reference in New Issue