From 2c170f3d04629939c376bce8d666139d0a912090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Tue, 22 Nov 2016 08:30:59 +0100 Subject: [PATCH] Add rich text custom field --- CHANGELOG.md | 12 +++- taiga/mdrender/service.py | 2 +- taiga/projects/custom_attributes/choices.py | 2 + taiga/projects/history/freeze_impl.py | 14 +++-- taiga/projects/history/models.py | 15 ++++- .../emails/includes/fields_diff-html.jinja | 60 ++++++++++++------- .../emails/includes/fields_diff-text.jinja | 26 ++++---- 7 files changed, 86 insertions(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 88c5c4a3..08e9819c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,17 @@ # Changelog # -## 3.1.0 ¿¿?? (¿¿??) + +## 3.1.0 unnamed (unreleased) ### Features - Contact with the project: if the projects have this module enabled Taiga users can contact them. -- Memberships API endpoints now allows using usernames and emails instead of using only emails -- Contacts API search by free text: consulting the username, full name and email +- Memberships API endpoints now allows using usernames and emails instead of using only emails. +- Contacts API search by free text: consulting the username, full name and email. +- Ability to create rich text custom fields in Epics, User Stories, Tasks and Isues. + +### Misc +- Lots of small and not so small bugfixes. + ## 3.0.0 Stellaria Borealis (2016-10-02) diff --git a/taiga/mdrender/service.py b/taiga/mdrender/service.py index 701ed0d4..c24454e4 100644 --- a/taiga/mdrender/service.py +++ b/taiga/mdrender/service.py @@ -167,7 +167,7 @@ class DiffMatchPatch(diff_match_patch.diff_match_patch): def get_diff_of_htmls(html1, html2): diffutil = DiffMatchPatch() - diffs = diffutil.diff_main(html1, html2) + diffs = diffutil.diff_main(html1 or "", html2 or "") diffutil.diff_cleanupSemantic(diffs) return diffutil.diff_pretty_html(diffs) diff --git a/taiga/projects/custom_attributes/choices.py b/taiga/projects/custom_attributes/choices.py index d03ce070..355cf4d1 100644 --- a/taiga/projects/custom_attributes/choices.py +++ b/taiga/projects/custom_attributes/choices.py @@ -21,12 +21,14 @@ from django.utils.translation import ugettext_lazy as _ TEXT_TYPE = "text" MULTILINE_TYPE = "multiline" +RICHTEXT_TYPE = "richtext" DATE_TYPE = "date" URL_TYPE = "url" TYPES_CHOICES = ( (TEXT_TYPE, _("Text")), (MULTILINE_TYPE, _("Multi-Line Text")), + (RICHTEXT_TYPE, _("Rich text")), (DATE_TYPE, _("Date")), (URL_TYPE, _("Url")) ) diff --git a/taiga/projects/history/freeze_impl.py b/taiga/projects/history/freeze_impl.py index 027691b6..159d7a3f 100644 --- a/taiga/projects/history/freeze_impl.py +++ b/taiga/projects/history/freeze_impl.py @@ -208,13 +208,14 @@ def extract_attachments(obj) -> list: @as_tuple def extract_epic_custom_attributes(obj) -> list: with suppress(ObjectDoesNotExist): - custom_attributes_values = obj.custom_attributes_values.attributes_values + custom_attributes_values = obj.custom_attributes_values.attributes_values for attr in obj.project.epiccustomattributes.all(): with suppress(KeyError): value = custom_attributes_values[str(attr.id)] yield {"id": attr.id, "name": attr.name, - "value": value} + "value": value, + "type": attr.type} @as_tuple @@ -226,7 +227,8 @@ def extract_user_story_custom_attributes(obj) -> list: value = custom_attributes_values[str(attr.id)] yield {"id": attr.id, "name": attr.name, - "value": value} + "value": value, + "type": attr.type} @as_tuple @@ -238,7 +240,8 @@ def extract_task_custom_attributes(obj) -> list: value = custom_attributes_values[str(attr.id)] yield {"id": attr.id, "name": attr.name, - "value": value} + "value": value, + "type": attr.type} @as_tuple @@ -250,7 +253,8 @@ def extract_issue_custom_attributes(obj) -> list: value = custom_attributes_values[str(attr.id)] yield {"id": attr.id, "name": attr.name, - "value": value} + "value": value, + "type": attr.type} def project_freezer(project) -> dict: diff --git a/taiga/projects/history/models.py b/taiga/projects/history/models.py index 9f60b0ab..1a2ded60 100644 --- a/taiga/projects/history/models.py +++ b/taiga/projects/history/models.py @@ -30,6 +30,7 @@ from .choices import HistoryType from .choices import HISTORY_TYPE_CHOICES from taiga.base.utils.diff import make_diff as make_diff_from_dicts +from taiga.projects.custom_attributes.choices import TEXT_TYPE # This keys has been removed from freeze_impl so we can have objects where the # previous diff has value for the attribute and we want to prevent their propagation @@ -250,15 +251,25 @@ class HistoryEntry(models.Model): changes = make_diff_from_dicts(oldcustattrs[aid], newcustattrs[aid], excluded_keys=("name")) + newcustattr = newcustattrs.get(aid, {}) if changes: + change_type = newcustattr.get("type", TEXT_TYPE) + old_value = oldcustattrs[aid].get("value", "") + new_value = newcustattrs[aid].get("value", "") + value_diff = get_diff_of_htmls(old_value, new_value) change = { - "name": newcustattrs.get(aid, {}).get("name", ""), - "changes": changes + "name": newcustattr.get("name", ""), + "changes": changes, + "type": change_type, + "value_diff": value_diff } custom_attributes["changed"].append(change) elif aid in oldcustattrs and aid not in newcustattrs: custom_attributes["deleted"].append(oldcustattrs[aid]) elif aid not in oldcustattrs and aid in newcustattrs: + new_value = newcustattrs[aid].get("value", "") + value_diff = get_diff_of_htmls("", new_value) + newcustattrs[aid]["value_diff"] = value_diff custom_attributes["new"].append(newcustattrs[aid]) if custom_attributes["new"] or custom_attributes["changed"] or custom_attributes["deleted"]: 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 eadca5c3..1f7fa5ce 100644 --- a/taiga/projects/history/templates/emails/includes/fields_diff-html.jinja +++ b/taiga/projects/history/templates/emails/includes/fields_diff-html.jinja @@ -170,40 +170,58 @@ {# CUSTOM ATTRIBUTES #} {% if values.new %} {% for attr in values['new']%} - - -

{{ attr.name }}

- - - - - {{ _("to") }}
- {{ attr.value|linebreaksbr }} - - - {% endfor %} - {% endif %} - {% if values.changed %} - {% for attr in values['changed'] %} - {% if attr.changes.value%} + {% if attr.type == "richtext" %} + + +

{{ attr.name }}

+

{{ mdrender(project, attr.value_diff) }}

+ + + {% else %}

{{ attr.name }}

- - {{ _("from") }}
- {{ attr.changes.value.0|linebreaksbr }} - {{ _("to") }}
- {{ attr.changes.value.1|linebreaksbr }} + {{ attr.value|linebreaksbr }} {% endif %} {% endfor %} {% endif %} + {% if values.changed %} + {% for attr in values['changed'] %} + {% if attr.changes.value%} + {% if attr.type == "richtext" %} + + +

{{ attr.name }}

+

{{ mdrender(project, attr.value_diff) }}

+ + + {% else %} + + +

{{ attr.name }}

+ + + {{ _("from") }}
+ {{ attr.changes.value.0|linebreaksbr }} + + + + + {{ _("to") }}
+ {{ attr.changes.value.1|linebreaksbr }} + + + {% endif %} + {% endif %} + {% endfor %} + {% endif %} {% if values.deleted %} {% for attr in values['deleted']%} 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 ff0a1b0d..dd2975aa 100644 --- a/taiga/projects/history/templates/emails/includes/fields_diff-text.jinja +++ b/taiga/projects/history/templates/emails/includes/fields_diff-text.jinja @@ -66,27 +66,27 @@ {% elif field_name == "custom_attributes" %} {# CUSTOM ATTRIBUTES #} - {% elif field_name == "attachments" %} - {% if values.new %} - {% for attr in values['new']%} + {% if values.new %} + {% for attr in values['new']%} + - {{ attr.name }}: * {{ attr.value }} - {% endfor %} - {% endif %} + {% endfor %} + {% endif %} - {% if values.changed %} - {% for attr in values['changed'] %} + {% if values.changed %} + {% for attr in values['changed'] %} - {{ attr.name }}: * {{ _("From:") }} {{ attr.changes.value.0 }} * {{ _("To:") }} {{ attr.changes.value.1 }} - {% endfor %} - {% endif %} + {% endfor %} + {% endif %} - {% if values.deleted %} - {% for attr in values['deleted']%} + {% if values.deleted %} + {% for attr in values['deleted']%} - {{ attr.name }}: {{ _("-deleted-") }} * {{ attr.value }} - {% endfor %} - {% endif %} + {% endfor %} + {% endif %} {% endif %} {% endfor %}