Merge pull request #885 from taigaio/rich-text-custom-fields

Rich text custom fields
remotes/origin/issue/4795/notification_even_they_are_disabled
David Barragán Merino 2016-11-24 20:05:03 +01:00 committed by GitHub
commit 86897d3469
7 changed files with 86 additions and 45 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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"))
)

View File

@ -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:

View File

@ -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"]:

View File

@ -170,40 +170,58 @@
{# CUSTOM ATTRIBUTES #}
{% if values.new %}
{% for attr in values['new']%}
<tr>
<td valign="middle" rowspan="2" class="update-row-name">
<h3>{{ attr.name }}</h3>
</td>
</tr>
<tr>
<td valign="top">
<span>{{ _("to") }}</span><br>
<strong>{{ attr.value|linebreaksbr }}</strong>
</td>
</tr>
{% endfor %}
{% endif %}
{% if values.changed %}
{% for attr in values['changed'] %}
{% 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>
<td valign="middle" rowspan="2" class="update-row-name">
<h3>{{ attr.name }}</h3>
</td>
<td valign="top" class="update-row-from">
<span>{{ _("from") }}</span><br>
<strong>{{ attr.changes.value.0|linebreaksbr }}</strong>
</td>
</tr>
<tr>
<td valign="top">
<span>{{ _("to") }}</span><br>
<strong>{{ attr.changes.value.1|linebreaksbr }}</strong>
<strong>{{ attr.value|linebreaksbr }}</strong>
</td>
</tr>
{% endif %}
{% endfor %}
{% endif %}
{% if values.changed %}
{% for attr in values['changed'] %}
{% 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>
<td valign="middle" rowspan="2" class="update-row-name">
<h3>{{ attr.name }}</h3>
</td>
<td valign="top" class="update-row-from">
<span>{{ _("from") }}</span><br>
<strong>{{ attr.changes.value.0|linebreaksbr }}</strong>
</td>
</tr>
<tr>
<td valign="top">
<span>{{ _("to") }}</span><br>
<strong>{{ attr.changes.value.1|linebreaksbr }}</strong>
</td>
</tr>
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{% if values.deleted %}
{% for attr in values['deleted']%}
<tr>

View File

@ -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 %}