from django.contrib.auth.mixins import LoginRequiredMixin from django.db import models from django.shortcuts import get_object_or_404, render from django.urls import reverse_lazy from django.views.generic import CreateView, DeleteView, DetailView, ListView, UpdateView, View from apps.core.permissions import AdminRequiredMixin from apps.issues.models import Issue, IssueComment class IssueListView(LoginRequiredMixin, ListView): model = Issue template_name = "pages/issues/issue_list.html" context_object_name = "issues" paginate_by = 20 def get_queryset(self): user = self.request.user qs = Issue.objects.select_related("project", "assignee", "reporter") if user.is_admin(): return qs.all() if user.is_client(): return qs.filter(project__client=user) return qs.filter(models.Q(assignee=user) | models.Q(reporter=user)) class IssueDetailView(LoginRequiredMixin, DetailView): model = Issue template_name = "pages/issues/issue_detail.html" context_object_name = "issue" def get_queryset(self): user = self.request.user qs = Issue.objects.select_related("project", "assignee", "reporter") if user.is_admin(): return qs.all() if user.is_client(): return qs.filter(project__client=user) return qs.filter(models.Q(assignee=user) | models.Q(reporter=user)) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["comments"] = self.object.comments.select_related("author").all() return context class IssueCreateView(LoginRequiredMixin, CreateView): model = Issue template_name = "pages/issues/issue_form.html" fields = ["project", "title", "description", "priority", "assignee"] def form_valid(self, form): form.instance.reporter = self.request.user return super().form_valid(form) def get_success_url(self): return reverse_lazy("issue_detail", kwargs={"pk": self.object.pk}) class IssueUpdateView(LoginRequiredMixin, UpdateView): model = Issue template_name = "pages/issues/issue_form.html" fields = ["title", "description", "status", "priority", "assignee"] def get_success_url(self): return reverse_lazy("issue_detail", kwargs={"pk": self.object.pk}) class IssueDeleteView(AdminRequiredMixin, DeleteView): model = Issue template_name = "pages/issues/issue_confirm_delete.html" success_url = reverse_lazy("issue_list") class IssueCommentCreateView(LoginRequiredMixin, View): def post(self, request, issue_pk): issue = get_object_or_404(Issue, pk=issue_pk) body = request.POST.get("body", "") if body: IssueComment.objects.create(issue=issue, author=request.user, body=body) if request.htmx: return render(request, "partials/issues/comment_list.html", {"comments": issue.comments.all()}) return render(request, "pages/issues/issue_detail.html", {"issue": issue, "comments": issue.comments.all()})