Coverage for src / mesh / views / views_journal_section.py: 43%
87 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-07-09 13:14 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-07-09 13:14 +0000
1from typing import Any
3from django.contrib import messages
4from django.contrib.auth.mixins import LoginRequiredMixin
5from django.core.exceptions import PermissionDenied
6from django.http import HttpResponseRedirect
7from django.shortcuts import get_object_or_404
8from django.urls import reverse
9from django.utils.translation import gettext_lazy as _
10from django.views.generic.edit import CreateView, UpdateView
12from mesh.models.orm.journal_models import JournalSection
13from mesh.views.forms.base_forms import DEFAULT_FORM_BUTTONS, FormAction
14from mesh.views.forms.submission_forms import JournalSectionForm
16from .components.breadcrumb import get_base_breadcrumb
17from .components.button import Button
18from .components.tree_node import build_tree_recursive
21class JournalSectionListView(LoginRequiredMixin, CreateView):
22 """
23 View to display all existing sections of the journal.
24 """
26 model = JournalSection
27 form_class = JournalSectionForm
28 template_name = "mesh/journal_section_list.html"
30 # Commenting : get_form should always return a form
31 # def get_form(self, form_class=None):
32 # if not self.role_handler.check_rights("can_edit_journal_sections"):
33 # return None
34 # return super().get_form(form_class)
36 def get_form_kwargs(self) -> dict[str, Any]:
37 kwargs = super().get_form_kwargs()
38 kwargs["_parents"] = JournalSection.objects.all_journal_sections()
39 return kwargs
41 def setup(self, request, *args, **kwargs):
42 super().setup(request, *args, **kwargs)
43 if not self.request.current_role.can_access_journal_sections():
44 raise PermissionDenied
46 def post(self, request, *args, **kwargs):
47 if not self.request.current_role.can_edit_journal_sections():
48 raise PermissionError
49 return super().post(request, *args, **kwargs)
51 def get_success_url(self) -> str:
52 return reverse("mesh:journal_section_list")
54 def get_context_data(self, *args, **kwargs):
55 context = super().get_context_data(*args, **kwargs)
57 context["journal_sections_tree"] = build_tree_recursive(JournalSection.objects)
58 context["page_title"] = _("Journal sections")
60 breadcrumb = get_base_breadcrumb()
61 breadcrumb.add_item(title=_("Journal sections"), url=reverse("mesh:journal_section_list"))
62 context["breadcrumb"] = breadcrumb
64 return context
66 def form_valid(self, form):
67 form.instance._user = self.request.user
68 return super().form_valid(form)
71class JournalSectionEditView(LoginRequiredMixin, UpdateView):
72 model = JournalSection
73 form_class = JournalSectionForm
74 journal_section: JournalSection
75 template_name = "mesh/forms/submission_journal_section_update.html"
77 def setup(self, request, *args, **kwargs):
78 super().setup(request, *args, **kwargs)
79 if not self.request.current_role.can_edit_journal_sections():
80 raise PermissionError
81 self.journal_section = get_object_or_404(JournalSection, pk=kwargs["pk"])
83 def get_success_url(self) -> str:
84 return reverse("mesh:journal_section_list")
86 def get_form(self, form_class=None):
87 form: JournalSectionForm = super().get_form(form_class)
88 form.buttons = [
89 *DEFAULT_FORM_BUTTONS,
90 Button(
91 id="form_delete",
92 title=_("Delete"),
93 icon_class="fa-trash",
94 attrs={
95 "type": ["submit"],
96 "class": ["button-error"],
97 "name": [FormAction.DELETE.value],
98 },
99 ),
100 ]
101 return form
103 def get_form_kwargs(self):
104 kwargs = super().get_form_kwargs()
105 kwargs["_parents"] = JournalSection.objects.all_journal_sections().exclude(
106 pk__in=[
107 *[c.pk for c in self.journal_section.all_children()],
108 self.journal_section.pk,
109 ]
110 )
111 return kwargs
113 def form_valid(self, form):
114 form.instance._user = self.request.user
115 return super().form_valid(form)
117 def get_context_data(self, *args, **kwargs):
118 context = super().get_context_data(*args, **kwargs)
120 context["journal_section"] = self.journal_section
121 context["journal_sections_tree"] = build_tree_recursive(
122 JournalSection.objects, self.journal_section
123 )
125 parent = self.journal_section.parent
126 if parent is None:
127 title_button = Button(
128 id="title-back-to",
129 title=_("Back to index"),
130 icon_class="fa-folder-tree",
131 attrs={
132 "href": [reverse("mesh:journal_section_list")],
133 "class": ["as-button"],
134 },
135 )
136 else:
137 title_button = Button(
138 id="title-back-to",
139 title=_("Back to") + f" {parent.name}",
140 icon_class="fa-arrow-right-long",
141 attrs={
142 "href": [
143 reverse(
144 "mesh:submission_journal_section_update",
145 kwargs={"pk": parent.pk},
146 )
147 ],
148 "class": ["as-button"],
149 },
150 )
151 context["title_buttons"] = [title_button]
153 # Generate breadcrumb
154 breadcrumb = get_base_breadcrumb()
155 breadcrumb.add_item(title=_("Journal sections"), url=reverse("mesh:journal_section_list"))
156 breadcrumb.add_item(
157 title=self.journal_section.name,
158 url=reverse(
159 "mesh:submission_journal_section_update",
160 kwargs={"pk": self.journal_section.pk},
161 ),
162 )
163 context["breadcrumb"] = breadcrumb
164 return context
166 def post(self, request, *args, **kwargs):
167 if FormAction.DELETE.value in request.POST:
168 self.journal_section.delete()
169 messages.success(
170 request,
171 _(f"The journal_section {self.journal_section.name} was successfully deleted."),
172 )
173 return HttpResponseRedirect(self.get_success_url())
174 return super().post(request, *args, **kwargs)