Commit 2f17a28d by Félicie

plugin added

parent e0fed82c
...@@ -20,8 +20,6 @@ ...@@ -20,8 +20,6 @@
/lib/redmine/scm/adapters/mercurial/redminehelper.pyo /lib/redmine/scm/adapters/mercurial/redminehelper.pyo
/log/*.log* /log/*.log*
/log/mongrel_debug /log/mongrel_debug
/plugins/*
!/plugins/README
/public/dispatch.* /public/dispatch.*
/public/plugin_assets/* /public/plugin_assets/*
/public/themes/* /public/themes/*
......
= Redmine Scrum plugin
== Main features
Take a look to https://redmine.ociotec.com/projects/redmine-plugin-scrum or
https://redmine.ociotec.com/projects/redmine-plugin-scrum/wiki for further
details.
== Access to plugin source code
If you want to access to the plugin source code repository you need to
support this plugin via https://www.patreon.com/ociotec (check tier with GIT
access).
If not you can always download a tagged version of it at:
https://redmine.ociotec.com/projects/redmine-plugin-scrum.
== Installation instructions
As any other Redmine plugin (you need GitLab access, take a look to
https://www.patreon.com/ociotec in order to gain this access):
cd <redmine-path>/plugins
git clone ssh://git@git.ociotec.com:10022/redmine/scrum.git
cd ..
bundle exec rake redmine:plugins:migrate
Finally restart your Redmine installation.
# Copyright © Emilio González Montaña
# Licence: Attribution & no derivatives
# * Attribution to the plugin web page URL should be done if you want to use it.
# https://redmine.ociotec.com/projects/redmine-plugin-scrum
# * No derivatives of this plugin (or partial) are allowed.
# Take a look to licence.txt file at plugin root folder for further details.
module ScrumHelper
include ProjectsHelper
def render_pbi_left_header(pbi)
parts = []
if Scrum::Setting.render_position_on_pbi
parts << "#{l(:field_position)}: #{pbi.position}"
end
if Scrum::Setting.render_category_on_pbi and pbi.category
parts << "#{l(:field_category)}: #{h(pbi.category.name)}"
end
if Scrum::Setting.render_version_on_pbi and pbi.fixed_version
parts << "#{l(:field_fixed_version)}: #{link_to_version(pbi.fixed_version)}"
end
render :inline => parts.join(", ")
end
def render_pbi_right_header(pbi)
parts = []
if Scrum::Setting.render_author_on_pbi
parts << authoring(pbi.created_on, pbi.author)
end
if Scrum::Setting.render_assigned_to_on_pbi and pbi.assigned_to
parts << "#{l(:field_assigned_to)}: #{link_to_user(pbi.assigned_to)}"
end
if Scrum::Setting.render_updated_on_pbi and pbi.created_on != pbi.updated_on
parts << "#{l(:label_updated_time, time_tag(pbi.updated_on))}"
end
render :inline => parts.join(", ")
end
def render_issue_icons(issue)
icons = []
if (User.current.allowed_to?(:view_time_entries, issue.project) and
((issue.is_pbi? and Scrum::Setting.render_pbis_speed) or
(issue.is_task? and Scrum::Setting.render_tasks_speed)) and
(speed = issue.speed))
if speed <= Scrum::Setting.lowest_speed
icons << render_issue_icon(LOWEST_SPEED_ICON, speed)
elsif speed <= Scrum::Setting.low_speed
icons << render_issue_icon(LOW_SPEED_ICON, speed)
elsif speed >= Scrum::Setting.high_speed
icons << render_issue_icon(HIGH_SPEED_ICON, speed)
end
end
render :inline => icons.join('\n')
end
def project_selector_tree(project, indent = '')
options = [["#{indent}#{project.name}", project.id]]
project.children.visible.each do |child_project|
options += project_selector_tree(child_project, indent + '» ')
end
return options
end
DEVIATION_ICONS = [LOWEST_SPEED_ICON = "icon-major-deviation",
LOW_SPEED_ICON = "icon-minor-deviation",
HIGH_SPEED_ICON = "icon-below-deviation"]
private
def render_issue_icon(icon, speed)
link_to("", "#", :class => "icon float-icon #{icon}",
:title => l(:label_issue_speed, :speed => speed))
end
end
# Copyright © Emilio González Montaña
# Licence: Attribution & no derivatives
# * Attribution to the plugin web page URL should be done if you want to use it.
# https://redmine.ociotec.com/projects/redmine-plugin-scrum
# * No derivatives of this plugin (or partial) are allowed.
# Take a look to licence.txt file at plugin root folder for further details.
class PendingEffort < ActiveRecord::Base
belongs_to :issue
include Redmine::SafeAttributes
safe_attributes :issue_id, :date, :effort
end
# Copyright © Emilio González Montaña
# Licence: Attribution & no derivatives
# * Attribution to the plugin web page URL should be done if you want to use it.
# https://redmine.ociotec.com/projects/redmine-plugin-scrum
# * No derivatives of this plugin (or partial) are allowed.
# Take a look to licence.txt file at plugin root folder for further details.
class SprintEffort < ActiveRecord::Base
belongs_to :user
belongs_to :sprint
end
<%= javascript_tag do %>
var <%= graph[:id] %>_data = [
<%- rows.each do |name, data| -%>
{
key: '<%= name ? name : "---" %>',
values: [<%= raw(data.collect{ |name, value| "{x: '#{name}', y: #{value}}" }.join(', ')) %>]
},
<%- end -%>
];
if (<%= graph[:id] %>_data.length > 0)
{
nv.addGraph(function() {
var chart = nv.models.multiBarChart()
.color(d3.scale.category10().range())
.reduceXTicks(false)
.showControls(false);
chart.tooltip.contentGenerator(function(data) {
return '<h3>' + data.value + ' (' + data.series.length + ')</h3><p>' + data.series[0]['key'] + ': ' + data.series[0]['value'] + '</p>';
});
chart.yAxis.tickFormat(d3.format('.2f'));
chart.yAxis.ticks(10);
if (<%= graph[:id] %>_data[0].values.length > 1)
{
chart.margin({bottom: 100});
chart.xAxis.rotateLabels(-30);
}
d3.select("#<%= graph[:id] %> svg")
.datum(<%= graph[:id] %>_data)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
}
<% end %>
<div class="scrum-content">
<div class="scrum-contextual">
<%= link_to('',
'#',
:title => "#{l(:label_fullscreen)}",
:class => 'icon icon-fullscreen',
:onclick => "$('.scrum-content').toggleClass('scrum-content-fullscreen');") %>
<%= link_to('',
'#',
:title => "#{l(:label_exit_fullscreen)}",
:class => 'icon icon-normal-screen',
:onclick => "$('.scrum-content').toggleClass('scrum-content-fullscreen');") %>
<%= javascript_tag do %>
$(document).keyup(function(event) {
if (event.keyCode == 27) {
$('.scrum-content').removeClass('scrum-content-fullscreen');
}
});
<% end %>
</div>
<%= yield %>
</div>
<div class="contextual scrum-menu">
<%- if User.current.allowed_to?(:view_product_backlog, @project) -%>
<%= link_to(l(:label_product_backlog), product_backlog_path(@product_backlog),
:class => 'icon icon-product-backlog') %>
<%- end -%>
<%- if User.current.allowed_to?(:view_product_backlog_burndown, @project) -%>
<%= link_to(l(:label_product_backlog_burndown_chart), burndown_product_backlog_path(@product_backlog),
:class => 'icon icon-burndown') %>
<%- end -%>
<%- if User.current.allowed_to?(:view_release_plan, @project) -%>
<%= link_to(l(:label_release_plan), release_plan_product_backlog_path(@product_backlog),
:class => 'icon icon-release-plan') %>
<%- end -%>
<%- if User.current.allowed_to?(:manage_sprints, @project) and @product_backlog -%>
<%= link_to('', new_project_sprint_path(@project, :back_url => url_for(params.permit!), :create_product_backlog => true),
:class => 'icon icon-add', :title => l(:button_add)) %>
<%= link_to('', edit_sprint_path(@product_backlog, :back_url => url_for(params.permit!)),
:class => 'icon icon-edit', :title => l(:button_edit)) %>
<%= link_to('', sprint_path(@product_backlog),
{:method => :delete,
:data => {:confirm => l(:text_are_you_sure)},
:class => 'icon icon-del',
:title => l(:button_delete)}) %>
<%- end -%>
<%= render_scrum_help %>
</div>
<input id="<%= element_id %>" type="text" class="editable-time" size="2" title="<%= title %>"
value="<%= number_with_precision(value, precision: 2, strip_insignificant_zeros: true) %>"
<%= 'readonly' unless editable %>/>
<%- if defined?(unit) -%>
<span <% if defined?(unit_title) %> title="<%= unit_title %>"<% end %>>
<%= unit %>
</span>
<%- end -%>
<%- if editable -%>
<%= javascript_tag do %>
$(document).ready(function() {
$("#<%= element_id %>").change(function() {
if ($.isFunction($.fn.setupAjaxIndicator)) {
setupAjaxIndicator();
}
$.ajax({
url: "<%= change_element_path %>",
type: "POST",
data: {value: $(this).val()},
error: function() {
alert("<%= l(:error_changing_value) %>");
},
complete: function() {
if ($.isFunction($.fn.hideOnLoad)) {
hideOnLoad();
}
}
});
});
});
<% end %>
<%- end -%>
<%= javascript_tag do %>
$(document).ready(function() {
<%- link = link_to(l(:label_scrum), Redmine::Plugin::registered_plugins[:scrum].url)
author = Redmine::Plugin::registered_plugins[:scrum].author
copy_right = link_to("©", "http://creativecommons.org/licenses/by-nd/4.0/")
legend = "Powered by #{link} plugin #{copy_right} 2013-2015 #{author}" -%>
$("#footer").append('<div class="bgl"><div class="bgr"><%= raw legend %></div></div>');
});
<% end %>
\ No newline at end of file
<%- if User.current.allowed_to?(:view_pending_effort, project) or
User.current.allowed_to?(:edit_pending_effort, project) -%>
<%= render :partial => "common/scrum_editable_value",
:locals => {:project => project,
:title => l(:field_pending_effort),
:element_id => "pending_effort_#{task.id}",
:value => task.pending_effort,
:unit => "h",
:unit_title => l(:field_pending_effort),
:editable => (User.current.allowed_to?(:edit_sprint_board, project) and
User.current.allowed_to?(:edit_pending_effort, project) and
task.editable?),
:change_element_path => change_pending_effort_path(task)} %>
<%- end -%>
<%= render :partial => "common/scrum_editable_value",
:locals => {:title => l(:label_remaining_story_point_plural),
:element_id => "remaining_story_points_#{pbi.id}",
:value => pbi.remaining_story_points,
:unit => l(:label_remaining_story_point_unit),
:unit_title => l(:label_remaining_story_point_plural),
:editable => (User.current.allowed_to?(:edit_issues, pbi.project) and
pbi.editable? and !read_only),
:change_element_path => change_remaining_story_points_path(pbi)} %>
<div class="contextual scrum-menu">
<%- if User.current.allowed_to?(:view_sprint_board, @project) -%>
<%= link_to(l(:label_sprint_board),
@sprint ? sprint_path(@sprint) : project_sprints_path(@project),
:class => 'icon icon-sprint-board') %>
<%- end -%>
<%- if User.current.allowed_to?(:view_sprint_burndown, @project) -%>
<%= link_to(l(:label_sprint_burndown_chart_hours),
@sprint ? burndown_sprint_path(@sprint, :type => :effort) :
burndown_index_project_sprints_path(@project, :type => :effort),
:class => 'icon icon-burndown') %>
<%= link_to(l(:label_sprint_burndown_chart_sps),
@sprint ? burndown_sprint_path(@sprint, :type => :sps) :
burndown_index_project_sprints_path(@project, :type => :sps),
:class => 'icon icon-burndown') %>
<%- end -%>
<%- if User.current.allowed_to?(:view_sprint_stats, @project) -%>
<%= link_to(l(:label_sprint_stats),
@sprint ? stats_sprint_path(@sprint) : stats_index_project_sprints_path(@project),
:class => 'icon icon-stats') %>
<%- end -%>
<%- if User.current.allowed_to?(:manage_sprints, @project) and @sprint -%>
<%= link_to('', new_project_sprint_path(@project, :back_url => url_for(params.permit!)),
:class => 'icon icon-add', :title => l(:button_add)) %>
<%= link_to('', edit_sprint_path(@sprint, :back_url => url_for(params.permit!)),
:class => 'icon icon-edit', :title => l(:button_edit)) %>
<%= link_to('', sprint_path(@sprint),
{:method => :delete,
:data => {:confirm => l(:text_are_you_sure)},
:class => 'icon icon-del',
:title => l(:button_delete)}) %>
<%= link_to('', edit_effort_sprint_path(@sprint, :back_url => url_for(params.permit!)),
:class => 'icon icon-time-add', :title => l(:label_edit_effort)) %>
<%- end -%>
<%= render_scrum_help %>
</div>
<%= render :partial => "common/scrum_editable_value",
:locals => {:title => l(:label_story_point_plural),
:element_id => "story_points_#{pbi.id}",
:value => pbi.story_points,
:unit => l(:label_story_point_unit),
:unit_title => l(:label_story_point_plural),
:editable => (User.current.allowed_to?(:edit_issues, pbi.project) and
pbi.editable? and !read_only),
:change_element_path => change_story_points_path(pbi)} %>
<table class="scrum-stats-chart-table">
<tr>
<td align="right">
<svg id="<%= graph[:id] %>"
style="width: <%= graph[:width] %>px; height: <%= graph[:height] %>px;">
</svg>
</td>
<td align="left">
<table class="scrum-stats-table">
<thead>
<tr>
<th align="left"><%= element[:label] %></th>
<th align="center"><%= unit[:plural_label] %></th>
<th align="center">%</th>
</tr>
</thead>
<tbody>
<%- rows.each do |row| -%>
<tr>
<td align="left"><%= row[element[:name]].nil? ? "---" : row[element[:name]] %></td>
<td align="center"><%= "#{row[:total].round(2)} #{unit[:label]}" %></td>
<td align="center"><%= "#{row[:percentage].round}%" %></td>
</tr>
<%- end -%>
<tr>
<td align="left" class="total"><%= l(:label_total) %></td>
<td align="center" class="total"><%= "#{total.round(2)} #{unit[:label]}" %></td>
<td align="center" class="total">100%</td>
</tr>
</tbody>
</table>
</td>
</tr>
</table>
<%= render :partial => "sprints/pie_chart",
:formats => [:js],
:locals => {:graph => graph,
:element => element,
:rows => rows} %>
<h3>Burndown en equipos multi-proyecto</h3>
<p>Si tienes varios proyectos por debajo del proyecto del equipo Scrum, y
asignas EPPs y tareas a esos proyectos hijos (estos han de tener tambi&eacute;n
el m&oacute;dulo de Scrum activo), entonces el burndown puede descomponerse en
varias series, una serie por subproyecto.</p>
<h3>Burndown on multi-project teams</h3>
<p>If you have several projects under the Scrum team project, and you assign
PBIs &amp; tasks to those child projects (they should also have Scrum module
enabled), then the burndown could be decomposed in several series, one serie
per subproject.</p>
<%= link_to(content_tag('b', l(:label_help)), '#', :class => 'icon icon-help',
:id => "helpLink_#{unique_id}") %>
<div id="helpDialog_<%= unique_id %>">
<%= render :partial => "help/#{template}", :locals => {:links => links} %>
<%= render :partial => "help/support" %>
</div>
<%= render(:partial => 'help/help', :formats => [:js],
:locals => {:unique_id => unique_id}) %>
<%= javascript_tag do %>
$("#helpDialog_<%= unique_id %>").dialog({
autoOpen: false,
modal: true,
width: 850,
height: 600,
title: "<%= l(:label_help) %>"
});
$('#helpLink_<%= unique_id %>').click(function() {
$('#helpDialog_<%= unique_id %>').dialog('open');
return(false);
});
<% end %>
<hr />
<h2>Apoya este plugin de Scrum para Redmine</h2>
<p>Si quieres que este plugin siga siendo de <b>c&oacute;digo abierto y
gratis</b>, necesito tu apoyo:</p>
<table style="width: 100%">
<tr>
<td align="center">
<a href="http://www.patreon.com/ociotec" target="_blank">
<%= image_tag('patreon-logo.png', :plugin => 'scrum') %>
</a>
</td>
<td align="center">
o
</td>
<td align="center">
<a href="https://www.paypal.me/ociotec/5" target="_blank">
<%= image_tag('paypal-logo.png', :plugin => 'scrum') %>
</a>
</td>
</tr>
</table>
<p>Saludos,<br/>
<a href="https://redmine.ociotec.com/projects/redmine-plugin-scrum"
target="_blank">Emilio Gonz&aacute;lez Monta&ntilde;a</a></p>
<hr />
<h2>Support this Redmine Scrum plugin</h2>
<p>In order to be an <b>open source &amp; free plugin</b>, I need your
support:</p>
<table style="width: 100%">
<tr>
<td align="center">
<a href="http://www.patreon.com/ociotec" target="_blank">
<%= image_tag('patreon-logo.png', :plugin => 'scrum') %>
</a>
</td>
<td align="center">
or
</td>
<td align="center">
<a href="https://www.paypal.me/ociotec/5" target="_blank">
<%= image_tag('paypal-logo.png', :plugin => 'scrum') %>
</a>
</td>
</tr>
</table>
<p>Kindly regards,<br/>
<a href="https://redmine.ociotec.com/projects/redmine-plugin-scrum"
target="_blank">Emilio Gonz&aacute;lez Monta&ntilde;a</a></p>
<h2>Ayuda del tablero de la pila de producto</h2>
<h3>EPPs</h3>
<p>Una pila de producto incluye EPPs (Elementos de la Pila de Producto).
T&iacute;picamente historias de usuario, errores y deuda t&eacute;cnica...
En <%= links[:plugin_settings] %> puedes configurar que tipos de petici&oacute;
son consideradors EPPs.</p>
<p>Los EPPs aparecen en una cola ordenada, donde la cima de la pila contiene
los EPPs que van a ser implementados primero por el equipo.</p>
<p>Muchas caracter&iacute;sticas s&oacute;lo aparecen si los permisos lo
permiten, as&iacute; que echa un vistazo a <%= links[:permissions] %> para
habilitarlos/deshabilitarlos para cada perfil.</p>
<h3>Trabajando con EPPs</h3>
<p>Los EPPs pueden crearse en este tablero usando los
<i class="icon icon-add">enlaces</i> al principio del tablero (si quieres crear
EPPs en la cima de la pila) or al final del tablero (si quieres crear EPPs al
final de la pila).</p>
<p>Una vez que tienes EPPs en la pila de producto, puedes arrastralos en
vertical para cambiar su orden (as&iacute; el equipo empezar&aacute; con estos
primero). Puesdes moverlos al inicio/final de la pila usando
<i class="icon icon-move-top">el icono de mover arriba</i> y
<i class="icon icon-move-bottom">el icono de mover abajo</i>.</p>
<p>En el post-it del EPP ver&aacute;s sus atributos (para habilitar
m&aacute;s/menos atributos echa un vistazo a <%= links[:plugin_settings] %>).
Puedes editar los haciendo click en <i class="icon icon-edit">el icono del
lapicero</i>.</p>
<p>Los EPPs se estiman en puntos de historia (PHs), puedes editar su valor
directamente haciendo click en el valor de PHs y escribiendo un nuevo valor
(luego pulsa ENTER o TAB). Si los puntos de historia pendientes est&aacute;
habilidato (en <%= links[:plugin_settings] %>) entonces ver&aacute;s que
este campo tambi&eacute;n est&aacute;, tambi&eacute;n ser&aacute; editable.</p>
<h3>La pila de producto en equipos multi-proyecto</h3>
<p>Si tienes varios proyectos bajo el proyecto del equipo Scrum, y asignas
EPPs y tareas a esos proyectos hijos (deben tener tambi&eacute;n el
m&oacute;dulo Scrum activo), entonces la pila de producto puede ser filtrada
por subproyecto. Si filtras la pila de producto, la ordenación de EPPs no
estará permitida.</p>
<h2>Product backlog board help</h2>
<h3>PBIs</h3>
<p>A product backlog includes PBIs (Product Backlog Items). Typically they
represent user stories, bugs, technical debts... Under
<%= links[:plugin_settings] %> you can configure which issue trackers are
considered PBIs.</p>
<p>PBIs are listed in a sorted queue, where the top of the queue contains the
PBIs that are going to be implemented by the team first.</p>
<p>A lot of the described features are enabled only with permissions, so take a
look to <%= links[:permissions] %> to enable/disable permissions for each
role.</p>
<h3>Working with PBIs</h3>
<p>PBIs can be created in this board using the
<i class="icon icon-add">links</i> at the begin of the board (if you want to
create PBIs at the top of the queue) or at the end of the board (if you want
to create PBIs at the bottom of the queue).</p>
<p>Once you have PBIs on the product backlog, you can dragged in vertical
to change their order (so the team will start with the ones before).
You can also move them to the top/bottom of the queue using
<i class="icon icon-move-top">move to top icon</i> and
<i class="icon icon-move-bottom">move to bottom icon</i>.</p>
<p>In the PBI post-it you will see its attributes (to enable more/less
attributes take a look to <%= links[:plugin_settings] %>). You can edit them
clicking on the <i class="icon icon-edit">pencil icon</i>.</p>
<p>PBIs are estimated in story points (SPs), you can edit directly this value
clicking on the SPs value and typing a new value (then press ENTER or TAB).
If remaining story points is enabled (under <%= links[:plugin_settings] %>)
then you will see that field also in the post-it, it's also editable.</p>
<h3>Product backlog on multi-project teams</h3>
<p>If you have several projects under the Scrum team project, and you assign
PBIs &amp; tasks to those child projects (they should also have Scrum module
enabled), then the product backlog could be filtered by subproject. If you
filter the product backlog, sorting PBIs will not be permitted.</p>
<h2>Ayuda del burndown de la pila de producto</h2>
<p>El burndown de la pila de producto muestra el progreso del equipo en puntos
de historia a lo largo de los Sprints y la preducci&oacute;n del progreso del
equipo de los futuros Sprints.</p>
<h3>Entendiendo el burndown</h3>
<p>La l&iacute;nea (o l&iacute;neas en equipos multi-proyecto) representa los
PHs pendientes de los EPPs del Sprint d&iacute;a a d&iacute;a (no tiene que
ver de ning&uacute;n modo con el campo de PHs del EPP, sin embargo normalmente
el primer valor de los PHs pendientes del EPP es igual a los PHs).</p>
<%= render :partial => 'help/product_backlog/velocity_modes',
:locals => {:links => links} %>
<%= render :partial => 'help/burndown_multi_project',
:locals => {:links => links} %>
<h2>Product backlog burndown help</h2>
<p>Product backlog burndown shows the progress of the team in story points
along the Sprints and the prediction based on team velocity of future
Sprints.</p>
<h3>Understanding the burndown</h3>
<p>The line (or lines in multi-project teams) represent the pending
SPs of Sprint PBIs day by day (this is not related in any way with the
PBI SPs field, nevertheless first PBI pending SPs value uses to be equal to the
SPs field).</p>
<%= render :partial => 'help/product_backlog/velocity_modes',
:locals => {:links => links} %>
<%= render :partial => 'help/burndown_multi_project',
:locals => {:links => links} %>
<h2>Ayuda de la pila de producto</h2>
<p>C&oacute;mo usar el formaulario de la pila de producto:</p>
<ul>
<li><b>Nombre:</b> normalmente algo como <i>Pila de producto</i>.</li>
<li><b>Descripci&oacute;n:</b> puedes poner aqu&iacute; cualquier
informaci&oacute;n relevante del equipo.</li>
<li><b>Compartido:</b> si compartes la pila de producto podr&aacute;s
asignar EPPs de los proyectos hijos a la pila de producto, esto permite
el uso de multiples proyectos.</li>
</ul>
<h2>Product backlog help</h2>
<p>How to use the product backlog form:</p>
<ul>
<li><b>Name:</b> usually something like <i>Product backlog</i>.</li>
<li><b>Description:</b> you can put here any relevant information for the
team.</li>
<li><b>Shared:</b> if you share a product backlog you will be able to assign
PBIs of child projects to this product backlog, this will enable
multi-project usage.</li>
</ul>
<h2>Ayuda del plan de liberaciones</h2>
<p>En el plan de liberaciones ver&aacute;s una especie de pila de producto
pero centrada en dar informaci&oacute;n de cuando est&aacute; previsto que
cada versi&oacute;n sea liberada.</p>
<p>En esta vista no se pueden editar u ordenar EPPs.</p>
<%= render :partial => 'help/product_backlog/velocity_modes',
:locals => {:links => links} %>
<h3>Plan de liberaciones en equipos multi-proyecto</h3>
<p>Si tienes varios proyectos bajo el proyecto del equipo Scrum, y asignas
EPPs a esos proyectos hijos (deben tener tambi&eacute;n el
m&oacute;dulo Scrum activo), entonces el plan de liberaciones puede ser filtrado
por subproyecto.</p>
<h2>Release plan help</h2>
<p>In the release plan you will see a kind of product backlog but focused on
giving information to plan when each version is going to be released.</p>
<p>In this view you cannot edit or sort PBIs.</p>
<%= render :partial => 'help/product_backlog/velocity_modes',
:locals => {:links => links} %>
<h3>Release plan on multi-project teams</h3>
<p>If you have several projects under the Scrum team project, and you assign
PBIs &amp; tasks to those child projects (they should also have Scrum module
enabled), then the release plan could be filtered by subproject.</p>
<h3>Trabajando con predicciones</h3>
<p>Este plugin tiene tres modos de predicci&oacute;n:</p>
<ul>
<li><b>Modo normal</b> (<i>Usa todos los EPPs de los &uacute;ltimos N Sprints
para calcular la velocidad</i>): la velocidad del equipo es calculada usando
la media de los PHs de los EPPs cerrados en los &uacute;ltimos N Sprints.</li>
<li><b>Modo planificaci&oacute;n</b> (<i>s&oacute;lo los planificados</i>):
igual que el modo normal pero s&oacute;lo los EPPs planificados
contar&aacute;n en la velocidad del equipo. Los planificados son aqueyos
EPPs que se crearon antes de que el Sprint empezara, los otros se consideran
interrupciones del Sprint, as&iacute; que no incrementar&aacute;n la
velocidad del equipo.</li>
<li><b>Modo personalizado</b>: sirve para jugar con diferentes valores de
velocidad.</li>
</ul>
<h3>Working with predictions</h3>
<p>This plugin has three predictions modes:</p>
<ul>
<li><b>Regular mode</b> (<i>Use all PBIs from last N Sprints to calculate the
velocity</i>): team velocity is calculated using the media of the closed PBIs
SPs in the last N Sprints.</li>
<li><b>Scheduled mode</b> (<i>Only scheduled ones</i>): same as regular mode
but only the scheduled PBIs will count in the team velocity. Scheduled ones
are PBIs created before the Sprint starts, others are considered as Sprint
interruptions, so they will not increase the team velocity.</li>
<li><b>Custom mode</b>: just play with custom velocity values.</li>
</ul>
<h2>Ayuda de la configuraci&oacute;n de proyecto de pilas de producto</h2>
<p>En esta vista encontrar&aacute;s la lista de pilas de producto, normalmente
crear&aacute;s una sola pila de producto, pero se permite crear m&aacute;s de
una (por ejemplo para EPPs no claros, o para deuda t&eacute;cnica si prefieres
separarlos de otras caracter&iacute;sticas...).</p>
<p>No puedes borrar una pila de producto si tiene peticiones asignadas.
A veces es dificil darse cuenta porque el tablero de la pila de producto
s&oacute;lo muestra las peticiones EPP en unos estados. As&iacute; que si el
plugin puede indicar que la pila no puede ser borrada, ve a la pesta&ntilde;a
de peticiones y crea un filtro por cualquier tipo de petici&oacute;n, en
cualquier estado asignado a esta pila de producto (mostrado como campo
<i>Sprint</i>).</p>
<h2>Product backlogs project settings help</h2>
<p>In this view you will find the list of product backlogs, usually you'll
create only one product backlog, but it's OK if you create more than one
(i.e. for not clear PBIs, or for technical debt if you prefer to separate them
from regular features...).</p>
<p>You cannot delete a product backlog if it has any issue assigned to it.
This sometimes is difficult to detect because in the product backlog board only
PBI issues in a configured state are rendered. So if the plugin tells you that
the product backlog cannot be deleted, go to issues tab &amp; create a filter
by any tracker, in any state assigned to this product backlog (rendered as
<i>Sprint</i> field).</p>
<h2>Ayuda de la configuraci&oacute;n de proyecto de Sprints</h2>
<p>En esta vista encontrar&aacute;s la lista de Sprints, los Sprints se
ordenan por las fechas de inicio y fin para que sea m&aacute;s f&aacute;cil
su seguimiento</p>
<p>No puedes borrar un Sprint si tiene peticiones asignadas.
A veces es dificil darse cuenta porque el tablero del Sprint
s&oacute;lo muestra las peticiones EPP en unos estados. As&iacute; que si el
plugin puede indicar que el Sprint no puede ser borrado, ve a la pesta&ntilde;a
de peticiones y crea un filtro por cualquier tipo de petici&oacute;n, en
cualquier estado asignado a este Sprint.</p>
<h2>Sprints project settings help</h2>
<p>In this view you will find the list of Sprints, Sprints are sorted by
begin &amp; end dates in order to make easier the follow up.</p>
<p>You cannot delete an Sprint if it has any issue assigned to it.
This sometimes is difficult to detect because in the Sprint board only
PBI issues in a configured state are rendered. So if the plugin tells you that
the Sprint cannot be deleted, go to issues tab &amp; create a filter
by any tracker, in any state assigned to this Sprint.</p>
<h2>Ayuda de la configuraci&oacute;n del plugin Scrum</h2>
<p>Este plugin es altamente configurable, normalmente los valores por defecto
est&aacute;n bien, pero algunos deben ser configurados antes de empezar a usar
este plugin.</p>
<h3>Pasos obligatorios/m&iacute;nimos</h3>
<p>Normalmente configurar este plugin implica ejecutar varios pasos en la
secci&oacute;n de administraci&oacute;n antes de empezar a configura el plugin
en s&iacute; mismo:</p>
<ol>
<li>Habilitar los permisos del plugin en <%= links[:permissions] %>.</li>
<li>Crear tipos de petici&oacute;n para los EPPs. Normalmente un tipo para
historias de usuario, otro para errores y otro para deuda t&eacute;cnica.
Cuanto menos mejor, as&iacute; que habilita solo los campos: categor&iacute;a,
versi&oacute;n prevista y descripci&oacute;n.</li>
<li>Crea un tipo de petici&oacute;n para tareas, normalmente con un tipo es
suficiente, pero est&aacute; bien si quieres crear varios. De nuevo menos es
m&aacute;s, as&iacute; que habilita s&oacute;lo estos campos: asignado,
petici&oacute;n padre, tiempo estimado y descripci&oacute;n.</li>
<li>Crea un campo de petici&oacute;n personalizado para los puntos de
historia: debe de ser un valor num&eacute;rico, entero o de punto flotante,
pero es mejor si usas una lista de valores similar a una secuencia de
Fibonacci como: 0, 0.5, 1, 2, 3, 5, 8, 13, 20, 40, 100.</li>
</ol>
<h3>Configurando los ajustes del plugin</h3>
<p>Casi todos los valores son auto explicativos o incluyen descripciones para
entenderlos.</p>
<p>Varios valores son selecciones de m&uacute;ltiples valores, simplemente
presiona CTRL (o CMD en MacOS) para seleccionar varios valores.</p>
<p>Si no entiendes el prop&oacute;sito de algo y quieres probarlo, simplemente
cambia un &uacute;nico valor y comprueba qu&eacute; ha cambiado en la vista
relacionada.</p>
<p><a href="https://redmine.ociotec.com/projects/redmine-plugin-scrum/boards/11"
target="_blank">El foro de soporte del plugin</a> es tambi&eacute;n un buen
lugar para preguntar si lo necesitas.</p>
<h3>Pasos opcionales</h3>
<ol>
<li>Crear un campo personalizado para peticiones para indicar si el EPP o
tarea est&aacute; bloquedo.</li>
<li>Crear un campo personalizado booleano para peticiones para indicar si
el EPP se permite estar solo en el tamblero del Sprint, es decir sin tareas
hijas.</li>
</ol>
<h2>Scrum plugin settings help</h2>
<p>This plugin is highly configurable, usually default values are OK, but
some of them must be configured before start using the plugin.</p>
<h3>Mandatory/minimum steps</h3>
<p>Usually configuring this plugin implies doing several steps in the admin
section before start configuring the plugin itself:</p>
<ol>
<li>Enable Scrum plugin permissions under <%= links[:permissions] %>.</li>
<li>Create trackers for PBIs. Usually one tracker for user stories, other
for bugs and another for technical debts. The less the better, so just enable
fields as: category, target version &amp; description.</li>
<li>Create a tracker for tasks, usually only one tracker is enough, but it's
OK if you create several. Again the less the better, so just enable fields:
assignee, parent issue, estimated time &amp; description.</li>
<li>Create issue custom field for story points: it must be a numeric value,
integer or float, but it's better if you use a list of values type with
a kind of Fibonacci values as: 0, 0.5, 1, 2, 3, 5, 8, 13, 20, 40, 100.</li>
</ol>
<h3>Configuring plugin settings</h3>
<p>Almost all values are auto explanatory or include descriptions to understand
them.</p>
<p>Several values are multiple value selections, just press CTRL (or CMD on
MacOS) to select several values.</p>
<p>If you don't understand the purpose of something and you want to try it out,
just change that single value and check what changed in the related view.</p>
<p><a href="https://redmine.ociotec.com/projects/redmine-plugin-scrum/boards/11"
target="_blank">Plugin support forum</a> it's also a good place to ask if you
need it.</p>
<h3>Optional steps</h3>
<ol>
<li>Create an issue custom boolean value to set that a PBI/task is
blocked.</li>
<li>Create an issue custom boolean value to set that a PBI is
allowed to be in the Sprint board alone, that means without child tasks.</li>
</ol>
<h2>Ayuda de las estad&iacute;sticas de Scrum</h2>
<p>Las estad&iacute;sticas de Scrum muestran informaci&oacute;n de diversos
aspectos del proyecto a nivel global, no s&oacute;lo relativas a un s&oacute;lo
Sprint.</p>
<p>Aqu&iacute; encontrar&aacute;s ayuda para responder a preguntas como:</p>
<ul>
<li>La velocidad del equipo a lo largo de los Sprints.</li>
<li>Cu&aacute;ntas horas son un punto de historia a lo largo de los
Sprints.</li>
<li>Cu&aacute;ntos PHs gastamos en cada categor&iacute;a del proyecto o por
tipo de EPP.</li>
<li>Cu&aacute;nto tiempo gastamos en cada actividad del proyecto.</li>
</ul>
<h2>Scrum stats help</h2>
<p>Scrum stats shows information about different aspects of the global project,
not only regarding a single Sprint.</p>
<p>Here you will find help to answer questions like:</p>
<ul>
<li>Team velocity along the Sprints.</li>
<li>How many hours mean an story point along the Sprints.</li>
<li>How much SPs do we spend in each project issue category or PBI type.</li>
<li>How much time do we spent by project activity.</li>
</ul>
<h2>Ayuda del tablero del Sprint</h2>
<h3>EPPs y tareas</h3>
<p>Un tablero del Sprint incluye EPPs y tareas. EPPs (o Elementos de la Pila
de Producto) son normalmente historias de usuario, errores o deuda
t&eacute;cnica... y estos se descomponen en tareas hijas. En
<%= links[:plugin_settings] %> puedes configurar qu&eacute; tipos de peticiones
son considerados EPPs y cuales son considerados tareas.</p>
<p>Los EPPs se encuentran en la parte izquierda del tablero, las tareas en las
columnas a la derecha. Hay una columna por cada posible estado de las tereas
(estos estados son configurables en <%= links[:plugin_settings] %>).</p>
<p>Muchas caracter&iacute;sticas aqu&iacute; descritas est&aacute;n s&oacute;lo
habilitadas con los permisos apropiados, as&iacute; que echa un vistazo a
<%= links[:permissions] %> para habilitarlos/deshabilitarlos para cada
perfil.</p>
<h3>Trabajando con EPPs</h3>
<p>Los EPPs pueden crearse en este tablero con los
<i class="icon icon-add">enlaces</i> al final del tablero o movi&eacute;ndolos
desde la vista de la pila de producto.</p>
<p>Una vez que tienes EPPs en el tablero del Sprint, puedes arrastrarlos en
vertical para cambiar su orden (as&iacute; el equipo empezar&aacute; antes por
los que est&eacute;n al principio). En los post-its de los EPPs ver&aacute;s
sus atributos (para habilitar m&aacute;s/menos atributos echa un vistazo a
<%= links[:plugin_settings] %>). Puedes editarlos haciendo click en el
<i class="icon icon-edit">icono del lapicero</i>.</p>
<p>Los EPPs se estima en puntos de historia (PHs), puedes editar esta valor
directamente haciendo click en el valor de PHs y escribiendo un nuevo valor
(luego pulsa ENTER o TAB). Si el ajuste de usar puntos de historia restante
est&aacute; habilitado (en <%= links[:plugin_settings] %>) entonces ver&aacute;s
que el campo aparece tambi&eacute;n en el post-it, tambi&eacute;n ser&aacute;
editable; este valor se usa para calcular un burndown por PHs preciso,
as&iacute; que no olvideis actualizarlo d&iaacute;a a d&iacute;a (antes de
salir de la oficina).</p>
<h3>Trabajando con tareas</h3>
<p>Las tareas son asuntos t&eacute;cnicos a realizar para completar un EPP.
Pueden ser creadas directamente haciendo click en el
<i class="icon icon-add">icono</i> en los post-its de EPP (o creando una
petici&oacute;n hija en la ficha del EPP).</p>
<p>Para cambiar el estado de la tarea, simplemente arr&aacute;strala en
direcci&oacute;n horizontal (o ed&iacute;tala y cambia su estado). Ten en
cuenta tu flujo de trabajo del tipo de petici&oacute;n, porque puede que algunos
movimientos esten prohibidos para algunos perdiles (pregunta a tus
administradores). Hay varias acciones autom&aacute;ticas implicadas cuando
mueves post-its (echa un vistazo a <%= links[:plugin_settings] %> para
habilitarlas/deshabilitarlas):</p>
<ul>
<li>Cuando mueves la primera tarea del estado nuevo (primer estado de los
tipos de peticiones en los ajustes de administraci&oacute;n) a cualquier otro
estado, el plugin cambia el estado del EPP padre a en progreso (segundo
estado).</li>
<li>Cuando cambias el estado de una tarea a cualquiera menos nuevo, y esta
no tiene asignado, el plugin la asigna al usuario actual; si la tarea es
cambiada al estado nuevo, el campo asignado es vaciado.</li>
<li>Cuando la &uacute;ltima tarea es completada, el esfuerzo pendiente se
establece a cero y el EPP padre es cambiado a un estado configurable (por
ejemplo resuelto).</li>
</ul>
<p>Las tareas son estimadas en horas, usando el campo esfuerzo estimaod, este
tambi&eacute;n puede editarse en el post-it. Para calcular el burndown del
Sprint por horas es necesario que tambi&eacute;n se rellene el campo de esfuerzo
pendiente (d&iacute;a a d&iacute;a). Puedes imputar tiempo en las tareas
haciendo click en el <i class="icon icon-time-add">icono de imputar
tiempo</i>.</p>
<p>Tan pronto como asignes una tarea o imputes tiempo en ella, un mini-post-it
naranja (el color es configurable en <%= links[:plugin_settings] %>) es
a&ntilde;adido a la tarea, y un mini-post-it verde en el caso de que imputes
tiempo de revisi&oacute;n (la actividad para el tiempo de revisi&oacute;n es
configurada en <%= links[:plugin_settings] %>). Esto permite hacer seguimiento
de que se est&aacute; haciendo m&aacute;s f&aacute;cilmente.</p>
<h2>Sprint board help</h2>
<h3>PBIs &amp; tasks</h3>
<p>An Sprint board includes PBIs &amp; tasks. PBIs (or Product Backlog Items)
are typically user stories, bugs, technical debts... and they are composed of
child tasks. Under <%= links[:plugin_settings] %> you can configure which issue
trackers are considered PBIs and which are considered tasks.</p>
<p>PBIs are located on the left part of the board, tasks on the right columns.
There is a column per possible task status (these statuses are configurable
under <%= links[:plugin_settings] %>).</p>
<p>A lot of the described features are enabled only with permissions, so take a
look to <%= links[:permissions] %> to enable/disable permissions for each
role.</p>
<h3>Working with PBIs</h3>
<p>PBIs can be created in this board with the <i class="icon icon-add">links</i>
at the end of the board or moved from the product backlog view.</p>
<p>Once you have PBIs on the Sprint board, you can dragged in vertical to
change their order (so the team will start with the ones at the beginning).
In the PBI post-it you will see its attributes (to enable more/less attributes
take a look to <%= links[:plugin_settings] %>). You can edit them clicking on
the <i class="icon icon-edit">pencil icon</i>.</p>
<p>PBIs are estimated in story points (SPs), you can edit directly this value
clicking on the SPs value and typing a new value (then press ENTER or TAB).
If use remaining story points is enabled (under <%= links[:plugin_settings] %>)
then you will see that field also in the post-it, it's also editable; this
is used to calculate a precise Sprint burndown by SPs, so don't forget to
update it day by day (before leaving the office).</p>
<h3>Working with tasks</h3>
<p>Tasks are technical things to be done in order to complete a PBI. They can
be created directly clicking on the <i class="icon icon-add">icon</i> in the
PBI post-its (or creating new child issues from the PBI issue form).</p>
<p>To change task status, just drag &amp; drop in horizontal direction (or edit
&amp; change its status). Take care of your tracker work flow, because maybe
some movements are forbidden for some roles (ask your administrators).
There are a few automatic actions involved when you move task post-its
(take a look to <%= links[:plugin_settings] %> to enable/configure them):</p>
<ul>
<li>When you move the first task from new (first tracker state defined
in the admin settings) to any other state, the plugin change parent PBI
status to in progress (the second state).</li>
<li>When you change a task status to anything but new, and it has not
assignee, the plugin set it to current user; if the task is changed to new
status, the assignee is removed.</li>
<li>When the last task is closed, the remaining effort is set to zero and the
parent PBI is changed to a configurable status (i.e. resolved).</li>
</ul>
<p>Tasks are estimated in hours, using the estimated effort field, this is also
editable in the post-it. In order to calculate an Sprint burndown by hours is
also necessary to fill the remaining effort field (day by day). You can log
time to the tasks clicking on
<i class="icon icon-time-add">log entry icon</i>.</p>
<p>As soon as you assign a task or log time into it, an orange mini-post-it
(color is configurable under <%= links[:plugin_settings] %>) is attached to the
task, and a green one in case you log review time (review time has also to be
configured under <%= links[:plugin_settings] %>). This allow to follow up how
is doing what easily.</p>
<h2>Ayuda para el burndown por esfuerzo del Sprint</h2>
<p>El burndown por esfuerzo del Sprint muestra el progreso del equipo comparando
el esfuerzo estimado con el esfuerzo pendiente real. Todos los esfuerzos son
medidos en horas.</p>
<h3>Rellenado el esfuerzo estimado</h3>
<p>Cuando el Sprint comienza el equipo configura el esfuerzo estimado en
<%= links[:sprint_effort] %>, para rellenar esta tabla (una fila por miembro
del equipo, una columna por d&iacute;a del Sprint) debes seguir las siguientes
reglas:</p>
<ul>
<li>S&oacute;lo los miembros activos (aquellos que van a trabar en tareas)
deben rellenarse.</li>
<li>No pongas nada cuando un miembro del equipo no est&eacute; disponible
(por ejemplo en fin de semana o festivos). Si todo el mundo no tiene esfuerzo
un d&iacute;a, entonces ese d&iacute;a no ser&aacute; mostrado.</li>
<li>Es v&aacute;lido poner 0.0 en una celda si quieres reflejar que el
miembro del equipo trabaja en el Sprint, pero quiz&aacute;s s&oacute;lo para
asistir a reuniones.</li>
<li>Se acepta poner decimales, pero no inviertas mucho tiempo pensando acerca
de cuanto tiempo pner aqu&iacute;, esto es Scrum, pon un n&uacute;mero y
val&oacute;ralo en la siguiente retrospectiva del Sprint ;)</li>
</ul>
<h3>Imputando esfuerzo d&iacute;a a d&iacute;a</h3>
<p>Cada miembro del equipo debe imputar las horas d&iacute;a a d&iacute;a.
Esto se debe a que el plugin registra en que d&iacute;a se hace cada esfuerzo,
no olvides imputar las horas cada d&iacute;a si quieres un gr&aacute;fico de
burndown preciso.</p>
<h3>Entendiendo el burndown por esfuerzo</h3>
<p>La l&iacute;nea de esfuerzo estimado representa la tabla que el equipo
rellen&oacute; antes. En cambio, la l&iacute;nea de esfuerzo pendiente (o
l&iacute;neas en equipos multi-proyecto) representa el esfuerzo pendiente de
las tareas del Sprint d&iacute;a a d&iacute;a (no tiene nada que ver con el
campo de esfuerzo estimado de las tareas).</p>
<%= render :partial => 'help/burndown_multi_project',
:locals => {:links => links} %>
<h2>Sprint burndown by effort help</h2>
<p>Sprint burndown by effort shows the progress of the team comparing the
estimated effort with the actual pending effort. All these efforts are measured
in hours.</p>
<h3>Filling the estimated effort</h3>
<p>When the Sprint starts the team must configure the estimated effort under
<%= links[:sprint_effort] %>, to fill this table (one row per team member,
one column per Sprint day) you must follow these rules:</p>
<ul>
<li>Only active members (those who are going to work on tasks) must be
filled.</li>
<li>Don't fill anything when a team member is not available (i.e. weekend
days or holidays). If everybody has no effort one day, that day will not be
rendered.</li>
<li>It's valid to put 0.0 in a cell if you want to reflect that the team
member is working on the Sprint, but maybe only to attend to meetings.</li>
<li>It's OK to put decimals, but don't invest too much time thinking about
how much time to put here, this is Scrum, put a number and evaluate it in
the next Sprint retrospective ;)</li>
</ul>
<h3>Logging effort day by day</h3>
<p>Every team member must log the time day by day. Due the fact the plugin
records every effort on the day is logged, don't forget to log the time every
day if you want an accurate burndown graph.</p>
<h3>Understanding the burndown by effort</h3>
<p>Estimated effort line it's just the table that the team filled before.
On the other hand, pending effort line (or lines in multi-project teams)
represents the pending effort of Sprint tasks day by day (this is not related
in any way with the estimated effort tasks field).</p>
<%= render :partial => 'help/burndown_multi_project',
:locals => {:links => links} %>
<h2>Ayuda del burndown por PHs del Sprint</h2>
<p>El burndown por PHs del Sprint muestra el progreso del equipo en puntos de
historia. El valor puede ser imputado por los usuarios de manera precisa
(v&iacute;a el campo de puntos de historia pendientes, que debe ser habilitado
en <%= links[:plugin_settings] %>) o de manera menos precisa cuando cada EPP
es completado.</p>
<h3>Imputando PHs pendientes d&iacute;a a d&iacute;a</h3>
<p>Cada miembro del equipo debe imputar los PHs pendientes d&iacute;a a
d&iaute;a en los EPPs. Debido al hecho de que el plugin guarda en que
d&iacute;a se registra cada valor de PHs pendientes, no olvides imputar dicho
valor si quieres que el gr&aacute;fico del burndown sea preciso.</p>
<h3>Entendiendo el burndown por PHs</h3>
<p>La l&iacute;nea de PHs pendientes (o l&iacute;neas para equipos
multi-proyecto) representa los PHs pendientes de los EPPs del Sprint d&iacute;a
a d&iacute;a (esto no est&aacute; relacionado de ninguna manera con el campo
de PHs del EPP, sin embargo normalemente los PHs pendientes del EPP suelen ser
iguales al campo de PHs cuando se empieza a trabajar en el EPP).</p>
<%= render :partial => 'help/burndown_multi_project',
:locals => {:links => links} %>
<h2>Sprint burndown by SPs help</h2>
<p>Sprint burndown by SPs shows the progress of the team in story points. The
valor can accurately logged by users (via pending story points field, it must
be enabled under <%= links[:plugin_settings] %>) or with less precision when
each PBI is closed.</p>
<h3>Logging pending SPs day by day</h3>
<p>Every team member must log the pending SPs day by day in the PBIs. Due the
fact the plugin records every pending SPs on the day is logged, don't forget
to log that value every day if you want an accurate burndown graph.</p>
<h3>Understanding the burndown by SPs</h3>
<p>Pending SPs line (or lines in multi-project teams) represents the pending
SPs of Sprint PBIs day by day (this is not related in any way with the
PBI SPs field, nevertheless usually PBI pending SPs use to be equal to the
SPs field when we start working on the PBI).</p>
<%= render :partial => 'help/burndown_multi_project',
:locals => {:links => links} %>
<h2>Ayuda de editar esfuerzo estimado del Sprint</h2>
<p>Cada miembro del equipo (trabajando y haciendo tareas) debe estimar el tiempo
que va a poder dedicar al proyecto cada d&iacute;a del Sprint.</p>
<p>Deja en blanco las celdas si no se prev&eacute; trabajo ese d&iacute; (por
ejmplo en fin de semana) para evitar que el burndown por esfuerzo muestre dicho
d&iacute;a.</p>
<p>Los decimales o incluso 0.0 son valores permitidos.</p>
<h2>Sprint edit estimated effort help</h2>
<p>For each team member (working &amp; doing tasks) should estimate the time
that is going to allocate for the project each day of the Sprint.</p>
<p>Left blank the cell if no work is going to be done in a day (i.e. weekend
days) to avoid burndown by effort to render that day.</p>
<p>Decimals or even 0.0 are allowed values.</p>
<h2>Ayuda del Sprint</h2>
<p>C&oacute;mo usar el formulario del Sprint:</p>
<ul>
<li><b>Nombre:</b> normalmente algo como <i>Sprint 14</i>.</li>
<li><b>Descripci&oacute;n:</b> puedes poner aqu&iacute; el objetivo del Sprint
o cualquier otra informaci&oacute;n relevante para el equipo.</li>
<li><b>Fechas de inicio y fin:</b> estas fechas se usan para calcular cosas
como los burndowns o la tabla de esfuerzo estimado.</li>
<li><b>Estado:</b> un Sprint puede estar abierto o cerrado, los EPPs
s&oacute;lo pueden ser asignados a Sprints abiertos.</li>
<li><b>Compartido:</b> si compartes un Sprint se podr&aacute; asignar EPPs de
proyectos hijos a este Sprint, esto habilita el uso de multi-proyecto.</li>
</ul>
<h2>Sprint help</h2>
<p>How to use the Sprint form:</p>
<ul>
<li><b>Name:</b> usually something like <i>Sprint 14</i>.</li>
<li><b>Description:</b> you can put here the Sprint objective or any other
relevant information for the team.</li>
<li><b>Start &amp; end dates:</b> these dates are used to calculate things
like burndowns, estimated effort table.</li>
<li><b>State:</b> an Sprint can be open or closed, PBIs can be only assigned
to open Sprints.</li>
<li><b>Shared:</b> if you share an Sprint you will be able to assign PBIs of
child projects to this Sprint, this will enable multi-project usage.</li>
</ul>
<h2>Ayuda de las estad&iacute;sticas del Sprint</h2>
<p>Las estad&iacute;sticas del Sprint muestran informaci&oacute;n sobre
diversos aspectos del Sprint, algunos requiren el suo de estimaciones de
esfuerzo de tiempo, imputar esfuerzos, categor&iacute;s de proyecto...</p>
<p>Usa esta informaci&oacute;n para conseguir feedback de de tu Sprint y usarla
en tus retrospectivas de Scrum para contestar a preguntas como:</p>
<ul>
<li>¿Cu&aacute;nto esfuerzo/PHs gastamos en arreglar errores? puede que se
necesite priorizar la deuda t&eacute;cnica.</li>
<li>¿Invertimos suficiente tiempo en revisiones? o ¿quiz&aacute;s
demasiado?</li>
<li>¿Todas los miembros del equipo han conseguido dedicar el tiempo estimado?
¿hay algui&eacute;n que no est&eacute; haciendo revisiones?</li>
<li>¿Ponemos el esfuerzo en EPPs planificados (creados antes de la fecha de
inicio del Sprint)? o ¿quiz&aacute;s tenemos muchas interrupciones (EPPs
creados a mitad del Sprint)?</li>
<li>...</li>
</ul>
<h2>Sprint stats help</h2>
<p>Sprint stats shows information about different aspects of the Sprint, some
of them will require to use time effort estimations, effort logging, project
categories...</p>
<p>Use this information to get feedback of your Sprint &amp; use it in your
Scrum retrospectives to answer things like:</p>
<ul>
<li>How much effort/SPs did I spend on bugs? maybe we need to prioritize
technical debt.</li>
<li>Do I spend enough time on reviews? maybe too much?</li>
<li>Did everyone in the team achieved to do all the estimated time? is anyone
not doing reviews?</li>
<li>Do we put the effort in planned PBIs (created at the beginning of the
Sprint)? or maybe do we have a lot of interruptions (PBIs created in the
middle of the Sprint)?</li>
<li>...</li>
</ul>
<td width="250px">
<div class="tabular">
<p>
<label><%= l(:label_pbis_count) %>:</label>
<%= stats[:closed_pbis_count] %>/<%= stats[:total_pbis_count] %><br />
<label><%= l(:label_sps_count) %>:</label>
<%= stats[:closed_sps_count] %>/<%= stats[:total_sps_count] %><br />
<label><%= l(:label_percentage_closed_sps) %>:</label>
<%= number_to_percentage(stats[:closed_total_percentage],
:precision => 1, :separator => '.') %>
</p>
</div>
</td>
<tr valign="top">
<td width="300px">
<div class="tabular">
<%- filtered_params = params.to_h.symbolize_keys.except(:controller, :action, :id) -%>
<p>
<label><%= l(:label_product_backlog) %>:</label>
<%- options = product_backlog.project.product_backlogs.collect{ |other_product_backlog|
[other_product_backlog.name, path.call(other_product_backlog, filtered_params)] }
options = options_for_select(options, path.call(product_backlog, filtered_params)) -%>
<%= select_tag('selected_sprint_id', options,
:onchange => "if (this.value != '') { window.location = this.value; }") %>
</p>
<%- if product_backlog.shared and @subprojects and !@project.children.visible.empty? -%>
<p>
<label><%= l(:label_filter_by_project) %>:</label>
<%- options = options_for_select(@subprojects, @selected_subproject) -%>
<%= select_tag('select_project_id', options,
:onchange => "if (this.value != '') { window.location = this.value; }") %>
</p>
<%- end -%>
</div>
</td>
<td>
<%- unless product_backlog.description.blank? -%>
<%= textilizable(product_backlog.description) %>
<%- end -%>
</td>
<%- if Scrum::Setting.show_project_totals_on_backlog -%>
<%= render :partial => 'post_its/stats', :locals => {:stats => @stats} %>
<%- end -%>
</tr>
<%- pbi_id = "pbi_#{pbi.id}" -%>
<li id="<%= pbi_id %>"
class="<%= pbi.post_it_css_class(:small_rotate => true, :small_scale => true,
:draggable => User.current.allowed_to?(:sort_product_backlog, pbi.project) &&
params[:filter_by_project].blank?) %>">
<table>
<tr>
<td class="header-1">
<span class="pb-pbi-mini-post-its-container">
<%- if pbi.scrum_blocked? -%>
<span class="<%= Issue.blocked_post_it_css_class %>">
<%= l :label_blocked %>
</span>
&nbsp;&nbsp;
<%- end -%>
</span>
<%= render_pbi_left_header(pbi) %>
</td>
<td class="header-2">
<%= render_pbi_right_header(pbi) %>
</td>
<%- if pbi.has_story_points? -%>
<td class="story-points" rowspan="2">
<%= render :partial => 'common/scrum_story_points',
:locals => {:pbi => pbi, :read_only => read_only} %>
</td>
<%- end -%>
<%- if Scrum::Setting.use_remaining_story_points? -%>
<td class="story-points" rowspan="2">
<%= render :partial => 'common/scrum_remaining_story_points',
:locals => {:pbi => pbi, :read_only => read_only} %>
</td>
<%- end -%>
<%- if User.current.allowed_to?(:edit_product_backlog, project) and
User.current.allowed_to?(:edit_issues, pbi.project) and
pbi.editable? and !read_only -%>
<td rowspan="2">
<%= link_to '', edit_pbi_path(pbi),
:remote => true, :method => 'GET', :class => 'icon icon-edit' %>
</td>
<%- end -%>
<%- if User.current.allowed_to?(:sort_product_backlog, project) and
User.current.allowed_to?(:edit_issues, pbi.project) and
pbi.editable? and !read_only -%>
<td rowspan="2">
<%= link_to '', move_pbi_path(pbi, :top),
:remote => true, :method => 'GET', :class => 'icon icon-move-top' %>
<br />
<%= link_to '', move_pbi_path(pbi, :bottom),
:remote => true, :method => 'GET', :class => 'icon icon-move-bottom' %>
</td>
<%- end -%>
</tr>
<tr>
<td class="content" colspan="2">
<%= link_to_issue(pbi, :tracker => false, :project => project != pbi.project) %>
</td>
</tr>
</table>
</li>
<%- if User.current.allowed_to?(:edit_product_backlog, pbi.project) and pbi.editable? and !read_only -%>
<%= javascript_tag do %>
draggableOnTouchScreen("<%= pbi_id %>");
<% end %>
<%- end -%>
<%- if User.current.allowed_to?(:edit_product_backlog, project) &&
params[:filter_by_project].blank? -%>
<%= javascript_tag do %>
$(document).ready(function() {
$('#pbis').sortable({
update: function() {
if ($.isFunction($.fn.setupAjaxIndicator)) {
setupAjaxIndicator();
}
$.ajax({
url: '<%= sort_product_backlog_path(product_backlog) %>',
type: 'POST',
data: $('#pbis').sortable('serialize'),
dataType: 'script',
error: function() {
alert('<%= l(:error_changing_pbi_order) %>');
location.reload(true);
},
complete: function() {
if ($.isFunction($.fn.hideOnLoad)) {
hideOnLoad();
}
},
success: function(data) {
var error_messages = JSON.parse(data);
if (error_messages && error_messages.length > 0) {
alert('<%= l(:error_changing_pbi_order) %>\n' +
error_messages.join('\n'));
location.reload(true);
} else if ($.isFunction($.fn.hideOnLoad)) {
hideOnLoad();
}
}
});
}
});
});
<% end %>
<%- end -%>
<%- Scrum::Setting.tracker_fields(issue.tracker.id, Scrum::Setting::TrackerFields::SPRINT_BOARD_CUSTOM_FIELDS).each do |custom_field_id| -%>
<%- custom_field = CustomField.find(custom_field_id)
field_value = issue.custom_field_values.select{|c| c.custom_field == custom_field}.first -%>
<%- if custom_field.visible_by?(issue.project, User.current) and
field_value.present? and field_value.value.present? and
(!field_value.value.is_a?(Array) or (field_value.value.any? and !field_value.value.first.blank?)) -%>
<%= content_tag("div", :title => custom_field.description) do %>
<span class="post-it-legend"><%= custom_field.name %>:</span>
<%= show_value(field_value) %>
<% end %>
<%- end -%>
<%- end -%>
<%- if Scrum::Setting.tracker_field?(issue.tracker.id, :status_id, Scrum::Setting::TrackerFields::SPRINT_BOARD_FIELDS) and issue.status -%>
<%= content_tag("div") do %>
<span class="post-it-legend"><%= l(:field_status) %>:</span>
<%= h(issue.status.name) %>
<% end %>
<%- end -%>
<%- if Scrum::Setting.tracker_field?(issue.tracker.id, :category_id, Scrum::Setting::TrackerFields::SPRINT_BOARD_FIELDS) and issue.category -%>
<%= content_tag("div") do %>
<span class="post-it-legend"><%= l(:field_category) %>:</span>
<%= h(issue.category.name) %>
<% end %>
<%- end -%>
<%- if Scrum::Setting.tracker_field?(issue.tracker.id, :fixed_version_id, Scrum::Setting::TrackerFields::SPRINT_BOARD_FIELDS) and issue.fixed_version -%>
<%= content_tag("div") do %>
<span class="post-it-legend"><%= l(:field_fixed_version) %>:</span>
<%= link_to_version(issue.fixed_version) %>
<% end %>
<%- end -%>
<%- there_is_last_sprint = (!(project.last_sprint.nil?))
render_move_to_last_sprint = (there_is_last_sprint and
((sprint.is_product_backlog?) or (sprint.id != project.last_sprint.id)))
menu_needed = render_move_to_last_sprint -%>
<%- if menu_needed -%>
<div class="contextual scrum-menu">
<%- if User.current.allowed_to?(:edit_issues, project) and
User.current.allowed_to?(:edit_sprint_board, project) and
sprint.open? -%>
<%- if render_move_to_last_sprint -%>
<%= link_to(l(:label_move_not_closed_pbis_to_last_sprint), move_not_closed_pbis_to_last_sprint_path(sprint),
:method => :post, :class => 'icon icon-sprint-board') %>
<%- end -%>
<%- end -%>
</div>
<%- end -%>
<table class="box attributes" width="100%">
<tr valign="top">
<td width="300px">
<div class="tabular">
<p>
<label><%= l(:label_sprint) %>:</label>
<%- options = project.sprints.collect{ |other_sprint|
[other_sprint.name, path.call(other_sprint, :type => @type)]}
options = options_for_select(options, path.call(sprint, :type => @type)) -%>
<%= select_tag "selected_sprint_id", options,
:onchange => "if (this.value != '') { window.location = this.value; }" %>
</p>
<p>
<label><%= l(:field_start_date) %>:</label>
<%= format_date sprint.sprint_start_date %>
</p>
<p>
<label><%= l(:field_end_date) %>:</label>
<%= format_date sprint.sprint_end_date %>
</p>
<%- if params[:action] == 'show' -%>
<p>
<label><%= l(:label_filter_by_assignee) %>:</label>
<select id="tasks-assignees"></select>
</p>
<%- end -%>
<%- if sprint.shared and @subprojects and !@only_one -%>
<p>
<label><%= l(:label_filter_by_project) %>:</label>
<%- options = options_for_select(@subprojects, @selected_subproject) -%>
<%= select_tag('select_project_id', options,
:onchange => "if (this.value != '') { window.location = this.value; }") %>
</p>
<%- end -%>
</div>
</td>
<td>
<%- if !(sprint.description.blank?) -%>
<%= textilizable(sprint.description) %>
<%- end -%>
</td>
<%- if Scrum::Setting.show_project_totals_on_sprint -%>
<%= render :partial => 'post_its/stats', :locals => {:stats => @stats} %>
<%- end -%>
</tr>
</table>
<%- pbi_id = "pbi_#{pbi.id}" -%>
<%- is_simple = pbi.is_simple_pbi? -%>
<table id="<%= pbi_id %>"
class="<%= pbi.post_it_css_class(:rotate => true,
:scale => true,
:draggable => true) %>">
<tr>
<td class="content" colspan="3">
<%- if User.current.allowed_to?(:edit_sprint_board, project) and
User.current.allowed_to?(:edit_issues, project) and
pbi.editable? and !read_only -%>
<%= link_to "", edit_pbi_path(pbi), :remote => true, :method => "GET",
:class => "icon icon-edit float-icon", :title => l(:label_edit_pbi) %>
<%- unless is_simple -%>
<%- Tracker.task_trackers.each do |tracker| -%>
<%= link_to "", new_task_path(pbi, tracker), :remote => true, :method => "GET",
:class => "icon icon-add float-icon",
:title => l(:label_add_task, :tracker => tracker.name) %>
<%- end -%>
<%- end -%>
<%- end -%>
<%= render_issue_icons(pbi) %>
<div>
<%= link_to_issue(pbi, :tracker => false, :truncate => 150,
:project => project != pbi.project) %>
</div>
<%= render :partial => "post_its/sprint_board/fields", :formats => [:html],
:locals => {:project => project, :issue => pbi} %>
<%= render :partial => "post_its/sprint_board/custom_fields", :formats => [:html],
:locals => {:project => project, :issue => pbi} %>
<div class="doers-reviewers-post-its-container">
<%- if pbi.scrum_blocked? -%>
<div class="<%= Issue.blocked_post_it_css_class %>">
<%= l :label_blocked %>
</div>
<%- end -%>
</div>
</td>
</tr>
<tr>
<td class="estimation">
<%- if pbi.has_story_points? -%>
<%= render :partial => "common/scrum_story_points", :formats => [:html],
:locals => {:pbi => pbi, :read_only => read_only} %>
<%- end -%>
<%- if Scrum::Setting.use_remaining_story_points? -%>
<%= render :partial => "common/scrum_remaining_story_points", :formats => [:html],
:locals => {:pbi => pbi, :read_only => read_only} %>
<%- end -%>
</td>
<td class="spent">
<%- if User.current.allowed_to?(:view_time_entries, project) -%>
<%= render_hours(pbi.total_time, :title => l(:label_total_effort),
:ignore_zero => pbi.children.empty?) %>
<%- end -%>
</td>
<td class="pending">
<%- if User.current.allowed_to?(:view_pending_effort, project) -%>
<%= render_hours(pbi.pending_effort_children, :title => l(:field_pending_effort),
:ignore_zero => pbi.children.empty?) %>
<%- end -%>
</td>
</tr>
</table>
<%= render :partial => 'post_its/sprint_board/pbi', :formats => [:js],
:locals => {:project => project,
:pbi => pbi,
:pbi_id => pbi_id,
:other_pbi_status_ids => defined?(other_pbi_status_ids) ? other_pbi_status_ids : []} %>
<%- if User.current.allowed_to?(:sort_sprint_board, project) and pbi.editable? -%>
<%= javascript_tag do %>
draggableOnTouchScreen("pbi_<%= pbi.id %>_handle");
<% end %>
<%- end -%>
<%- if User.current.allowed_to?(:edit_sprint_board, project) and pbi.editable? and pbi.is_simple_pbi? -%>
<%= javascript_tag do %>
<%- other_pbi_status_ids.each do |pbi_status_id| -%>
$(document).ready(function() {
$("#<%= pbi_id %>").draggable({
revert: "invalid",
axis: "x",
containment: "<%= pbi_status_id %>",
cursor: "ew-resize",
stack: "table"
});
draggableOnTouchScreen("<%= pbi_id %>");
});
<%- end -%>
<% end %>
<%- end -%>
\ No newline at end of file
<%- pbi_row_id = "pbi_#{pbi.id}_row" -%>
<%- is_simple = pbi.is_simple_pbi? -%>
<tr class="sprint-board"
id="<%= pbi_row_id %>">
<td class="<%= pbi.sortable? ? 'sprint-board-pbi-handle post-it-vertical-move-cursor' : '' %>"
id="pbi_<%= pbi.id %>_handle">
</td>
<td class="sprint-board">
<%- unless is_simple -%>
<%= render :partial => 'post_its/sprint_board/pbi', :formats => [:html],
:locals => {:project => project,
:pbi => pbi,
:read_only => false} %>
<%- end -%>
</td>
<%- tasks = pbi.tasks_by_status_id -%>
<%- task_statuses.each do |status| -%>
<%- pbi_status_id = "pbi_#{pbi.id}_status_#{status.id}" -%>
<%- other_pbi_status_ids = task_statuses.select{|other| other != status}.collect{
|other| "pbi_#{pbi.id}_status_#{other.id}"
} -%>
<td id="<%= pbi_status_id %>" class="sprint-board">
<%- if is_simple -%>
<%- if pbi.status == status -%>
<%= render :partial => 'post_its/sprint_board/pbi', :formats => [:html],
:locals => {:project => project,
:pbi => pbi,
:other_pbi_status_ids => other_pbi_status_ids,
:read_only => false} %>
<%- end -%>
<%- else -%>
<%- tasks[status.id].each do |task| -%>
<%= render :partial => 'post_its/sprint_board/task', :formats => [:html],
:locals => {:project => project,
:task => task,
:pbi_status_id => pbi_status_id,
:other_pbi_status_ids => other_pbi_status_ids,
:read_only => false} %>
<%- end -%>
<%- end -%>
</td>
<%= render :partial => 'post_its/sprint_board/pbi_status', :formats => [:js],
:locals => {:project => project,
:pbi_id => pbi.id,
:pbi_status_id => pbi_status_id,
:status => status} %>
<%- end -%>
</tr>
<%= javascript_tag do %>
$(document).ready(function() {
$("#<%= pbi_status_id %>").droppable({
accept: ".sprint-task,.sprint-pbi",
drop: function(event, ui) {
if ($.isFunction($.fn.setupAjaxIndicator)) {
setupAjaxIndicator();
}
if (!(ui.draggable.is($(this).children()))) {
$.ajax({
url: "<%= project_sprints_change_issue_status_path(@project) %>",
type: "POST",
data: {task: encodeURIComponent($(ui.draggable).attr("id")),
status: encodeURIComponent("<%= status.id %>")},
error: function() {
alert("<%= l(:error_changing_task_status) %>");
var task = $(ui.draggable);
task.detach();
task.appendTo($("#<%= "pbi_#{pbi_id}_status_" %>" + ui.draggable.attr("old-status")));
},
complete: function() {
if ($.isFunction($.fn.hideOnLoad)) {
hideOnLoad();
}
},
success: function() {
ui.draggable.attr("old-status", "<%= status.id %>");
window["container_" + $(ui.draggable).attr("id")] = "";
}
});
}
ui.draggable.appendTo($(this)).removeAttr("style");
ui.draggable.attr("style", "position: relative; " + ui.draggable.attr("style"));
}
});
});
<% end %>
\ No newline at end of file
<%- task_id = "task_#{task.id}" -%>
<table id="<%= task_id %>"
class="<%= task.post_it_css_class(:rotate => true,
:scale => true,
:draggable => true) %>"
old-status="<%= task.status.id %>">
<tr>
<td class="content" colspan="3">
<div class="content">
<%- if User.current.allowed_to?(:edit_sprint_board, project) and
User.current.allowed_to?(:edit_issues, project) and
task.editable? and !read_only -%>
<%= link_to('', edit_task_path(task), :remote => true, :method => 'GET',
:class => 'icon icon-edit float-icon', :title => l(:label_edit_task)) %>
<%- end -%>
<%- if User.current.allowed_to?(:log_time, project) -%>
<%= link_to('',
new_scrum_time_entry_path(task,
:pbi_status_id => pbi_status_id,
:other_pbi_status_ids => other_pbi_status_ids.join(','),
:task_id => task_id),
:remote => true, :method => 'GET',
:class => 'icon icon-log-time float-icon',
:title => l(:button_log_time)) %>
<%- end -%>
<%= render_issue_icons(task) %>
<%= render(:partial => 'post_its/sprint_board/fields', :formats => [:html],
:locals => {:project => project, :issue => task}) %>
<div>
<%= link_to_issue(task, :tracker => false, :truncate => 100,
:project => project != task.project) %>
</div>
<%= render(:partial => 'post_its/sprint_board/custom_fields', :formats => [:html],
:locals => {:project => project, :issue => task}) %>
<div class="doers-reviewers-post-its-container">
<%- task.doers.each do |doer| -%>
<div class="<%= Issue.doer_post_it_css_class %>">
<%= avatar(doer, :size => '14') %> <%= link_to_user doer %>
</div>
<%- end -%>
<%- task.reviewers.each do |reviewer| -%>
<div class="<%= Issue.reviewer_post_it_css_class %>">
<%= avatar(reviewer, :size => '14') %> <%= link_to_user reviewer %>
</div>
<%- end -%>
<%- if task.scrum_blocked? -%>
<div class="<%= Issue.blocked_post_it_css_class %>">
<%= l :label_blocked %>
</div>
<%- end -%>
</div>
</div>
</td>
</tr>
<tr>
<td class="estimation">
<%= render_hours(task.estimated_hours, :title => l(:field_estimated_hours)) %>
</td>
<td class="spent">
<%- if User.current.allowed_to?(:view_time_entries, project) -%>
<%= render_hours(task.spent_hours, :title => l(:label_spent_time), :ignore_zero => true,
:link => project_time_entries_path(task.project, :issue_id => task.id)) %>
<%- end -%>
</td>
<td class="pending">
<%= render(:partial => 'common/scrum_pending_effort', :formats => [:html],
:locals => {:project => project, :task => task}) %>
</td>
</tr>
</table>
<%= render(:partial => 'post_its/sprint_board/task', :formats => [:js],
:locals => {:project => project,
:other_pbi_status_ids => other_pbi_status_ids,
:task_id => task_id,
:task => task}) %>
<%- if User.current.allowed_to?(:edit_sprint_board, project) and task.editable? -%>
<%= javascript_tag do %>
<%- other_pbi_status_ids.each do |pbi_status_id| -%>
$(document).ready(function() {
$("#<%= task_id %>").draggable({
revert: "invalid",
axis: "x",
containment: "<%= pbi_status_id %>",
cursor: "ew-resize",
stack: "table"
});
draggableOnTouchScreen("<%= task_id %>");
});
<%- end -%>
<% end %>
<%- end -%>
\ No newline at end of file
<div>
<%- if User.current.allowed_to?(:add_issues, project) and
@product_backlog.open? -%>
<%- Tracker.pbi_trackers(project).each do |tracker| -%>
<span class="post-it settings-post-it <%= tracker.post_it_css_class %>">
<%= link_to(tracker.name,
new_pbi_path(@product_backlog, tracker, :top => top),
:remote => true, :method => 'GET', :class => 'icon icon-add',
:title => l(top ? :label_add_pbi_at_top : :label_add_pbi_at_bottom,
:tracker => tracker.name)) %>
</span>
<%- end -%>
<%- end -%>
<%= link_to(l(:label_check_dependencies),
check_dependencies_product_backlog_path(@product_backlog),
:remote => true, :method => 'GET', :class => 'icon icon-help') %>
</div>
<br />
<%= javascript_tag do %>
// Create the tooltip DOM element.
var toolTip = document.createElement("div"),
leftOffset = -(~~$("html").css("padding-left").replace("px", "") + ~~$("body").css("margin-left").replace("px", "")),
topOffset = -32;
toolTip.className = "graphic-tooltip";
document.body.appendChild(toolTip);
// Chart data.
var data = {
// Horizontal set of values (ordinal), vertical values (linear).
"xScale": "ordinal",
"yScale": "linear",
"yMin": 0,
"main": [
<%- serieIndex = 0
series.each do |serie| -%>
{
// Sprint story points serie.
"className": ".story-points-<%= serieIndex %>",
"data": [
<%- serie[:data].each_with_index do |value, i| -%>
{
"x": <%= i %>,
"y": <%= value[:pending_story_points] %>,
"tooltip": "<%= value[:story_points_tooltip] %>"
},
<%- end -%>
]
},
<%- serieIndex += 1 -%>
<%- end -%>
]
};
// X axis labels.
var x_axis_labels = [
<%- x_axis_labels.each do |label| -%>
'<%= label %>',
<%- end -%>
];
// Chart options.
var options = {
// Fill axis labels.
"tickFormatX": function(x) { return x_axis_labels[x]; },
// Render a tooltip when mouse goes over the values.
"mouseover": function(d, i) {
var pos = $(this).offset();
$(toolTip).text(d.tooltip)
.css({top: topOffset + pos.top, left: pos.left + leftOffset})
.show();
},
// Hide the tooltip when mouse exists the values.
"mouseout": function(x) {
$(toolTip).hide();
}
};
// Generate the chart.
new xChart("line-dotted", data, "#burndown-chart", options);
<% end %>
<table class="box attributes" width="100%">
<%= render :partial => 'post_its/product_backlog/head',
:locals => {:product_backlog => product_backlog,
:path => method(:burndown_product_backlog_path)} %>
<%= render :partial => 'scrum/velocity_form',
:locals => {:url => burndown_product_backlog_path(product_backlog),
:sprints_count => sprints_count,
:velocity => velocity,
:velocity_type => velocity_type} %>
</table>
<h3 class="title"><%= l(:label_check_dependencies) %></h3>
<%- if @pbis_dependencies.count <= 0 -%>
<%= l(:label_no_invalid_dependencies) %>
<%- else -%>
<p><%= l(:label_invalid_dependencies) %></p>
<ul>
<%- @pbis_dependencies.each do |pbi_dependencies| -%>
<%- if pbi_dependencies[:dependencies].count > 0 -%>
<li>
<%= raw l(:label_invalid_dependencies_for_pbi, :pbi => link_to_issue(pbi_dependencies[:pbi])) %>
<ul>
<%- pbi_dependencies[:dependencies].each do |dependency| -%>
<li><%= link_to_issue(dependency) %></li>
<%- end -%>
</ul>
</li>
<%- end -%>
<%- end -%>
</ul>
<%- end -%>
<%= render :partial => 'scrum/velocity_form',
:locals => {:url => release_plan_product_backlog_path(@product_backlog),
:sprints_count => @sprints_count,
:velocity => @velocity,
:velocity_type => @velocity_type} %>
<tr>
<td colspan="3">
<%= l(:label_release_plan_stats,
:sps => @total_story_points,
:pbis => @pbis_with_estimation,
:pbis_without_sps => @pbis_without_estimation) %>
</td>
</tr>
<%= render :partial => 'common/scrum_backlog_menu' %>
<h2><%= l(:label_product_backlog_burndown_chart) %></h2>
<% content_for :header_tags do %>
<%= javascript_include_tag 'd3.min.js', :plugin => 'scrum' %>
<%= javascript_include_tag 'xcharts.min.js', :plugin => 'scrum' %>
<%= stylesheet_link_tag 'xcharts.min.css', :plugin => 'scrum' %>
<% end %>
<div id="messages"></div>
<%= render :partial => 'burndown_head',
:locals => {:product_backlog => @product_backlog,
:sprints_count => @sprints_count,
:velocity => @velocity,
:velocity_type => @velocity_type} %>
<%- if @warning -%>
<p class="warning"><%= @warning %></p>
<%- end -%>
<div style="position: relative;">
<%- unless @only_one -%>
<svg height="500" width="350" class="xchart"
style="position: absolute; top: 0px; right: 0px;">
<%- i = 0 -%>
<%- row_space = 20 -%>
<%- @series.each do |serie| -%>
<g class="line color<%= i %>">
<path class="line" stroke-width="10" d="M5 <%= 15 + (i * row_space) %> H70" />
</g>
<g class="axis">
<text x="80" y="<%= 18 + (i * row_space) %>"><%= serie[:label] %></text>
</g>
<%- i += 1 -%>
<%- end -%>
</svg>
<%- end -%>
<figure id="burndown-chart"
style="left-margin: auto; right-margin:auto; width: 90%; height: 500px;" />
</div>
<%= render :partial => 'product_backlog/burndown', :formats => [:js],
:locals => {:series => @series, :x_axis_labels => @x_axis_labels} %>
<%= render :partial => 'common/scrum_footer' %>
$("#ajax-modal").html("<%= escape_javascript(render :partial => "product_backlog/check_dependencies") %>");
showModal("ajax-modal", "800px");
\ No newline at end of file
<%= render :partial => 'common/scrum_backlog_menu' %>
<h2>
<%= l(:label_release_plan) %>
</h2>
<table class="box attributes" width="100%">
<%= render :partial => 'post_its/product_backlog/head',
:locals => {:project => @project, :product_backlog => @product_backlog,
:path => method(:release_plan_product_backlog_path)} %>
<%= render :partial => 'release_plan_head',
:locals => {:sprints_count => @sprints_count,
:sps_per_sprint => @velocity,
:default_sps_per_sprint => @default_velocity,
:use_not_scheduled_pbis_for_velocity => @use_not_scheduled_pbis_for_velocity,
:total_story_points => @total_story_points,
:pbis_with_estimation => @pbis_with_estimation,
:pbis_without_estimation => @pbis_without_estimation} %>
</table>
<%= render :layout => 'common/fullscreen_content' do %>
<table class="sprint-board">
<tr class="sprint-board">
<th class="sprint-board"><%= l(:label_sprint_plural) %></th>
<th class="sprint-board"><%= l(:label_version_plural) %></th>
<th class="sprint-board"><%= l(:label_pbi_plural) %></th>
</tr>
<%- @sprints.each_with_index do |sprint, index| -%>
<tr class="sprint-board">
<td class="sprint-board" align="center">
<%= "#{l(:field_sprint)} +#{index + 1}" %>
</td>
<td class="sprint-board">
<%= raw(sprint[:versions].collect{|version| link_to_version(version)}.join(", ")) %>
</td>
<td class="sprint-board">
<ul id="pbis" class="pbis">
<%- sprint[:pbis].each do |pbi| -%>
<%= render :partial => 'post_its/product_backlog/pbi',
:locals => {:project => @project, :pbi => pbi, :read_only => true} %>
<%- end -%>
</ul>
</td>
</tr>
<%- end -%>
</table>
<% end %>
<%= render :partial => 'common/scrum_footer' %>
<%= render :partial => 'common/scrum_backlog_menu' %>
<h2><%= l(:label_product_backlog) %></h2>
<table class="box attributes" width="100%">
<%= render :partial => 'post_its/product_backlog/head',
:locals => {:project => @project, :product_backlog => @product_backlog,
:path => method(:product_backlog_path)} %>
</table>
<%= render :layout => 'common/fullscreen_content' do %>
<%= render :partial => 'product_backlog/actions',
:locals => {:project => @project, :top => true} %>
<div id="messages"></div>
<ul id="pbis" class="pbis">
<%- @product_backlog.pbis(@pbi_filter).each do |pbi| -%>
<%= render :partial => 'post_its/product_backlog/pbi',
:locals => {:project => @project, :pbi => pbi, :read_only => false} %>
<%- end -%>
</ul>
<%= render :partial => 'product_backlog/actions',
:locals => {:project => @project, :top => false} %>
<% end %>
<%- if User.current.allowed_to?(:edit_product_backlog, @project) -%>
<%= render :partial => 'post_its/product_backlog/pbis',
:formats => [:js],
:locals => {:project => @project, :product_backlog => @product_backlog} %>
<%- end -%>
<%= render :partial => 'common/scrum_footer' %>
<%- heads_for_wiki_formatter -%>
<div class="contextual scrum-menu">
<%= link_to(l(:label_product_backlog_new),
new_project_sprint_path(@project, :back_url => '', :create_product_backlog => true),
:class => 'icon icon-add') if User.current.allowed_to?(:manage_sprints, @project) %>
<%= render_scrum_help('product_backlogs') %>
</div>
<%- if @project.product_backlogs.empty? -%>
<p class="nodata"><%= l(:label_no_data) %></p>
<%- else -%>
<table class="list">
<thead>
<tr>
<th><%= l(:field_name) %></th>
<th><%= l(:field_status) %></th>
<th><%= l(:field_shared) %></th>
<th><%= l(:label_pbi_plural) %></th>
<th style="width:15%"></th>
</tr>
</thead>
<tbody>
<% for sprint in @project.product_backlogs %>
<tr class="version <%= cycle 'odd', 'even' %> <%= sprint.status %>">
<td><%= link_to(h(sprint.name), product_backlog_path(sprint)) %></td>
<td class="status"><%= l("label_sprint_status_#{sprint.status}") %></td>
<td align="center"><%= checked_image sprint.shared %></td>
<td align="center"><%= sprint.pbis.count %></td>
<td class="buttons">
<%- if User.current.allowed_to?(:manage_sprints, @project) -%>
<%= link_to l(:button_edit), edit_sprint_path(sprint),
:class => 'icon icon-edit' %>
<%= delete_link sprint_path(sprint) %>
<%- end -%>
</td>
</tr>
<% end; reset_cycle %>
<tbody>
</table>
<%- end -%>
<div class="contextual scrum-menu">
<%= link_to(l(:label_sprint_new), new_project_sprint_path(@project, :back_url => ''),
:class => 'icon icon-add') if User.current.allowed_to?(:manage_sprints, @project) %>
<%= render_scrum_help('sprints') %>
</div>
<%- if @project.sprints.empty? -%>
<p class="nodata"><%= l(:label_no_data) %></p>
<%- else -%>
<table class="list">
<thead>
<tr>
<th><%= l(:field_name) %></th>
<th><%= l(:field_start_date) %></th>
<th><%= l(:field_end_date) %></th>
<th><%= l(:field_status) %></th>
<th><%= l(:field_shared) %></th>
<th><%= l(:label_pbi_plural) %></th>
<th><%= l(:label_task_plural) %></th>
<th style="width:15%"></th>
</tr>
</thead>
<tbody>
<% for sprint in @project.sprints %>
<tr class="version <%= cycle 'odd', 'even' %> <%= sprint.status %>">
<td><%= link_to(h(sprint.name), sprint.is_product_backlog? ? product_backlog_path(sprint) : sprint) %></td>
<td align="center"><%= format_date(sprint.sprint_start_date) %></td>
<td align="center"><%= format_date(sprint.sprint_end_date) %></td>
<td class="status"><%= l("label_sprint_status_#{sprint.status}") %></td>
<td align="center"><%= checked_image sprint.shared %></td>
<td align="center"><%= sprint.pbis.count %></td>
<td align="center"><%= sprint.tasks.count %></td>
<td class="buttons">
<%- if User.current.allowed_to?(:manage_sprints, @project) -%>
<%= link_to l(:label_edit_effort), edit_effort_sprint_path(sprint),
:class => 'icon icon-time-add' %>
<%= link_to l(:button_edit), edit_sprint_path(sprint),
:class => 'icon icon-edit' %>
<%= delete_link sprint_path(sprint) %>
<%- end -%>
</td>
</tr>
<% end; reset_cycle %>
<tbody>
</table>
<%- end -%>
<h3 class="title"><%= l(:field_time_entries) %></h3>
<div id="time-entry-messages" />
<%= form_for :time_entry, :url => create_scrum_time_entry_path(@issue), :remote => true do |f| %>
<%= back_url_hidden_field_tag %>
<%= error_messages_for 'time_entry' %>
<%= hidden_field_tag :pbi_status_id, @pbi_status_id %>
<%= hidden_field_tag :other_pbi_status_ids, @other_pbi_status_ids %>
<%= hidden_field_tag :task_id, @task_id %>
<div class="box tabular">
<p>
<label><%= l(:field_hours) %>:</label>
<%= f.text_field :hours, :size => 15, :required => true %>
</p>
<p>
<label><%= l(:field_spent_on) %>:</label>
<%= f.text_field :spent_on, :size => 10, :value => Date.today, :required => true %>
</p>
<p>
<label><%= l(:field_comments) %>:</label>
<%= f.text_field :comments, :size => 15, :maxlength => 255 %>
</p>
<p>
<label><%= l(:field_activity) %>:</label>
<%= f.select :activity_id,
@project.activities.collect{|activity| [activity.name, activity.id]},
:required => true %>
</p>
<p>
<label><%= l(:field_user) %>:</label>
<%= f.select :user_id,
principals_options_for_select(@issue.assignable_users, @issue.assigned_to),
:required => true %>
</p>
<%- TimeEntry.new.custom_field_values.each do |value| -%>
<p>
<label><%= value.custom_field.name %>:</label>
<%= custom_field_tag :time_entry, value %>
</p>
<%- end -%>
<p>
<%= submit_tag l(:button_save) %>
</p>
</div>
<% end %>
<%= render :partial => "scrum/issue_attributes", :formats => [:html],
:locals => {:f => f, :issue => issue} %>
<p class="buttons">
<%= submit_tag l(:button_edit), :name => "edit", :disable_with => l(:label_loading) %>
<%= submit_tag l(:button_cancel), :name => nil, :onclick => "hideModal(this);", :type => "button" %>
</p>
\ No newline at end of file
<div id="main" class="nosidebar">
<div id="content">
<h3 class="title"><%= "#{@pbi.tracker.name} ##{@pbi.id}" %></h3>
<%- there_is_last_sprint = (!(@project.last_sprint.nil?))
there_is_product_backlog = (!(@project.product_backlogs.empty?))
render_move_to_last_sprint = (there_is_last_sprint and
((@pbi.sprint.is_product_backlog?) or (@pbi.sprint.id != @project.last_sprint.id)))
render_move_to_product_backlog = (there_is_product_backlog and
((!(@project.product_backlogs.include?(@pbi.sprint))) or
(@project.product_backlogs.size > 1)))
render_move_pbi = (there_is_product_backlog and (@pbi.sprint.id == @project.product_backlogs.first.id) and
User.current.allowed_to?(:sort_product_backlog, @project))
menu_needed = (render_move_to_last_sprint or render_move_to_product_backlog or render_move_pbi) -%>
<%- if menu_needed -%>
<div class="modal-issue-menu">
<%- if render_move_pbi -%>
<%= form_tag(move_pbi_path(@pbi, :before), :method => :get, :remote => true,
:id => 'move_pbi_before') do %>
<%= link_to(l(:label_move_pbi_before), '#', :onclick => "$('#move_pbi_before').submit(); return(false);") %>:
<%= text_field_tag(:before_other_pbi, '', :size => 3) %>
<%= javascript_tag "observeAutocompleteField('before_other_pbi', '#{escape_javascript auto_complete_issues_path(:project_id => @project, :scope => (Setting.cross_project_issue_relations? ? 'all' : nil))}')" %>
<% end %>
<%= form_tag(move_pbi_path(@pbi, :after), :method => :get, :remote => true,
:id => 'move_pbi_after') do %>
<%= link_to(l(:label_move_pbi_after), '#', :onclick => "$('#move_pbi_after').submit(); return(false);") %>:
<%= text_field_tag(:after_other_pbi, '', :size => 3) %>
<%= javascript_tag "observeAutocompleteField('after_other_pbi', '#{escape_javascript auto_complete_issues_path(:project_id => @project, :scope => (Setting.cross_project_issue_relations? ? 'all' : nil))}')" %>
<% end %>
<%- end -%>
<%- if render_move_to_last_sprint -%>
<%= link_to(l(:label_move_pbi_to_last_sprint), move_to_last_sprint_path(@pbi),
:remote => true, :method => :post, :class => "icon icon-sprint-board") %>
<%- end -%>
<%- if render_move_to_product_backlog -%>
<%- @project.product_backlogs.each do |product_backlog| -%>
<%= link_to(l(:label_move_pbi_to_name, :name => product_backlog.name),
move_to_product_backlog_path(@pbi, :id => product_backlog.id),
:remote => true, :method => :post, :class => "icon icon-product-backlog") %>
<%- end -%>
<%- end -%>
</div>
<%- end -%>
<div id="popup-messages"></div>
<%= labelled_form_for @pbi, :url => update_pbi_path(@pbi), :method => :post, :remote => true do |f| %>
<%= back_url_hidden_field_tag %>
<%= f.hidden_field :tracker_id, :value => @pbi.tracker_id %>
<%= f.hidden_field :sprint_id, :value => @pbi.sprint_id %>
<%= error_messages_for 'pbi' %>
<%= render :partial => 'scrum/edit_issue_attributes', :formats => [:html],
:locals => {:f => f, :issue => @pbi} %>
<% end %>
</div>
</div>
\ No newline at end of file
<div id="main" class="nosidebar">
<div id="content">
<h3 class="title"><%= @issue.tracker.name %></h3>
<div id="popup-messages"></div>
<%= labelled_form_for @issue, :url => update_task_path(@issue), :method => :post, :remote => true do |f| %>
<%= back_url_hidden_field_tag %>
<%= f.hidden_field :tracker_id, :value => @issue.tracker_id %>
<%= error_messages_for "task" %>
<%= render :partial => "scrum/edit_issue_attributes", :formats => [:html],
:locals => {:f => f, :issue => @issue} %>
<% end %>
</div>
</div>
<div class="box tabular">
<%- if issue.safe_attribute?(:subject) -%>
<p>
<%= f.text_field :subject, :size => 10, :maxlength => 255, :required => true %>
</p>
<%- end -%>
<%- if issue.safe_attribute?(:project_id) and
issue.sprint and issue.sprint.project and
issue.sprint.shared? and issue.sprint.project.children.any? -%>
<p>
<%= f.select :project_id, project_selector_tree(issue.sprint.project), {:required => true} %>
</p>
<%- end -%>
<%- allowed_statuses = issue.new_statuses_allowed_to(User.current) -%>
<%- if issue.safe_attribute?(:status_id) and allowed_statuses.present? -%>
<p>
<%= f.select :status_id, (allowed_statuses.collect {|status| [status.name, status.id]}), {:required => true} %>
</p>
<%- end -%>
<%- if issue.safe_attribute?(:priority_id) -%>
<p>
<%= f.select :priority_id, (IssuePriority.active.collect {|p| [p.name, p.id]}), {:required => true, :disabled => !issue.leaf?} %>
</p>
<%- end -%>
<%- if issue.field?(:assigned_to_id) -%>
<p>
<%= f.select :assigned_to_id, principals_options_for_select(issue.assignable_users, issue.assigned_to), :include_blank => true, :required => issue.required_attribute?('assigned_to_id') %>
</p>
<%- end -%>
<%- if issue.field?(:category_id) and issue.project.issue_categories.any? -%>
<p>
<%= f.select :category_id,
(issue.project.issue_categories.collect {|c| [c.name, c.id]}),
:include_blank => true,
:required => issue.required_attribute?(:category_id) %>
</p>
<% end %>
<%- if issue.field?(:fixed_version_id) and issue.assignable_versions.any? -%>
<p><%= f.select :fixed_version_id, version_options_for_select(issue.assignable_versions, issue.fixed_version), :include_blank => true, :required => issue.required_attribute?('fixed_version_id') %>
</p>
<%- end -%>
<%- method = (Redmine::VERSION::STRING < '3.3.0') ? :text_field : :date_field -%>
<%- if issue.field?(:start_date) -%>
<p>
<%= f.send method, :start_date, :size => 10, :disabled => !issue.leaf?, :required => issue.required_attribute?('start_date') %><%= calendar_for('issue_start_date') if issue.leaf? %>
</p>
<%- end -%>
<%- if issue.field?(:due_date) -%>
<p>
<%= f.send method, :due_date, :size => 10, :disabled => !issue.leaf?, :required => issue.required_attribute?('due_date') %><%= calendar_for('issue_due_date') if issue.leaf? %>
</p>
<%- end -%>
<%- if issue.field?(:estimated_hours) -%>
<p>
<%= f.text_field :estimated_hours, :size => 4, :maxlength => 10 %>
</p>
<%- end -%>
<%- if User.current.allowed_to?(:edit_pending_effort, issue.project) and
issue.is_task? -%>
<p>
<%= f.text_field :pending_effort, :size => 4, :maxlength => 10, :label => l(:field_pending_effort) %>
</p>
<%- end -%>
<%- if issue.field?(:done_ratio) and issue.leaf? and Issue.use_field_for_done_ratio? -%>
<p>
<%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r * 10} %", r * 10] }), :required => issue.required_attribute?('done_ratio') %>
</p>
<%- end -%>
<%- issue.editable_custom_field_values.each do |value| -%>
<%- if issue.custom_field?(value.custom_field) -%>
<p>
<%= custom_field_tag_with_label :issue, value, :required => value.custom_field.is_required %>
</p>
<%- end -%>
<%- end -%>
<%- if User.current.allowed_to?(:edit_pending_effort, issue.project) and
issue.is_pbi? and Scrum::Setting::use_remaining_story_points? -%>
<p>
<%= f.text_field :pending_effort, :size => 4, :maxlength => 10,
:label => l(:label_pending_sps) %>
</p>
<%- end -%>
<%- if issue.field?(:description) -%>
<p>
<%= f.label_for_field :description, :required => issue.required_attribute?(:description) %>
<%= content_tag :span, :id => "issue_description_and_toolbar" do %>
<%= f.text_area :description,
:rows => 8,
:accesskey => accesskey(:edit),
:class => "wiki-edit",
:no_label => true %>
<% end %>
</p>
<%= wikitoolbar_for 'issue_description' %>
<%- end -%>
<%- if issue.id -%>
<p>
<%= f.text_area :notes, :rows => 8, :class => "wiki-edit" %>
</p>
<%= wikitoolbar_for 'issue_notes' %>
<%- end -%>
</div>
<%= render :partial => "scrum/issue_attributes", :formats => [:js],
:locals => {:issue => issue} %>
<%- if issue.field?(:estimated_hours) and
issue.is_task? and
User.current.allowed_to?(:edit_pending_effort, issue.project) -%>
<%= javascript_tag do %>
var changeEstimatedHours = !$("#issue_estimated_hours").val();
var changePendingEffort = !$("#issue_pending_effort").val();
$("#issue_estimated_hours").change(function() {
if (changePendingEffort && $("#issue_estimated_hours").val()) {
$("#issue_pending_effort").val($("#issue_estimated_hours").val());
}
});
$("#issue_pending_effort").change(function() {
if (changeEstimatedHours && $("#issue_pending_effort").val()) {
$("#issue_estimated_hours").val($("#issue_pending_effort").val());
}
});
<% end %>
<%- end -%>
<%= javascript_tag do %>
$('#ajax-modal').on('click', 'div.jstTabs a.tab-preview', function(event){
var tab = $(event.target);
var url = tab.data('url');
var form = tab.parents('form');
var jstBlock = tab.parents('.jstBlock');
var element = encodeURIComponent(jstBlock.find('.wiki-edit').val());
var attachments = form.find('.attachments_fields input').serialize();
$.ajax({
url: url,
type: 'post',
data: "text=" + element + '&' + attachments,
success: function(data){
jstBlock.find('.wiki-preview').html(data);
}
});
});
<% end %>
<%= render :partial => "scrum/issue_attributes", :formats => [:html],
:locals => {:f => f, :issue => issue} %>
<p class="buttons">
<%= submit_tag l(:button_create_and_continue), :name => "create_and_continue", :disable_with => l(:label_loading) %>
<%= submit_tag l(:button_create), :name => "create", :disable_with => l(:label_loading) %>
<%= submit_tag l(:button_cancel), :name => nil, :onclick => "hideModal(this);", :type => "button" %>
</p>
\ No newline at end of file
<div id="main" class="nosidebar">
<div id="content">
<h3 class="title"><%= @pbi.tracker.name %></h3>
<div id="popup-messages"></div>
<%= labelled_form_for @pbi, :url => create_pbi_path(@sprint), :remote => true do |f| %>
<%= back_url_hidden_field_tag %>
<%= f.hidden_field :tracker_id, :value => @pbi.tracker_id %>
<%= f.hidden_field :sprint_id, :value => @pbi.sprint_id %>
<%= hidden_field_tag(:top, true) if @top %>
<%= error_messages_for "pbi" %>
<%= render :partial => "scrum/new_issue_attributes", :formats => [:html],
:locals => {:f => f, :issue => @pbi} %>
<% end %>
</div>
</div>
<div id="main" class="nosidebar">
<div id="content">
<h3 class="title"><%= @task.tracker.name %></h3>
<div id="popup-messages"></div>
<%= labelled_form_for @task, :url => create_task_path(@pbi), :remote => true do |f| %>
<%= back_url_hidden_field_tag %>
<%= f.hidden_field :tracker_id, :value => @task.tracker_id %>
<%= error_messages_for "task" %>
<%= render :partial => "scrum/new_issue_attributes", :formats => [:html],
:locals => {:f => f, :issue => @task} %>
<% end %>
</div>
</div>
<tr>
<td colspan="3">
<%= form_tag(url, :method => :get, :id => 'velocity_form') do %>
<%= hidden_field_tag(:filter_by_project, params[:filter_by_project]) %>
<%= label_tag(:velocity_type_all) do %>
<%= radio_button_tag(:velocity_type, 'all', 'all' == velocity_type) %>
<%= l(:label_velocity_all_pbis, :count => sprints_count) %>
<% end %>
&nbsp;&nbsp;&nbsp;
<%= label_tag(:velocity_type_only_scheduled) do %>
<%= radio_button_tag(:velocity_type, 'only_scheduled', 'only_scheduled' == velocity_type) %>
<%= content_tag('abbr', :title => l(:label_velocity_only_scheduled_pbis_hint)) do %>
<%= l(:label_velocity_only_scheduled_pbis) %>
<% end %>
<% end %>
&nbsp;&nbsp;&nbsp;
<%= label_tag(:velocity_type_custom) do %>
<%= radio_button_tag(:velocity_type, 'custom', 'custom' == velocity_type) %>
<%= l(:label_velocity_custom) %>
<% end %>
<%= text_field_tag(:custom_velocity, velocity, :size => 5,
:onclick => "$('#velocity_type_custom').prop('checked', true);") %>
&nbsp;&nbsp;&nbsp;
<%= button_tag(l(:button_update)) %>
<% end %>
</td>
</tr>
<%- if @continue or defined?(@exception) -%>
<%- if defined?(@exception) -%>
<%- message = l(:error_creating_pbi, :message => @exception.message)
message_class = "error" -%>
<%- else -%>
$("#new_issue").each (function() {
this.reset();
});
<%- message = l(:notice_pbi_created)
message_class = "notice" -%>
<%- end -%>
$("#popup-messages").html("<div class=\"flash <%= message_class %>\"><%= message %></div>");
<%- else -%>
$("#ajax-modal").dialog("close");
<%- end -%>
<%- if !defined?(@exception) -%>
if ($("#pbis").length > 0) {
<%- if @top -%>
$("#pbis").prepend("<%=
escape_javascript(render :partial => "post_its/product_backlog/pbi", :formats => [:html],
:locals => {:project => @project, :pbi => @pbi, :read_only => false}).html_safe
%>");
<%- else -%>
$("#pbis").append("<%=
escape_javascript(render :partial => "post_its/product_backlog/pbi", :formats => [:html],
:locals => {:project => @project, :pbi => @pbi, :read_only => false}).html_safe
%>");
<%- end -%>
} else if ($("#sprint_board").length > 0) {
$("#sprint_board").append("<%=
escape_javascript(render :partial => "post_its/sprint_board/pbi_row", :formats => [:html],
:locals => {:project => @project, :pbi => @pbi,
:task_statuses => IssueStatus.task_statuses}).html_safe
%>");
}
<%- if (!(IssueStatus.pbi_statuses.include?(@pbi.status))) -%>
$("#<%= @pbi.sprint.is_product_backlog? ? "pbi_#{@pbi.id}" : "pbi_#{@pbi.id}_row" %>").remove();
<%- end -%>
<%- end -%>
<%- if @continue or defined?(@exception) -%>
<%- if defined?(@exception) -%>
<%- message = l(:error_creating_task, :message => @exception.message)
message_class = "error" -%>
<%- else -%>
$("#new_issue").each (function() {
this.reset();
});
<%- message = l(:notice_task_created)
message_class = "notice" -%>
<%- end -%>
$("#popup-messages").html("<div class=\"flash <%= message_class %>\"><%= message %></div>");
<%- else -%>
$("#ajax-modal").dialog("close");
<%- end -%>
<%- if !defined?(@exception) -%>
<%- pbi_row = "pbi_#{@task.parent.id}_row" -%>
if ($("#<%= pbi_row %>").length > 0) {
$("#<%= pbi_row %>").replaceWith("<%=
escape_javascript(render :partial => "post_its/sprint_board/pbi_row", :formats => [:html],
:locals => {:project => @project, :pbi => @task.parent,
:task_statuses => IssueStatus.task_statuses}).html_safe
%>");
}
<%- end -%>
<%- if defined?(@exception) -%>
<%- message = l(:error_creating_time_entry, :message => @exception.message)
message_class = "error" -%>
$("#time-entry-messages").html("<div class=\"flash <%= message_class %>\"><%= message %></div>");
<%- else -%>
$("#ajax-modal").dialog("close");
<%- end -%>
<%- if !defined?(@exception) -%>
<%- pbi_row = "pbi_#{@issue.parent.id}_row" -%>
if ($("#<%= pbi_row %>").length > 0) {
$("#<%= pbi_row %>").replaceWith("<%=
escape_javascript(render :partial => "post_its/sprint_board/pbi_row", :formats => [:html],
:locals => {:project => @project, :pbi => @issue.parent,
:task_statuses => IssueStatus.task_statuses}).html_safe
%>");
}
<%- end -%>
$("#ajax-modal").html("<%= escape_javascript(render :partial => "scrum/edit_pbi_modal") %>");
showModal("ajax-modal", "880px");
\ No newline at end of file
$("#ajax-modal").html("<%= escape_javascript(render :partial => "scrum/edit_task_modal") %>");
showModal("ajax-modal", "880px");
\ No newline at end of file
<%- if defined?(@exception) -%>
<%- message = l(:error_updating_pbi, :message => @exception.message)
message_class = 'error' -%>
$("#popup-messages").html("<div class=\"flash <%= message_class %>\"><%= message %></div>");
<%- elsif @position == 'top' -%>
$("#popup-messages").html("");
<%- if @position == 'top' -%>
$("#<%= "pbi_#{@pbi.id}" %>").parent().prepend($("#<%= "pbi_#{@pbi.id}" %>"));
<%- elsif @position == 'bottom' -%>
$("#<%= "pbi_#{@pbi.id}" %>").parent().append($("#<%= "pbi_#{@pbi.id}" %>"));
<%- elsif @position == 'before' -%>
$("#ajax-modal").dialog("close");
$("#<%= "pbi_#{@other_pbi}" %>").before($("#<%= "pbi_#{@pbi.id}" %>"));
<%- elsif @position == 'after' -%>
$("#ajax-modal").dialog("close");
$("#<%= "pbi_#{@other_pbi}" %>").after($("#<%= "pbi_#{@pbi.id}" %>"));
<%- else -%>
console.log("Invalid position: <%= @position.inspect %>");
<%- end -%>
<%- end -%>
<%- if defined?(@exception) -%>
<%- message = l(:error_updating_pbi, :message => @exception.message)
message_class = "error" -%>
$("#popup-messages").html("<div class=\"flash <%= message_class %>\"><%= message %></div>");
<%- else -%>
$("#ajax-modal").dialog("close");
$("#<%= @previous_sprint.is_product_backlog? ? "pbi_#{@pbi.id}" : "pbi_#{@pbi.id}_row" %>").remove();
<%- end -%>
<%- if defined?(@exception) -%>
<%- message = l(:error_updating_pbi, :message => @exception.message)
message_class = "error" -%>
$("#popup-messages").html("<div class=\"flash <%= message_class %>\"><%= message %></div>");
<%- else -%>
$("#ajax-modal").dialog("close");
$("#<%= "pbi_#{@pbi.id}_row" %>").remove();
<%- end -%>
$("#ajax-modal").html("<%= escape_javascript(render :partial => "scrum/new_pbi_modal") %>");
showModal("ajax-modal", "800px");
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment