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 2d86404e..fd859948 100644
--- a/taiga/projects/history/templates/emails/includes/fields_diff-html.jinja
+++ b/taiga/projects/history/templates/emails/includes/fields_diff-html.jinja
@@ -91,19 +91,23 @@
{% elif field_name in ["tags", "watchers"] %}
{% set values_from = values.0 or [] %}
{% set values_to = values.1 or [] %}
+ {% set values_added = lists_diff(values_to, values_from) %}
+ {% set values_removed = lists_diff(values_from, values_to) %}
+
- {{ field_name }}
+ {{ verbose_name(obj_class, field_name) }}
|
- {{ _("from") }}
- {{ ', '.join(values_from) }}
- |
-
-
-
- {{ _("to") }}
- {{ ', '.join(values_to) }}
+ {% if values_added %}
+ {{ _("added") }}
+ {{ ', '.join(values_added) }}
+ {% endif %}
+
+ {% if values_removed %}
+ {{ _("removed") }}
+ {{ ', '.join(values_removed) }}
+ {% endif %}
|
{# DESCRIPTIONS #}
@@ -126,7 +130,7 @@
{% elif field_name == "assigned_to" %}
- {{ field_name }}
+ {{ verbose_name(obj_class, field_name) }}
|
{% if values.0 != None and values.0 != "" %}
@@ -154,7 +158,7 @@
|
- {{ field_name }}
+ {{ verbose_name(obj_class, field_name) }}
|
{{ _("from") }}
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 b2d23b7c..206e237c 100644
--- a/taiga/projects/history/templates/emails/includes/fields_diff-text.jinja
+++ b/taiga/projects/history/templates/emails/includes/fields_diff-text.jinja
@@ -12,7 +12,7 @@
] %}
{% for field_name, values in changed_fields.items() %}
{% if field_name not in excluded_fields %}
- - {{ verbose_name(object, field_name) }}:
+ - {{ verbose_name(obj_class, field_name) }}:
{# POINTS #}
{% if field_name == "points" %}
{% for role, points in values.items() %}
@@ -42,17 +42,16 @@
{% endif %}
{# TAGS AND WATCHERS #}
{% elif field_name in ["tags", "watchers"] %}
- * {{ _("to:") }} {{ ', '.join(values.1) }}
- {% if values.0 %}
- * {{ _("from:") }} {{ ', '.join(values.0) }}
+ {% set values_from = values.0 or [] %}
+ {% set values_to = values.1 or [] %}
+ {% set values_added = lists_diff(values_to, values_from) %}
+ {% set values_removed = lists_diff(values_from, values_to) %}
+
+ {% if values_added %}
+ * {{ _("added:") }} {{ ', '.join(values_added) }}
{% endif %}
- {# * #}
- {% else %}
- {% if values.1 != None and values.1 != "" %}
- * {{ _("to:") }} {{ values.1|linebreaksbr }}
- {% endif %}
- {% if values.0 != None and values.0 != "" %}
- * {{ _("from:") }} {{ values.0|linebreaksbr }}
+ {% if values_removed %}
+ * {{ _("removed:") }} {{ ', '.join(values_removed) }}
{% endif %}
{% endif %}
{% endif %}
diff --git a/taiga/projects/history/templatetags/functions.py b/taiga/projects/history/templatetags/functions.py
index 1938bb94..eef5133b 100644
--- a/taiga/projects/history/templatetags/functions.py
+++ b/taiga/projects/history/templatetags/functions.py
@@ -29,11 +29,15 @@ EXTRA_FIELD_VERBOSE_NAMES = {
@register.global_function
-def verbose_name(obj:object, field_name:str) -> str:
+def verbose_name(obj_class, field_name):
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
+ return obj_class._meta.get_field(field_name).verbose_name
except Exception:
return field_name
+
+@register.global_function
+def lists_diff(list1, list2):
+ return (list(set(list1) - set(list2)))
diff --git a/taiga/projects/notifications/services.py b/taiga/projects/notifications/services.py
index 8accc657..67d0e352 100644
--- a/taiga/projects/notifications/services.py
+++ b/taiga/projects/notifications/services.py
@@ -249,8 +249,10 @@ def send_sync_notifications(notification_id):
history_entries = tuple(notification.history_entries.all().order_by("created_at"))
obj, _ = get_last_snapshot_for_key(notification.key)
+ obj_class = get_model_from_key(obj.key)
context = {
+ "obj_class": obj_class,
"snapshot": obj.snapshot,
"project": notification.project,
"changer": notification.owner,
|