Coverage for src / mesh / views / views_journal_section.py: 42%

84 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-03-10 09:11 +0000

1from typing import Any 

2 

3from django.contrib import messages 

4from django.http import HttpRequest, HttpResponse, HttpResponseRedirect 

5from django.shortcuts import get_object_or_404 

6from django.urls import reverse_lazy 

7from django.utils.translation import gettext_lazy as _ 

8from django.views.generic.edit import CreateView, UpdateView 

9 

10from mesh.views.forms.base_forms import DEFAULT_FORM_BUTTONS, FormAction 

11from mesh.views.forms.submission_forms import JournalSectionForm 

12from mesh.views.mixins import RoleMixin 

13 

14from ..models.journal_models import JournalSection 

15from .components.breadcrumb import get_base_breadcrumb 

16from .components.button import Button 

17from .components.tree_node import build_tree_recursive 

18 

19 

20class JournalSectionListView(RoleMixin, CreateView): 

21 """ 

22 View to display all existing sections of the journal. 

23 """ 

24 

25 model = JournalSection 

26 form_class = JournalSectionForm 

27 template_name = "mesh/journal_section_list.html" 

28 

29 # Commenting : get_form should always return a form 

30 # def get_form(self, form_class=None): 

31 # if not self.role_handler.check_rights("can_edit_journal_sections"): 

32 # return None 

33 # return super().get_form(form_class) 

34 

35 def get_form_kwargs(self) -> dict[str, Any]: 

36 kwargs = super().get_form_kwargs() 

37 kwargs["_parents"] = JournalSection.objects.all_journal_sections() 

38 return kwargs 

39 

40 def restrict_dispatch(self, request: HttpRequest, *args, **kwargs) -> bool: 

41 if not self.role_handler.check_rights("can_access_journal_sections"): 

42 return True 

43 

44 if request.method == "POST" and not self.role_handler.check_rights( 

45 "can_edit_journal_sections" 

46 ): 

47 return True 

48 

49 return False 

50 

51 def get_success_url(self) -> str: 

52 return reverse_lazy("mesh:journal_section_list") 

53 

54 def get_context_data(self, *args, **kwargs): 

55 context = super().get_context_data(*args, **kwargs) 

56 

57 context["journal_sections_tree"] = build_tree_recursive(JournalSection.objects) 

58 context["page_title"] = _("Journal sections") 

59 

60 breadcrumb = get_base_breadcrumb() 

61 breadcrumb.add_item( 

62 title=_("Journal sections"), url=reverse_lazy("mesh:journal_section_list") 

63 ) 

64 context["breadcrumb"] = breadcrumb 

65 

66 return context 

67 

68 def form_valid(self, form) -> HttpResponse: 

69 form.instance._user = self.request.user 

70 return super().form_valid(form) 

71 

72 

73class JournalSectionEditView(RoleMixin, UpdateView): 

74 model = JournalSection 

75 form_class = JournalSectionForm 

76 journal_section: JournalSection 

77 template_name = "mesh/forms/submission_journal_section_update.html" 

78 

79 def restrict_dispatch(self, request: HttpRequest, *args, **kwargs) -> bool: 

80 if not self.role_handler.check_rights("can_edit_journal_sections"): 

81 return True 

82 self.journal_section = get_object_or_404(JournalSection, pk=kwargs["pk"]) 

83 return False 

84 

85 def get_success_url(self) -> str: 

86 return reverse_lazy("mesh:journal_section_list") 

87 

88 def get_form(self, form_class=None) -> JournalSectionForm: 

89 form: JournalSectionForm = super().get_form(form_class) 

90 form.buttons = [ 

91 *DEFAULT_FORM_BUTTONS, 

92 Button( 

93 id="form_delete", 

94 title=_("Delete"), 

95 icon_class="fa-trash", 

96 attrs={ 

97 "type": ["submit"], 

98 "class": ["button-error"], 

99 "name": [FormAction.DELETE.value], 

100 }, 

101 ), 

102 ] 

103 return form 

104 

105 def get_form_kwargs(self) -> dict[str, Any]: 

106 kwargs = super().get_form_kwargs() 

107 kwargs["_parents"] = JournalSection.objects.all_journal_sections().exclude( 

108 pk__in=[ 

109 *[c.pk for c in self.journal_section.all_children()], 

110 self.journal_section.pk, 

111 ] 

112 ) 

113 return kwargs 

114 

115 def get_context_data(self, *args, **kwargs): 

116 context = super().get_context_data(*args, **kwargs) 

117 

118 context["journal_section"] = self.journal_section 

119 context["journal_sections_tree"] = build_tree_recursive( 

120 JournalSection.objects, self.journal_section 

121 ) 

122 

123 parent = self.journal_section.parent 

124 if parent is None: 

125 title_button = Button( 

126 id="title-back-to", 

127 title=_("Back to index"), 

128 icon_class="fa-folder-tree", 

129 attrs={ 

130 "href": [reverse_lazy("mesh:journal_section_list")], 

131 "class": ["as-button"], 

132 }, 

133 ) 

134 else: 

135 title_button = Button( 

136 id="title-back-to", 

137 title=_("Back to") + f" {parent.name}", 

138 icon_class="fa-arrow-right-long", 

139 attrs={ 

140 "href": [ 

141 reverse_lazy( 

142 "mesh:submission_journal_section_update", 

143 kwargs={"pk": parent.pk}, 

144 ) 

145 ], 

146 "class": ["as-button"], 

147 }, 

148 ) 

149 context["title_buttons"] = [title_button] 

150 

151 # Generate breadcrumb 

152 breadcrumb = get_base_breadcrumb() 

153 breadcrumb.add_item( 

154 title=_("Journal sections"), url=reverse_lazy("mesh:journal_section_list") 

155 ) 

156 breadcrumb.add_item( 

157 title=self.journal_section.name, 

158 url=reverse_lazy( 

159 "mesh:submission_journal_section_update", 

160 kwargs={"pk": self.journal_section.pk}, 

161 ), 

162 ) 

163 context["breadcrumb"] = breadcrumb 

164 return context 

165 

166 def post(self, request: HttpRequest, *args, **kwargs) -> HttpResponse: 

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) 

175 

176 def form_valid(self, form: JournalSectionForm): 

177 form.instance._user = self.request.user 

178 return super().form_valid(form)