diff --git a/taiga/mdrender/templatetags/functions.py b/taiga/mdrender/templatetags/functions.py
index 07110191..7608f553 100644
--- a/taiga/mdrender/templatetags/functions.py
+++ b/taiga/mdrender/templatetags/functions.py
@@ -23,4 +23,6 @@ register = library.Library()
@register.global_function
def mdrender(project, text) -> str:
- return Markup(render(project, text))
+ if text:
+ return Markup(render(project, text))
+ return ""
diff --git a/taiga/projects/history/services.py b/taiga/projects/history/services.py
index 45d8f20f..775604d4 100644
--- a/taiga/projects/history/services.py
+++ b/taiga/projects/history/services.py
@@ -166,7 +166,8 @@ def make_diff(oldobj:FrozenObj, newobj:FrozenObj) -> FrozenDiff:
diff["description"][0],
diff["description"][1]
)
- diff["description_diff"] = (not_found_value, description_diff)
+ if description_diff:
+ diff["description_diff"] = (not_found_value, description_diff)
return FrozenDiff(newobj.key, diff, newobj.snapshot)
diff --git a/taiga/projects/history/templates/emails/includes/fields_diff-html.jinja b/taiga/projects/history/templates/emails/includes/fields_diff-html.jinja
index 00de9e29..769a0579 100644
--- a/taiga/projects/history/templates/emails/includes/fields_diff-html.jinja
+++ b/taiga/projects/history/templates/emails/includes/fields_diff-html.jinja
@@ -1,108 +1,125 @@
+{% set excluded_fields = [
+ "description",
+ "description_html"
+] %}
+
{% for field_name, values in changed_fields.items() %}
- -
- {{ verbose_name(object, field_name) }}
-
+ {% if field_name not in excluded_fields %}
+ -
+ {{ verbose_name(object, field_name) }}
+
-{# POINTS #}
- {% if field_name == "points" %}
+ {# POINTS #}
+ {% if field_name == "points" %}
- {% for role, points in values.items() %}
- -
- {{ role }}
-
- -
- to: {{ points.1|linebreaksbr }}
-
- -
- from: {{ points.0|linebreaksbr }}
-
- {% endfor %}
-
-{# ATTACHMENTS #}
- {% elif field_name == "attachments" %}
-
- {% if values.new %}
- -
- {{ _("Added") }}
-
-
- {% for att in values['new']%}
- -
-
- {{ att.filename|linebreaksbr }} {% if att.description %}({{ att.description|linebreaksbr }}){% endif %}
-
-
+ {% for role, points in values.items() %}
+ -
+ {{ role }}
+
+ -
+ to: {{ points.1|linebreaksbr }}
+
+ -
+ from: {{ points.0|linebreaksbr }}
+
{% endfor %}
- {% endif %}
- {% if values.changed %}
- -
- {{ _("Changed") }}
-
+ {# ATTACHMENTS #}
+ {% elif field_name == "attachments" %}
+
+ {% if values.new %}
+ -
+ {{ _("Added") }}
+
+
+ {% for att in values['new']%}
+ -
+
+ {{ att.filename|linebreaksbr }} {% if att.description %}({{ att.description|linebreaksbr }}){% endif %}
+
+
+ {% endfor %}
+ {% endif %}
+
+ {% if values.changed %}
+ -
+ {{ _("Changed") }}
+
+
+ {% for att in values['changed'] %}
+ -
+ {{ att.1.filename|linebreaksbr }} {% if att.1.description %}({{ att.1.description|linebreaksbr }}){% endif %}
+ {% if att.1.is_deprecated and not att.0.is_deprecated %}
+ to deprecated
+ {% elif not att.1.is_deprecated and att.0.is_deprecated %}
+ to not deprecated
+ {% endif %}
+
+ {% endfor %}
+ {% endif %}
+
+ {% if values.deleted %}
+ -
+ {{ _("Deleted") }}
+
+
+ {% for att in values['deleted']%}
+ -
+ {{ att.filename|linebreaksbr }}
+
+ {% endfor %}
+ {% endif %}
+
+ {# TAGS AND WATCHERS #}
+ {% elif field_name in ["tags", "watchers"] %}
- {% for att in values['changed'] %}
-
- {{ att.1.filename|linebreaksbr }} {% if att.1.description %}({{ att.1.description|linebreaksbr }}){% endif %}
- {% if att.1.is_deprecated and not att.0.is_deprecated %}
- to deprecated
- {% elif not att.1.is_deprecated and att.0.is_deprecated %}
- to not deprecated
- {% endif %}
-
- {% endfor %}
- {% endif %}
-
- {% if values.deleted %}
- -
- {{ _("Deleted") }}
+ to: {{ ', '.join(values.1)|linebreaksbr }}
- {% for att in values['deleted']%}
+ {% if values.0 %}
-
- {{ att.filename|linebreaksbr }}
+ from: {{ ', '.join(values.0)|linebreaksbr }}
- {% endfor %}
- {% endif %}
+ {% endif %}
-{# TAGS AND WATCHERS #}
- {% elif field_name in ["tags", "watchers"] %}
+ {# DESCRIPTIONS #}
+ {% elif field_name in ["description_diff"] %}
+ -
+ to: {{ mdrender(object.project, values.1) }}
+
+ {# ASSIGNED TO #}
+ {% elif field_name == "assigned_to" %}
+ -
+ {% if values.1 != None and values.1 != "" %}
+ to: {{ values.1|linebreaksbr }}
+ {% else %}
+ to: {{ _("Unassigned") }}
+ {% endif %}
+
- -
- to: {{ ', '.join(values.1)|linebreaksbr }}
-
+ -
+ {% if values.0 != None and values.0 != "" %}
+ from: {{ values.0|linebreaksbr }}
+ {% else %}
+ from: {{ _("Unassigned") }}
+ {% endif %}
+
+ {# * #}
+ {% else %}
+ {% if values.1 != None and values.1 != "" %}
+ -
+ to: {{ values.1|linebreaksbr }}
+
+ {% endif %}
- {% if values.0 %}
- -
- from: {{ ', '.join(values.0)|linebreaksbr }}
-
- {% endif %}
+ {% if values.0 != None and values.0 != "" %}
+ -
+ from: {{ values.0|linebreaksbr }}
+
+ {% endif %}
-{# DESCRIPTIONS #}
- {% elif field_name in ["description"] %}
- {% if values.1 != None or values.1 != "" %}
- -
- to: {{ mdrender(object.project, values.1) }}
-
- {% endif %}
-
- {% if values.0 != None or values.0 != "" %}
- -
- from: {{ mdrender(object.project, values.0) }}
-
- {% endif %}
-{# * #}
- {% else %}
- {% if values.1 != None or values.1 != "" %}
- -
- to: {{ values.1|linebreaksbr }}
-
- {% endif %}
-
- {% if values.0 != None or values.0 != "" %}
- -
- from: {{ values.0|linebreaksbr }}
-
{% endif %}
{% endif %}
diff --git a/taiga/projects/history/templates/emails/includes/fields_diff-text.jinja b/taiga/projects/history/templates/emails/includes/fields_diff-text.jinja
index 91358610..7ee49bfe 100644
--- a/taiga/projects/history/templates/emails/includes/fields_diff-text.jinja
+++ b/taiga/projects/history/templates/emails/includes/fields_diff-text.jinja
@@ -1,45 +1,51 @@
+{% set excluded_fields = [
+ "description_diff",
+ "description_html"
+] %}
{% for field_name, values in changed_fields.items() %}
+ {% if field_name not in excluded_fields %}
- {{ verbose_name(object, field_name) }}:
-{# POINTS #}
- {% if field_name == "points" %}
- {% for role, points in values.items() %}
+ {# POINTS #}
+ {% if field_name == "points" %}
+ {% for role, points in values.items() %}
* {{ role }} to: {{ points.1|linebreaksbr }} from: {{ points.0|linebreaksbr }}
- {% endfor %}
-{# ATTACHMENTS #}
- {% elif field_name == "attachments" %}
- {% if values.new %}
+ {% endfor %}
+ {# ATTACHMENTS #}
+ {% elif field_name == "attachments" %}
+ {% if values.new %}
* {{ _("Added") }}:
- {% for att in values['new']%}
+ {% for att in values['new']%}
- {{ att.filename|linebreaksbr }}
- {% endfor %}
- {% endif %}
+ {% endfor %}
+ {% endif %}
- {% if values.changed %}
+ {% if values.changed %}
* {{ _("Changed") }}
- {% for att in values['changed'] %}
+ {% for att in values['changed'] %}
- {{ att.1.filename|linebreaksbr }}
- {% endfor %}
- {% endif %}
+ {% endfor %}
+ {% endif %}
- {% if values.deleted %}
+ {% if values.deleted %}
* {{ _("Deleted") }}
- {% for att in values['deleted']%}
+ {% for att in values['deleted']%}
- {{ att.filename|linebreaksbr }}
- {% endfor %}
- {% endif %}
-{# TAGS AND WATCHERS #}
- {% elif field_name in ["tags", "watchers"] %}
+ {% endfor %}
+ {% endif %}
+ {# TAGS AND WATCHERS #}
+ {% elif field_name in ["tags", "watchers"] %}
* to: {{ ', '.join(values.1)|linebreaksbr }}
- {% if values.0 %}
+ {% if values.0 %}
* from: {{ ', '.join(values.0)|linebreaksbr }}
- {% endif %}
-{# * #}
- {% else %}
- {% if values.1 != None or values.1 != "" %}
+ {% endif %}
+ {# * #}
+ {% else %}
+ {% if values.1 != None and values.1 != "" %}
* to: {{ values.1|linebreaksbr }}
- {% endif %}
- {% if values.0 != None or values.0 != "" %}
+ {% endif %}
+ {% if values.0 != None and values.0 != "" %}
* from: {{ values.0|linebreaksbr }}
+ {% endif %}
{% endif %}
{% endif %}
{% endfor %}
diff --git a/taiga/projects/history/templatetags/functions.py b/taiga/projects/history/templatetags/functions.py
index b5da0051..07e7dcd3 100644
--- a/taiga/projects/history/templatetags/functions.py
+++ b/taiga/projects/history/templatetags/functions.py
@@ -14,13 +14,23 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
+from django.utils.translation import ugettext_lazy as _
+
from django_jinja import library
register = library.Library()
+EXTRA_FIELD_VERBOSE_NAMES = {
+ "description_diff": _("description"),
+}
+
+
@register.global_function
def verbose_name(obj:object, field_name:str) -> str:
+ if field_name in EXTRA_FIELD_VERBOSE_NAMES:
+ return EXTRA_FIELD_VERBOSE_NAMES[field_name]
+
try:
return obj._meta.get_field(field_name).verbose_name
except Exception: