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']%} -
{{ mdrender(project, attr.value_diff) }}
+{{ mdrender(project, attr.value_diff) }}
+