blob: 2f8568be79d0dfe91419ba6b6e8057d24eae9419 [file] [log] [blame]
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +01001# Copyright 2018 The Chromium Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
Copybara854996b2021-09-07 19:36:02 +00004
5"""A servlet for project owners to create a new template"""
6from __future__ import print_function
7from __future__ import division
8from __future__ import absolute_import
9
Copybara854996b2021-09-07 19:36:02 +000010import time
11
12import ezt
13
Copybara854996b2021-09-07 19:36:02 +000014from framework import framework_helpers
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010015from framework import permissions
Copybara854996b2021-09-07 19:36:02 +000016from framework import servlet
17from framework import urls
Copybara854996b2021-09-07 19:36:02 +000018from tracker import field_helpers
19from tracker import template_helpers
Copybara854996b2021-09-07 19:36:02 +000020from tracker import tracker_views
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010021from mrproto import tracker_pb2
Copybara854996b2021-09-07 19:36:02 +000022
23
24class TemplateCreate(servlet.Servlet):
25 """Servlet allowing project owners to create an issue template."""
26
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010027 _MAIN_TAB_MODE = servlet.Servlet.MAIN_TAB_PROCESS
Copybara854996b2021-09-07 19:36:02 +000028 _PAGE_TEMPLATE = 'tracker/template-detail-page.ezt'
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010029 _PROCESS_SUBTAB = servlet.Servlet.PROCESS_TAB_TEMPLATES
Copybara854996b2021-09-07 19:36:02 +000030
31 def AssertBasePermission(self, mr):
32 """Check whether the user has any permission to visit this page.
33
34 Args:
35 mr: commonly used info parsed from the request
36 """
37 super(TemplateCreate, self).AssertBasePermission(mr)
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010038 if not permissions.CanEditProjectConfig(mr, self.services):
Copybara854996b2021-09-07 19:36:02 +000039 raise permissions.PermissionException(
40 'User is not allowed to administer this project')
41
42 def GatherPageData(self, mr):
43 """Build up a dictionary of data values to use when rendering the page.
44
45 Args:
46 mr: commonly used info parsed from the request.
47
48 Returns:
49 Dict of values used by EZT for rendering the page.
50 """
51
52 config = self.services.config.GetProjectConfig(mr.cnxn, mr.project_id)
53 field_views = tracker_views.MakeAllFieldValueViews(
54 config, [], [], [], {})
55 approval_subfields_present = any(
56 fv.field_def.is_approval_subfield for fv in field_views)
57
58 initial_phases = [tracker_pb2.Phase()] * template_helpers.MAX_NUM_PHASES
59 return {
60 'admin_tab_mode':
61 self._PROCESS_SUBTAB,
62 'allow_edit':
63 ezt.boolean(True),
64 'uneditable_fields':
65 ezt.boolean(False),
66 'new_template_form':
67 ezt.boolean(True),
68 'initial_members_only':
69 ezt.boolean(False),
70 'template_name':
71 '',
72 'initial_content':
73 '',
74 'initial_must_edit_summary':
75 ezt.boolean(False),
76 'initial_summary':
77 '',
78 'initial_status':
79 '',
80 'initial_owner':
81 '',
82 'initial_owner_defaults_to_member':
83 ezt.boolean(False),
84 'initial_components':
85 '',
86 'initial_component_required':
87 ezt.boolean(False),
88 'initial_admins':
89 '',
90 'fields':
91 [
92 view for view in field_views
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010093 if view.field_def.type_name != "APPROVAL_TYPE"
Copybara854996b2021-09-07 19:36:02 +000094 ],
95 'initial_add_approvals':
96 ezt.boolean(False),
97 'initial_phases':
98 initial_phases,
99 'approvals':
100 [
101 view for view in field_views
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100102 if view.field_def.type_name == "APPROVAL_TYPE"
Copybara854996b2021-09-07 19:36:02 +0000103 ],
104 'prechecked_approvals': [],
105 'required_approval_ids': [],
106 'approval_subfields_present':
107 ezt.boolean(approval_subfields_present),
108 # We do not support setting phase field values during template creation.
109 'phase_fields_present':
110 ezt.boolean(False),
111 }
112
113 def ProcessFormData(self, mr, post_data):
114 """Validate and store the contents of the issues tracker admin page.
115
116 Args:
117 mr: commonly used info parsed from the request.
118 post_data: HTML form data from the request.
119
120 Returns:
121 String URL to redirect the user to, or None if response was already sent.
122 """
123
124 config = self.services.config.GetProjectConfig(mr.cnxn, mr.project_id)
125 parsed = template_helpers.ParseTemplateRequest(post_data, config)
126 field_helpers.ShiftEnumFieldsIntoLabels(
127 parsed.labels, [], parsed.field_val_strs, [], config)
128
129 if not parsed.name:
130 mr.errors.name = 'Please provide a template name'
131 if self.services.template.GetTemplateByName(mr.cnxn, parsed.name,
132 mr.project_id):
133 mr.errors.name = 'Template with name %s already exists' % parsed.name
134
135 (admin_ids, owner_id, component_ids,
136 field_values, phases,
137 approvals) = template_helpers.GetTemplateInfoFromParsed(
138 mr, self.services, parsed, config)
139
140 labels = [label for label in parsed.labels if label]
141 field_helpers.AssertCustomFieldsEditPerms(
142 mr, config, field_values, [], [], labels, [])
143
144 if mr.errors.AnyErrors():
145 field_views = tracker_views.MakeAllFieldValueViews(
146 config, [], [], field_values, {})
147 prechecked_approvals = template_helpers.GetCheckedApprovalsFromParsed(
148 parsed.approvals_to_phase_idx)
149
150 self.PleaseCorrect(
151 mr,
152 initial_members_only=ezt.boolean(parsed.members_only),
153 template_name=parsed.name,
154 initial_content=parsed.summary,
155 initial_must_edit_summary=ezt.boolean(parsed.summary_must_be_edited),
156 initial_description=parsed.content,
157 initial_status=parsed.status,
158 initial_owner=parsed.owner_str,
159 initial_owner_defaults_to_member=ezt.boolean(
160 parsed.owner_defaults_to_member),
161 initial_components=', '.join(parsed.component_paths),
162 initial_component_required=ezt.boolean(parsed.component_required),
163 initial_admins=parsed.admin_str,
164 labels=parsed.labels,
165 fields=[view for view in field_views
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100166 if view.field_def.type_name != 'APPROVAL_TYPE'],
Copybara854996b2021-09-07 19:36:02 +0000167 initial_add_approvals=ezt.boolean(parsed.add_approvals),
168 initial_phases=[tracker_pb2.Phase(name=name) for name in
169 parsed.phase_names],
170 approvals=[view for view in field_views
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100171 if view.field_def.type_name == 'APPROVAL_TYPE'],
Copybara854996b2021-09-07 19:36:02 +0000172 prechecked_approvals=prechecked_approvals,
173 required_approval_ids=parsed.required_approval_ids
174 )
175 return
176
177 self.services.template.CreateIssueTemplateDef(
178 mr.cnxn, mr.project_id, parsed.name, parsed.content, parsed.summary,
179 parsed.summary_must_be_edited, parsed.status, parsed.members_only,
180 parsed.owner_defaults_to_member, parsed.component_required,
181 owner_id, labels, component_ids, admin_ids, field_values, phases=phases,
182 approval_values=approvals)
183
184 return framework_helpers.FormatAbsoluteURL(
185 mr, urls.ADMIN_TEMPLATES, saved=1, ts=int(time.time()))
Adrià Vilanova Martínezde942802022-07-15 14:06:55 +0200186
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100187 def GetTemplateCreate(self, **kwargs):
188 return self.handler(**kwargs)
Adrià Vilanova Martínezde942802022-07-15 14:06:55 +0200189
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100190 def PostTemplateCreate(self, **kwargs):
191 return self.handler(**kwargs)