Add rich text custom field

remotes/origin/issue/4795/notification_even_they_are_disabled
Jesús Espino 2016-11-22 08:30:59 +01:00 committed by David Barragán Merino
parent 3e2226e41f
commit 2c170f3d04
7 changed files with 86 additions and 45 deletions

View File

@ -1,11 +1,17 @@
# Changelog # # Changelog #
## 3.1.0 ¿¿?? (¿¿??)
## 3.1.0 unnamed (unreleased)
### Features ### Features
- Contact with the project: if the projects have this module enabled Taiga users can contact them. - 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 - 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 - 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) ## 3.0.0 Stellaria Borealis (2016-10-02)

View File

@ -167,7 +167,7 @@ class DiffMatchPatch(diff_match_patch.diff_match_patch):
def get_diff_of_htmls(html1, html2): def get_diff_of_htmls(html1, html2):
diffutil = DiffMatchPatch() diffutil = DiffMatchPatch()
diffs = diffutil.diff_main(html1, html2) diffs = diffutil.diff_main(html1 or "", html2 or "")
diffutil.diff_cleanupSemantic(diffs) diffutil.diff_cleanupSemantic(diffs)
return diffutil.diff_pretty_html(diffs) return diffutil.diff_pretty_html(diffs)

View File

@ -21,12 +21,14 @@ from django.utils.translation import ugettext_lazy as _
TEXT_TYPE = "text" TEXT_TYPE = "text"
MULTILINE_TYPE = "multiline" MULTILINE_TYPE = "multiline"
RICHTEXT_TYPE = "richtext"
DATE_TYPE = "date" DATE_TYPE = "date"
URL_TYPE = "url" URL_TYPE = "url"
TYPES_CHOICES = ( TYPES_CHOICES = (
(TEXT_TYPE, _("Text")), (TEXT_TYPE, _("Text")),
(MULTILINE_TYPE, _("Multi-Line Text")), (MULTILINE_TYPE, _("Multi-Line Text")),
(RICHTEXT_TYPE, _("Rich text")),
(DATE_TYPE, _("Date")), (DATE_TYPE, _("Date")),
(URL_TYPE, _("Url")) (URL_TYPE, _("Url"))
) )

View File

@ -214,7 +214,8 @@ def extract_epic_custom_attributes(obj) -> list:
value = custom_attributes_values[str(attr.id)] value = custom_attributes_values[str(attr.id)]
yield {"id": attr.id, yield {"id": attr.id,
"name": attr.name, "name": attr.name,
"value": value} "value": value,
"type": attr.type}
@as_tuple @as_tuple
@ -226,7 +227,8 @@ def extract_user_story_custom_attributes(obj) -> list:
value = custom_attributes_values[str(attr.id)] value = custom_attributes_values[str(attr.id)]
yield {"id": attr.id, yield {"id": attr.id,
"name": attr.name, "name": attr.name,
"value": value} "value": value,
"type": attr.type}
@as_tuple @as_tuple
@ -238,7 +240,8 @@ def extract_task_custom_attributes(obj) -> list:
value = custom_attributes_values[str(attr.id)] value = custom_attributes_values[str(attr.id)]
yield {"id": attr.id, yield {"id": attr.id,
"name": attr.name, "name": attr.name,
"value": value} "value": value,
"type": attr.type}
@as_tuple @as_tuple
@ -250,7 +253,8 @@ def extract_issue_custom_attributes(obj) -> list:
value = custom_attributes_values[str(attr.id)] value = custom_attributes_values[str(attr.id)]
yield {"id": attr.id, yield {"id": attr.id,
"name": attr.name, "name": attr.name,
"value": value} "value": value,
"type": attr.type}
def project_freezer(project) -> dict: def project_freezer(project) -> dict:

View File

@ -30,6 +30,7 @@ from .choices import HistoryType
from .choices import HISTORY_TYPE_CHOICES from .choices import HISTORY_TYPE_CHOICES
from taiga.base.utils.diff import make_diff as make_diff_from_dicts 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 # 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 # 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], changes = make_diff_from_dicts(oldcustattrs[aid], newcustattrs[aid],
excluded_keys=("name")) excluded_keys=("name"))
newcustattr = newcustattrs.get(aid, {})
if changes: 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 = { change = {
"name": newcustattrs.get(aid, {}).get("name", ""), "name": newcustattr.get("name", ""),
"changes": changes "changes": changes,
"type": change_type,
"value_diff": value_diff
} }
custom_attributes["changed"].append(change) custom_attributes["changed"].append(change)
elif aid in oldcustattrs and aid not in newcustattrs: elif aid in oldcustattrs and aid not in newcustattrs:
custom_attributes["deleted"].append(oldcustattrs[aid]) custom_attributes["deleted"].append(oldcustattrs[aid])
elif aid not in oldcustattrs and aid in newcustattrs: 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]) custom_attributes["new"].append(newcustattrs[aid])
if custom_attributes["new"] or custom_attributes["changed"] or custom_attributes["deleted"]: if custom_attributes["new"] or custom_attributes["changed"] or custom_attributes["deleted"]:

View File

@ -170,6 +170,14 @@
{# CUSTOM ATTRIBUTES #} {# CUSTOM ATTRIBUTES #}
{% if values.new %} {% if values.new %}
{% for attr in values['new']%} {% for attr in values['new']%}
{% if attr.type == "richtext" %}
<tr>
<td colspan="2">
<h3>{{ attr.name }}</h3>
<p>{{ mdrender(project, attr.value_diff) }}</p>
</td>
</tr>
{% else %}
<tr> <tr>
<td valign="middle" rowspan="2" class="update-row-name"> <td valign="middle" rowspan="2" class="update-row-name">
<h3>{{ attr.name }}</h3> <h3>{{ attr.name }}</h3>
@ -181,11 +189,20 @@
<strong>{{ attr.value|linebreaksbr }}</strong> <strong>{{ attr.value|linebreaksbr }}</strong>
</td> </td>
</tr> </tr>
{% endif %}
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% if values.changed %} {% if values.changed %}
{% for attr in values['changed'] %} {% for attr in values['changed'] %}
{% if attr.changes.value%} {% if attr.changes.value%}
{% if attr.type == "richtext" %}
<tr>
<td colspan="2">
<h3>{{ attr.name }}</h3>
<p>{{ mdrender(project, attr.value_diff) }}</p>
</td>
</tr>
{% else %}
<tr> <tr>
<td valign="middle" rowspan="2" class="update-row-name"> <td valign="middle" rowspan="2" class="update-row-name">
<h3>{{ attr.name }}</h3> <h3>{{ attr.name }}</h3>
@ -202,6 +219,7 @@
</td> </td>
</tr> </tr>
{% endif %} {% endif %}
{% endif %}
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% if values.deleted %} {% if values.deleted %}

View File

@ -66,9 +66,9 @@
{% elif field_name == "custom_attributes" %} {% elif field_name == "custom_attributes" %}
{# CUSTOM ATTRIBUTES #} {# CUSTOM ATTRIBUTES #}
{% elif field_name == "attachments" %}
{% if values.new %} {% if values.new %}
{% for attr in values['new']%} {% for attr in values['new']%}
- {{ attr.name }}: - {{ attr.name }}:
* {{ attr.value }} * {{ attr.value }}
{% endfor %} {% endfor %}