Merge branch 'main' into narl.io

This commit is contained in:
nvrl committed 2026-02-18 03:36:35 +01:00
commit b1a16a4953
6 files changed
+119 -29

No files matched your search

+2
View File
@@ -124,12 +124,14 @@ class Notification(models.Model):
TYPE_CHOICES = [
('reply', 'Reply'),
('mention', 'Mention'),
('ticket', 'Ticket Update'),
]
recipient = models.ForeignKey(User, related_name='notifications', on_delete=models.CASCADE)
actor = models.ForeignKey(User, related_name='actions', on_delete=models.CASCADE)
notification_type = models.CharField(max_length=10, choices=TYPE_CHOICES)
rating = models.ForeignKey(Rating, on_delete=models.CASCADE, null=True, blank=True)
reply = models.ForeignKey(Reply, on_delete=models.CASCADE, null=True, blank=True)
ticket = models.ForeignKey('Ticket', on_delete=models.CASCADE, null=True, blank=True)
is_read = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
+12 -2
View File
@@ -119,13 +119,23 @@ class TicketMessageSerializer(serializers.ModelSerializer):
class TicketSerializer(serializers.ModelSerializer):
username = serializers.CharField(source='user.username', read_only=True)
user_email = serializers.EmailField(source='user.email', read_only=True)
user_avatar = serializers.SerializerMethodField()
messages = TicketMessageSerializer(many=True, read_only=True)
class Meta:
model = Ticket
fields = ['id', 'user', 'username', 'subject', 'description', 'status', 'created_at', 'updated_at', 'messages']
fields = ['id', 'user', 'username', 'user_email', 'user_avatar', 'subject', 'description', 'status', 'created_at', 'updated_at', 'messages']
read_only_fields = ['status', 'user']
def get_user_avatar(self, obj):
if obj.user.avatar:
request = self.context.get('request')
if request:
return request.build_absolute_uri(obj.user.avatar.url)
return obj.user.avatar.url
return None
class AdminUserListSerializer(serializers.ModelSerializer):
ips = serializers.SerializerMethodField()
@@ -155,7 +165,7 @@ class NotificationSerializer(serializers.ModelSerializer):
class Meta:
model = Notification
fields = ['id', 'actor_username', 'actor_avatar', 'notification_type', 'rating', 'reply', 'is_read', 'created_at', 'flavor_name', 'flavor_id']
fields = ['id', 'actor_username', 'actor_avatar', 'notification_type', 'rating', 'reply', 'ticket', 'is_read', 'created_at', 'flavor_name', 'flavor_id']
def get_actor_avatar(self, obj):
if obj.actor.avatar:
+32 -1
View File
@@ -576,7 +576,16 @@ class TicketViewSet(viewsets.ModelViewSet):
return Ticket.objects.filter(user=self.request.user).prefetch_related('messages', 'messages__user').order_by('-updated_at')
def perform_create(self, serializer):
serializer.save(user=self.request.user)
ticket = serializer.save(user=self.request.user)
# Notify all superusers about new ticket
admins = User.objects.filter(is_superuser=True).exclude(pk=self.request.user.pk)
for admin in admins:
Notification.objects.create(
recipient=admin,
actor=self.request.user,
notification_type='ticket',
ticket=ticket
)
@action(detail=True, methods=['post'])
def add_message(self, request, pk=None):
@@ -586,6 +595,28 @@ class TicketViewSet(viewsets.ModelViewSet):
return Response({'error': 'Text is required'}, status=status.HTTP_400_BAD_REQUEST)
msg = TicketMessage.objects.create(ticket=ticket, user=request.user, text=text)
# Notification logic
if request.user.is_superuser:
# Notify the user who opened the ticket
if ticket.user != request.user:
Notification.objects.create(
recipient=ticket.user,
actor=request.user,
notification_type='ticket',
ticket=ticket
)
else:
# Notify all superusers
admins = User.objects.filter(is_superuser=True).exclude(pk=request.user.pk)
for admin in admins:
Notification.objects.create(
recipient=admin,
actor=request.user,
notification_type='ticket',
ticket=ticket
)
return Response(TicketMessageSerializer(msg).data, status=status.HTTP_201_CREATED)
@action(detail=True, methods=['post'], permission_classes=[permissions.IsAdminUser])