matejak/estimagus

View on GitHub
estimage/webapp/templates/issue_view.html

Summary

Maintainability
Test Coverage
{%- if mode == "proj" %}
{% extends "general_plan.html" %}
{%- else %}
{% extends "general_retro.html" %}
{%- endif %}

{% import "utils.j2" as utils with context %}
{% from 'bootstrap5/form.html' import render_form %}


{% macro format_tracker_task_size() -%}
{% set time_cost_is_relevant = task.time_cost -%}
{% set point_cost_is_relevant = task.point_cost or not time_cost_is_relevant -%}
{% if point_cost_is_relevant -%}
    <p>Point cost: {{ task.point_cost }}</p>
{%- endif -%}
{% if time_cost_is_relevant -%}
    <p>Time cost: {{ task.time_cost }}{% if task.TIME_UNIT %} {{ task.TIME_UNIT }} {%- endif %}</p>
{%- endif -%}
{%- endmacro %}


{% set all_story_points = [1, 2, 3, 5, 8, 13] %}
{% macro id_of_populate_btn(sp) -%}
populate-{{ sp }}
{%- endmacro %}

{% macro populate_btn(sp) -%}
<div><a type="button" class="btn btn-outline-primary" id="{{ id_of_populate_btn(sp) }}">{{ sp }} SP</a></div>
{%- endmacro %}

{% macro space_evenly(elements) -%}
<div class="d-flex justify-content-evenly">{{ "".join(elements) | safe }}</div>
{%- endmacro %}

{% macro estimation_form_in_accordion(estimate_exists) -%}
{% set fillers_str = [] %}
{% for pval in all_story_points %}
{% set temp = fillers_str.append(populate_btn(pval)) %}
{% endfor %}
{{ utils.accordion_with_stuff(
    "Estimation", estimate_exists,
    ("Modify" if estimate_exists else "Create") ~ " the estimate",
    space_evenly(fillers_str) | safe ~
    render_form(forms["estimation"], button_map={"submit": "primary", "delete": "danger"}, action=head_url_for("main.estimate", task_name=task.name))
    )
}}
{%- endmacro %}


{% block content %}
<div class="container">
    <div class="row">
    <h1>Estimate</h1>
    {{ utils.task_metadata(task) | indent(4) }}
    <h2>Estimates</h2>
    <div class="row">
        <div class="col">
    {%- if context.estimation_source == "none" %}
        <p>Point estimate: {{ utils.render_precise_estimate(task.point_cost) }}</p>
    {%- else %}
        <p>Point estimate: {{ utils.render_estimate(context.estimation) }}</p>
    {%- endif %}
    {%- if context.estimation_source == "own" %}
        <p>The estimate is based on your personal estimate that is not visible to others.</p>
    {%- endif %}
    {%- if context.estimation_source == "global" %}
        <p>The estimate is based on the consensus estimate.</p>
    {%- endif %}
    {%- if context.estimation_source == "none" %}
        <p>The estimate is based on the data from the issue tracker.</p>
    {%- endif %}
    {%- if context.estimate_status == "duplicate" %}
        <p>Your personal estimate and consensus are the same. Remove the redundant personal estimate.</p>
    {%- elif context.estimate_status == "contradictory" %}
        <p>Your personal estimate is different than the global consensus, and overrides it for you.</p>
    {%- endif %}
    {%- if not context.authoritative_record_exists %}
        <p>The issue doesn't seem to be estimated in the issue tracker.</p>
    {%- elif context.estimation_source == "global"  %}
    {%- if context.authoritative_record_consistent %}
        <p>The estimation and its record in the issue tracker are consistent.</p>
    {%- else %}
        <p>The estimation and its record in the issue tracker aren't consistent, consider updating whatever is invalid.</p>
    {%- endif %}
    {%- endif %}
        </div>
        <div class="col">
        <img src="{{ head_url_for('vis.visualize_task_nominal', task_name=task.name, mode=mode) }}" alt="PERT prob density function for {{ task.name }}"/>
        </div>
    {% if not forms %}
        <div class="col">
        <img src="{{ head_url_for('vis.visualize_epic_burndown', epic_name=task.name, size='normal') }}" alt="Burndown for {{ task.name }}"/>
        </div>
        {%- endif %}
    </div>
    {% if forms %}
    <div class="row">
    {% block forms %}
    <h3>Consensus values</h3>
    {% if context.global_estimate_exists %}
    <p>Point cost: {{ utils.render_estimate(context.global_estimate) }}</p>
    {% endif %}
    {% if "consensus" in forms %}
        {{ render_form(forms["consensus"], button_map={"submit": "primary", "delete": "danger"}, action=head_url_for("main.act_on_global_estimate", task_name=task.name)) }}
    {% endif %}
    </div>
    <div class="col">
    <h3>Our values</h3>
    {{ estimation_form_in_accordion(context.own_estimation_exists) }}
    {% endblock %}
    </div>
    {%- if similar_sized_cards %}
        {{ utils.render_similar_sized_tasks(similar_sized_cards) }}
    {%- endif %}
    {%- endif %}
</div>
{% endblock %}

{% block footer %}
{{ super() }}
{% if forms %}
{% if "authoritative" in forms -%}
{{ forms["authoritative"].supporting_js([forms["authoritative"]]) | safe }}

    <script>
{% for pval in all_story_points %}
        // JavaScript to handle button click and populate form fields
document.getElementById("{{ id_of_populate_btn(pval) }}").addEventListener('click', function() {
    document.getElementById('optimistic').value = {{ "%.3g" % (pval * 0.468) }};
    document.getElementById('most_likely').value = {{ "%.3g" % (pval * 0.904) }};
    document.getElementById('pessimistic').value = {{ "%.3g" % (pval * 1.92) }};
        });
{% endfor %}
    </script>

{%- endif %}
{%- endif %}
{% endblock %}