diff --git a/anytask/issues/admin.py b/anytask/issues/admin.py
index 67969fe01..d221bbeb3 100644
--- a/anytask/issues/admin.py
+++ b/anytask/issues/admin.py
@@ -2,7 +2,7 @@
from issues.model_issue_field import IssueField
from issues.model_issue_status import IssueStatus, IssueStatusSystem
-from issues.models import Issue, Event
+from issues.models import Issue, Event, EventChange
from django.contrib import admin
from django.utils.translation import ugettext as _
@@ -58,8 +58,14 @@ class EventAdmin(admin.ModelAdmin):
readonly_fields = ('timestamp',)
+class EventChangeAdmin(admin.ModelAdmin):
+ raw_id_fields = ['event']
+ search_fields = ('event__id', )
+
+
admin.site.register(Issue)
admin.site.register(Event, EventAdmin)
+admin.site.register(EventChange, EventChangeAdmin)
admin.site.register(IssueField)
admin.site.register(IssueStatus, IssueStatusAdmin)
admin.site.register(IssueStatusSystem, IssueStatusSystemAdmin)
diff --git a/anytask/issues/migrations/0008_eventchange.py b/anytask/issues/migrations/0008_eventchange.py
new file mode 100644
index 000000000..451a20a10
--- /dev/null
+++ b/anytask/issues/migrations/0008_eventchange.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.29 on 2021-05-14 23:05
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('issues', '0007_auto_20210228_1721'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='EventChange',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('old_value', models.TextField(blank=True, max_length=2500)),
+ ('timestamp', models.DateTimeField(auto_now=True)),
+ ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='issues.Event')),
+ ],
+ ),
+ ]
diff --git a/anytask/issues/models.py b/anytask/issues/models.py
index f78800e3f..8ff4c08d1 100644
--- a/anytask/issues/models.py
+++ b/anytask/issues/models.py
@@ -557,6 +557,10 @@ def get_notify_message(self):
message.append(', '.join(file_list))
return u'\n'.join(message)
+ def get_history(self):
+ history = EventChange.objects.filter(event_id=self.id)
+ return history
+
def is_comment(self):
return self.field.name == 'comment'
@@ -579,6 +583,17 @@ def __unicode__(self):
return ret
+class EventChange(models.Model):
+ event = models.ForeignKey(Event, null=False, blank=False)
+
+ old_value = models.TextField(max_length=2500, blank=True)
+ timestamp = models.DateTimeField(auto_now=True)
+
+ def __unicode__(self):
+ ret = u'Change in event {0}, issue {1}'.format(self.event.id, self.event.issue.id)
+ return ret
+
+
@receiver(models.signals.post_save, sender=Issue)
def post_create_set_default_teacher(sender, instance, created, *args, **kwargs):
if created:
diff --git a/anytask/issues/templates/file_uploader.html b/anytask/issues/templates/file_uploader.html
index 70f068b0e..fd0198f52 100644
--- a/anytask/issues/templates/file_uploader.html
+++ b/anytask/issues/templates/file_uploader.html
@@ -66,6 +66,7 @@
+
{% block UPLOAD_FORM_BUTTON_BAR %}
{% comment %}
@@ -138,11 +139,16 @@
{% else %}
-
{% block UPLOAD_FORM_PROGRESS_BAR %}
{% comment %}
diff --git a/anytask/issues/templates/issues/event_history.html b/anytask/issues/templates/issues/event_history.html
new file mode 100644
index 000000000..6bee013eb
--- /dev/null
+++ b/anytask/issues/templates/issues/event_history.html
@@ -0,0 +1,25 @@
+{% load link_to_open %}
+{% load i18n %}
+{% load tz %}
+{% load info %}
+{% get_current_language as LANGUAGE_CODE %}
+
+{% load sanitize_html %}
+
+
+ {% for event_change in event_history %}
+ History
+
+
+
+ {% autoescape off %}
+ {{ event_change.old_value|sanitize }}
+ {% endautoescape %}
+
+
+
+ {% endfor %}
+ {% if not issue.get_history %}
+ {% trans "zdes_nichego_net" %}
+ {% endif %}
+
diff --git a/anytask/issues/templates/issues/history.html b/anytask/issues/templates/issues/history.html
index 2d8dc1022..cefd2e137 100644
--- a/anytask/issues/templates/issues/history.html
+++ b/anytask/issues/templates/issues/history.html
@@ -89,8 +89,25 @@ {% trans "obsuzhdenie_zadachi" %}
{{ event.author.last_name }} {{ event.author.first_name }}
- {% localtime on %} {{ event.timestamp|date:"d M H:i" }} {% endlocaltime %}
+ {% localtime on %} {{ event.timestamp|date:"d M H:i:s" }} {% endlocaltime %}
+
+ {% if event.author == user %} {# start edit message elements #}
+
+
+
+
+
+ {% endif %} {# end edit message elements #}
+
+ {# start message history elements #}
+
+
+
+
+
+ {# end message history elements #}
+
+
+ {# message history #}
+
+
Message history:
+ {% for event_change in event.get_history %}
+
+
+
+ {% localtime on %} {{ event_change.timestamp|date:"d M H:i:s" }} {% endlocaltime %}
+
+
+
+
+
+ {% autoescape off %}
+ {{ event_change.old_value|sanitize }}
+ {% endautoescape %}
+
+
+
+ {% endfor %}
+
{% if event.is_omg %}
{{ event.field.title }} changed to {{ event.value }} by {{ event.author.last_name }} {{ event.author.first_name }}
diff --git a/anytask/issues/templates/issues/issue_js.html b/anytask/issues/templates/issues/issue_js.html
index 71761dc0e..85910e031 100644
--- a/anytask/issues/templates/issues/issue_js.html
+++ b/anytask/issues/templates/issues/issue_js.html
@@ -221,5 +221,51 @@
$("#file_field").append('| ' + files + ' |
');
}
+ function start_edit_msg(event_id) {
+ // set value
+ tmp = $('#message_' + event_id).clone()[0];
+ files_tag = Array.from(tmp.children)
+ .filter(el => el.className == "files")[0];
+ if (files_tag) tmp.removeChild(files_tag);
+ $('#id_comment').val(tmp.innerHTML);
+
+ // set message edit id
+ $('#edit_msg_event_id').val(event_id);
+
+ // hide file upload
+ $('table').last().hide();
+ $('#drop-zone').hide();
+
+ // show cancel button
+ $('#cancel-edit-msg-btn').show();
+
+ // scroll to edit field
+ $('#submit-btn').focus();
+ $('#submit-btn').blur();
+ }
+
+ function end_edit_msg() {
+ // clean edit field
+ $('#id_comment').val("");
+
+ // clean edit message id
+ $('#edit_msg_event_id').val("");
+
+ // show file upload
+ $('table').last().show();
+ $('#drop-zone').show();
+
+ // hide cancel button
+ $('#cancel-edit-msg-btn').hide();
+ }
+
+ function show_edit_history(event_id) {
+ elem = $('#message_' + event_id + '_history');
+ if (elem[0].style.display == "none") {
+ elem.show();
+ } else {
+ elem.hide();
+ }
+ }
diff --git a/anytask/issues/views.py b/anytask/issues/views.py
index 413a32504..8d60a8a9d 100644
--- a/anytask/issues/views.py
+++ b/anytask/issues/views.py
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
import os
from copy import deepcopy
+from difflib import Differ
from django.conf import settings
from django.contrib.auth.decorators import login_required
@@ -19,7 +20,7 @@
from anyrb.common import AnyRB
from issues.model_issue_field import IssueField
from issues.model_issue_status import IssueStatus
-from issues.models import Issue, Event, File
+from issues.models import Issue, Event, File, EventChange
def user_is_teacher_or_staff(user, issue):
@@ -267,8 +268,28 @@ def upload(request):
issue = get_object_or_404(Issue, id=int(request.POST['issue_id']))
if 'update_issue' in request.POST:
+
+ # If event_id in POST, edit message and redirect back
+ if 'event_id' in request.POST and request.POST['event_id'].isdigit():
+ user = request.user
+ event_id = int(request.POST['event_id'])
+ event = get_object_or_404(Event, id=event_id)
+ if event.author != user:
+ raise PermissionDenied
+
+ old_value = event.value
+ new_value = request.POST['comment']
+ history = EventChange.objects.create(
+ event=event,
+ old_value=old_value)
+ history.save()
+ event.value = new_value
+ event.save()
+ return HttpResponsePermanentRedirect("/issue/" + request.POST['issue_id'])
+
event_value = {'files': [], 'comment': '', 'compilers': []}
event_value['comment'] = request.POST['comment']
+
file_counter = 0
for field, value in dict(request.POST).iteritems():
if 'compiler' in field: