blob: e10a25b48ff920e2a4ab2874e436ebb11a335dce [file] [log] [blame]
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
"""A servlet for project owners to create a new template"""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
import collections
import logging
import time
import ezt
from framework import authdata
from framework import framework_bizobj
from framework import framework_helpers
from framework import servlet
from framework import urls
from framework import permissions
from tracker import field_helpers
from tracker import template_helpers
from tracker import tracker_bizobj
from tracker import tracker_helpers
from tracker import tracker_views
from services import user_svc
from proto import tracker_pb2
class TemplateCreate(servlet.Servlet):
"""Servlet allowing project owners to create an issue template."""
_MAIN_TAB_MODE = servlet.Servlet.MAIN_TAB_PROCESS
_PAGE_TEMPLATE = 'tracker/template-detail-page.ezt'
_PROCESS_SUBTAB = servlet.Servlet.PROCESS_TAB_TEMPLATES
def AssertBasePermission(self, mr):
"""Check whether the user has any permission to visit this page.
Args:
mr: commonly used info parsed from the request
"""
super(TemplateCreate, self).AssertBasePermission(mr)
if not self.CheckPerm(mr, permissions.EDIT_PROJECT):
raise permissions.PermissionException(
'User is not allowed to administer this project')
def GatherPageData(self, mr):
"""Build up a dictionary of data values to use when rendering the page.
Args:
mr: commonly used info parsed from the request.
Returns:
Dict of values used by EZT for rendering the page.
"""
config = self.services.config.GetProjectConfig(mr.cnxn, mr.project_id)
field_views = tracker_views.MakeAllFieldValueViews(
config, [], [], [], {})
approval_subfields_present = any(
fv.field_def.is_approval_subfield for fv in field_views)
initial_phases = [tracker_pb2.Phase()] * template_helpers.MAX_NUM_PHASES
return {
'admin_tab_mode':
self._PROCESS_SUBTAB,
'allow_edit':
ezt.boolean(True),
'uneditable_fields':
ezt.boolean(False),
'new_template_form':
ezt.boolean(True),
'initial_members_only':
ezt.boolean(False),
'template_name':
'',
'initial_content':
'',
'initial_must_edit_summary':
ezt.boolean(False),
'initial_summary':
'',
'initial_status':
'',
'initial_owner':
'',
'initial_owner_defaults_to_member':
ezt.boolean(False),
'initial_components':
'',
'initial_component_required':
ezt.boolean(False),
'initial_admins':
'',
'fields':
[
view for view in field_views
if view.field_def.type_name is not "APPROVAL_TYPE"
],
'initial_add_approvals':
ezt.boolean(False),
'initial_phases':
initial_phases,
'approvals':
[
view for view in field_views
if view.field_def.type_name is "APPROVAL_TYPE"
],
'prechecked_approvals': [],
'required_approval_ids': [],
'approval_subfields_present':
ezt.boolean(approval_subfields_present),
# We do not support setting phase field values during template creation.
'phase_fields_present':
ezt.boolean(False),
}
def ProcessFormData(self, mr, post_data):
"""Validate and store the contents of the issues tracker admin page.
Args:
mr: commonly used info parsed from the request.
post_data: HTML form data from the request.
Returns:
String URL to redirect the user to, or None if response was already sent.
"""
config = self.services.config.GetProjectConfig(mr.cnxn, mr.project_id)
parsed = template_helpers.ParseTemplateRequest(post_data, config)
field_helpers.ShiftEnumFieldsIntoLabels(
parsed.labels, [], parsed.field_val_strs, [], config)
if not parsed.name:
mr.errors.name = 'Please provide a template name'
if self.services.template.GetTemplateByName(mr.cnxn, parsed.name,
mr.project_id):
mr.errors.name = 'Template with name %s already exists' % parsed.name
(admin_ids, owner_id, component_ids,
field_values, phases,
approvals) = template_helpers.GetTemplateInfoFromParsed(
mr, self.services, parsed, config)
labels = [label for label in parsed.labels if label]
field_helpers.AssertCustomFieldsEditPerms(
mr, config, field_values, [], [], labels, [])
if mr.errors.AnyErrors():
field_views = tracker_views.MakeAllFieldValueViews(
config, [], [], field_values, {})
prechecked_approvals = template_helpers.GetCheckedApprovalsFromParsed(
parsed.approvals_to_phase_idx)
self.PleaseCorrect(
mr,
initial_members_only=ezt.boolean(parsed.members_only),
template_name=parsed.name,
initial_content=parsed.summary,
initial_must_edit_summary=ezt.boolean(parsed.summary_must_be_edited),
initial_description=parsed.content,
initial_status=parsed.status,
initial_owner=parsed.owner_str,
initial_owner_defaults_to_member=ezt.boolean(
parsed.owner_defaults_to_member),
initial_components=', '.join(parsed.component_paths),
initial_component_required=ezt.boolean(parsed.component_required),
initial_admins=parsed.admin_str,
labels=parsed.labels,
fields=[view for view in field_views
if view.field_def.type_name is not 'APPROVAL_TYPE'],
initial_add_approvals=ezt.boolean(parsed.add_approvals),
initial_phases=[tracker_pb2.Phase(name=name) for name in
parsed.phase_names],
approvals=[view for view in field_views
if view.field_def.type_name is 'APPROVAL_TYPE'],
prechecked_approvals=prechecked_approvals,
required_approval_ids=parsed.required_approval_ids
)
return
self.services.template.CreateIssueTemplateDef(
mr.cnxn, mr.project_id, parsed.name, parsed.content, parsed.summary,
parsed.summary_must_be_edited, parsed.status, parsed.members_only,
parsed.owner_defaults_to_member, parsed.component_required,
owner_id, labels, component_ids, admin_ids, field_values, phases=phases,
approval_values=approvals)
return framework_helpers.FormatAbsoluteURL(
mr, urls.ADMIN_TEMPLATES, saved=1, ts=int(time.time()))