Add comment and reply functionality with preview and notification templates

This commit is contained in:
pacnpal
2025-02-07 13:13:49 -05:00
parent 2c4d2daf34
commit 0e0ed01cee
30 changed files with 5153 additions and 383 deletions

View File

@@ -1,9 +1,11 @@
# history_tracking/mixins.py
from django.db import models
from django.conf import settings
from django.contrib.contenttypes.fields import GenericRelation
class HistoricalChangeMixin(models.Model):
"""Mixin for historical models to track changes"""
comments = GenericRelation('CommentThread', related_query_name='historical_record')
id = models.BigIntegerField(db_index=True, auto_created=True, blank=True)
history_date = models.DateTimeField()
history_id = models.AutoField(primary_key=True)
@@ -33,6 +35,7 @@ class HistoricalChangeMixin(models.Model):
@property
def diff_against_previous(self):
"""Get enhanced diff with syntax highlighting and metadata"""
prev_record = self.prev_record
if not prev_record:
return {}
@@ -54,11 +57,69 @@ class HistoricalChangeMixin(models.Model):
old_value = getattr(prev_record, field)
new_value = getattr(self, field)
if old_value != new_value:
changes[field] = {"old": str(old_value), "new": str(new_value)}
field_type = self._meta.get_field(field).get_internal_type()
syntax_type = self._get_syntax_type(field_type)
changes[field] = {
"old": str(old_value),
"new": str(new_value),
"syntax_type": syntax_type,
"metadata": {
"field_type": field_type,
"comment_anchor_id": f"{self.history_id}_{field}",
"line_numbers": self._compute_line_numbers(old_value, new_value)
}
}
except AttributeError:
continue
return changes
def _get_syntax_type(self, field_type):
"""Map Django field types to syntax highlighting types"""
syntax_map = {
'TextField': 'text',
'JSONField': 'json',
'FileField': 'path',
'ImageField': 'path',
'URLField': 'url',
'EmailField': 'email',
'CodeField': 'python' # Custom field type for code
}
return syntax_map.get(field_type, 'text')
def _compute_line_numbers(self, old_value, new_value):
"""Compute line numbers for diff navigation"""
old_lines = str(old_value).count('\n') + 1
new_lines = str(new_value).count('\n') + 1
return {
"old": list(range(1, old_lines + 1)),
"new": list(range(1, new_lines + 1))
}
def get_structured_diff(self, other_version=None):
"""Get structured diff between two versions with enhanced metadata"""
compare_to = other_version or self.prev_record
if not compare_to:
return None
diff_data = self.diff_against_previous
return {
"changes": diff_data,
"metadata": {
"timestamp": self.history_date.isoformat(),
"user": self.history_user_display,
"change_type": self.history_type,
"reason": self.history_change_reason,
"performance": {
"computation_time": None # To be filled by frontend
}
},
"navigation": {
"next_id": None, # To be filled by frontend
"prev_id": None, # To be filled by frontend
"current_position": None # To be filled by frontend
}
}
@property
def history_user_display(self):
"""Get a display name for the history user"""