From e1d1c642500768cafbf1f4880c9bf7abb0804e1d Mon Sep 17 00:00:00 2001 From: Byron Jones Date: Tue, 16 Sep 2014 12:49:50 +0800 Subject: Bug 1058615: New Custom Bugzilla Form Needed For PR Team --- extensions/BMO/Config.pm | 7 +- extensions/BMO/Extension.pm | 54 +- .../en/default/bug/create/comment-mozpr.txt.tmpl | 130 ++ .../en/default/bug/create/create-mozpr.html.tmpl | 1274 ++++++++++---------- extensions/BMO/web/js/form_validate.js | 30 +- 5 files changed, 865 insertions(+), 630 deletions(-) create mode 100644 extensions/BMO/template/en/default/bug/create/comment-mozpr.txt.tmpl (limited to 'extensions/BMO') diff --git a/extensions/BMO/Config.pm b/extensions/BMO/Config.pm index 8fbec2720..93445f576 100644 --- a/extensions/BMO/Config.pm +++ b/extensions/BMO/Config.pm @@ -34,7 +34,12 @@ use constant REQUIRED_MODULES => [ package => 'Sys-Syslog', module => 'Sys::Syslog', version => 0 - } + }, + { + package => 'File-MimeInfo', + module => 'File::MimeInfo::Magic', + version => '0' + }, ]; use constant OPTIONAL_MODULES => [ diff --git a/extensions/BMO/Extension.pm b/extensions/BMO/Extension.pm index 8cbc8f185..81333345c 100644 --- a/extensions/BMO/Extension.pm +++ b/extensions/BMO/Extension.pm @@ -41,6 +41,7 @@ use Bugzilla::Util; use Date::Parse; use DateTime; use Encode qw(find_encoding encode_utf8); +use File::MimeInfo::Magic; use Scalar::Util qw(blessed); use Sys::Syslog qw(:DEFAULT setlogsock); @@ -1008,6 +1009,9 @@ sub post_bug_after_creation { elsif ($format eq 'swag') { $self->_post_gear_bug($args); } + elsif ($format eq 'mozpr') { + $self->_post_mozpr_bug($args); + } } sub _post_employee_incident_bug { @@ -1153,6 +1157,30 @@ sub _post_gear_bug { filename => "gear_" . $bug->id . ".csv", mimetype => "text/csv", }); + $bug->update($bug->creation_ts); +} + +sub _post_mozpr_bug { + my ($self, $args) = @_; + my $vars = $args->{vars}; + my $bug = $vars->{bug}; + my $input = Bugzilla->input_params; + + if ($input->{proj_mat_file}) { + $self->_add_attachment($args, { + data => $input->{proj_mat_file_attach}, + description => $input->{proj_mat_file_desc}, + filename => scalar $input->{proj_mat_file_attach}, + }); + } + if ($input->{pr_mat_file}) { + $self->_add_attachment($args, { + data => $input->{pr_mat_file_attach}, + description => $input->{pr_mat_file_desc}, + filename => scalar $input->{pr_mat_file_attach}, + }); + } + $bug->update($bug->creation_ts); } sub _add_attachment { @@ -1163,6 +1191,7 @@ sub _add_attachment { $attachment_args->{creation_ts} = $bug->creation_ts; $attachment_args->{ispatch} = 0 unless exists $attachment_args->{ispatch}; $attachment_args->{isprivate} = 0 unless exists $attachment_args->{isprivate}; + $attachment_args->{mimetype} ||= $self->_detect_content_type($attachment_args->{data}); # If the attachment cannot be successfully added to the bug, # we notify the user, but we don't interrupt the bug creation process. @@ -1180,12 +1209,35 @@ sub _add_attachment { $bug->add_comment('', { isprivate => 0, type => CMT_ATTACHMENT_CREATED, extra_data => $attachment->id }); - $bug->update($bug->creation_ts); delete $bug->{attachments}; } else { $args->{vars}->{'message'} = 'attachment_creation_failed'; } + + # Note: you must call $bug->update($bug->creation_ts) after adding all attachments +} + +# bugzilla's content_type detection makes assumptions about form fields, which +# means we can't use it here. this code is lifted from +# Bugzilla::Attachment::get_content_type and the TypeSniffer extension. +sub _detect_content_type { + my ($self, $data) = @_; + my $cgi = Bugzilla->cgi; + + # browser provided content-type + my $content_type = $cgi->uploadInfo($data)->{'Content-Type'}; + $content_type = 'image/png' if $content_type eq 'image/x-png'; + + if ($content_type eq 'application/octet-stream') { + # detect from filename + my $filename = scalar($data); + if (my $from_filename = mimetype($filename)) { + return $from_filename; + } + } + + return $content_type || 'application/octet-stream'; } sub buglist_columns { diff --git a/extensions/BMO/template/en/default/bug/create/comment-mozpr.txt.tmpl b/extensions/BMO/template/en/default/bug/create/comment-mozpr.txt.tmpl new file mode 100644 index 000000000..bfd421388 --- /dev/null +++ b/extensions/BMO/template/en/default/bug/create/comment-mozpr.txt.tmpl @@ -0,0 +1,130 @@ +[%# This Source Code Form is subject to the terms of the Mozilla Public + # License, v. 2.0. If a copy of the MPL was not distributed with this + # file, You can obtain one at http://mozilla.org/MPL/2.0/. + # + # This Source Code Form is "Incompatible With Secondary Licenses", as + # defined by the Mozilla Public License, v. 2.0. + #%] + +[% USE Bugzilla %] +[% cgi = Bugzilla.cgi +%] +[% PROCESS global/variables.none.tmpl +%] + + Project Title: [% cgi.param("short_desc") %] + +Project Description and Scope: +[%+ cgi.param("desc") %] + +== Timings + + Start Date: [% cgi.param("start_date") %] + Announcement Date: [% cgi.param("announce_date") %] + Internal Deadline: [% cgi.param("deadline") %] + +== Owners + + Project PR Owner: [% cgi.param("pr_owner") %] +[%~ " " _ cgi.param("pr_owner_other") IF cgi.param("pr_owner") == "Other:" %] + Project Owner: [% cgi.param("owner") %] + +== RASCI + + Responsible: [% cgi.param("rasci_r") || "-" %] + Approver: [% cgi.param("rasci_a") %] + Supporter: [% cgi.param("rasci_s") || "-" %] + Consultant: [% cgi.param("rasci_c") || "-" %] + Informed: [% cgi.param("rasci_i") || "-" %] + +== Details + + Tier: [% cgi.param("tier") %] + PR Approach: [% cgi.param("pr_approach") %] +Product Group Focus: [% cgi.param("group_focus") %] +[%~ " " _ cgi.param("group_focus_other") IF cgi.param("group_focus") == "Other:" %] + Region: [% cgi.param("region") %] +[%~ " " _ cgi.param("region_other") IF cgi.param("region") == "Other:" %] + +== Goals, Audience, and Messages + +Project Goals: +[%+ cgi.param("project_goals") %] + +PR Goals: +[%+ cgi.param("pr_goals") %] + +Company Goal: [% cgi.param("company_goal") %] + +Audiences: +[% FOREACH audience = cgi.param("audience") %] + - [% audience %] +[% " " _ cgi.param("audience_other") IF audience == "Other:" %] +[% END %] + +Key Messages: +[%+ cgi.param("key_messages") %] +[% IF cgi.param("proj_mat_online") %] + +== Project Materials - Online Documentation + + Description: [% cgi.param("proj_mat_online_desc") %] + Link: [% cgi.param("proj_mat_online_link") %] +[% END %] +[% IF cgi.param("proj_mat_file") %] + +== Project Materials - Attached + + Description: [% cgi.param("proj_mat_file_desc") %] + File Name: [% cgi.param("proj_mat_file_attach") %] +[% END %] +[% IF cgi.param("pr_mat_online") %] + +== PR Project Materials - Online Documentation + + Description: [% cgi.param("pr_mat_online_desc") %] + Link: [% cgi.param("pr_mat_online_link") %] +[% END %] +[% IF cgi.param("pr_mat_file") %] + +== PR Project Materials - Attached + + Description: [% cgi.param("pr_mat_file_desc") %] + File Name: [% cgi.param("pr_mat_file_attach") %] +[% END %] + +== Requirements + + Metrica Coverage: [% cgi.param("metrica") %] +[% IF cgi.param("press_center") %] + +Press Center Update: +[% FOREACH option = cgi.param("press_center") %] + - [% option %] +[% " " _ cgi.param("press_center_other") IF option == "Other:" %] +[% END %] +[% END %] +[% IF cgi.param("resources") || cgi.param("internal_resources") %] + + Internal Resources: +[% " " _ cgi.param("resources") IF cgi.param("resources") %] +[% FOREACH option = cgi.param("internal_resources") %] + - [% option %] +[% " " _ cgi.param("internal_resources_other") IF option == "Other:" %] +[% END %] +[% END %] +[% IF cgi.param("resources") || cgi.param("external_resources") %] + + External Resources: +[% FOREACH option = cgi.param("external_resources") %] + - [% option %] +[% " " _ cgi.param("external_resources_other") IF option == "Other:" %] +[% END %] +[% END %] + + Localization: [% cgi.param("localization") %] +[%~ " " _ cgi.param("localization_other") IF cgi.param("localization") == "Other:" %] + +== Budget + + Budget: [% cgi.param("budget") %] +[%~ " " _ cgi.param("budget_extra") IF cgi.param("budget") == "Extra" %] + diff --git a/extensions/BMO/template/en/default/bug/create/create-mozpr.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-mozpr.html.tmpl index 06336d63f..f231ea3b9 100644 --- a/extensions/BMO/template/en/default/bug/create/create-mozpr.html.tmpl +++ b/extensions/BMO/template/en/default/bug/create/create-mozpr.html.tmpl @@ -1,655 +1,683 @@ -[%# The contents of this file are subject to the Mozilla Public - # License Version 1.1 (the "License"); you may not use this file - # except in compliance with the License. You may obtain a copy of - # the License at http://www.mozilla.org/MPL/ +[%# This Source Code Form is subject to the terms of the Mozilla Public + # License, v. 2.0. If a copy of the MPL was not distributed with this + # file, You can obtain one at http://mozilla.org/MPL/2.0/. # - # Software distributed under the License is distributed on an "AS - # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - # implied. See the License for the specific language governing - # rights and limitations under the License. - # - # The Original Code is the Bugzilla Bug Tracking System. - # - # The Initial Developer of the Original Code is Netscape Communications - # Corporation. Portions created by Netscape are - # Copyright (C) 1998 Netscape Communications Corporation. All - # Rights Reserved. - # - # Contributor(s): Gervase Markham - # Ville Skyttä - # Shane H. W. Travis - # Marc Schumann - # Akamai Technologies - # Max Kanat-Alexander - # Frédéric Buclin + # This Source Code Form is "Incompatible With Secondary Licenses", as + # defined by the Mozilla Public License, v. 2.0. #%] -[% PROCESS "global/field-descs.none.tmpl" %] +[% PROCESS global/variables.none.tmpl %] -[% title = BLOCK %]Create a PR Request[% END %] +[% inline_style = BLOCK %] +#pr_form { + padding: 10px; + width: 600px; +} -[% PROCESS global/header.html.tmpl - title = title - style_urls = [ 'skins/standard/attachment.css' ] - javascript_urls = [ "js/attachment.js", "js/util.js", - "js/field.js", "js/TUI.js" ] - onload = 'set_assign_to();' - yui = [ 'autocomplete' ] -%] +#pr_form input[type="text"], #pr_form textarea { + width: 100%; + margin-bottom: 2px; +} - +#pr_form label.normal { + font-weight: normal; + display: inline; +} -[% IF user.in_group("mozilla-confidential") %] +#pr_form .calendar_button { + margin-top: 0.5em; +} -[% USE Bugzilla %] +#pr_form .desc { + padding-bottom: 3px; +} -
- - +#pr_form .field { + margin-bottom: 10px; +} - - - - - - - - - - - - - - - - [%# We can't use the select block in these two cases for various reasons. %] -[% matches = default.component_.matches('^(.*) - (.*)$') %] -[% default.location = matches.0 %] -[% default.fakecomp = matches.1 %] -[% IF default.location == '' %] - [% default.location = 'US' %] -[% END %] -[% locations = [] %] -[% fakecomps = [] %] -[% FOREACH c = product.components %] - [% matches = c.name.match('^(.*) - (.*)$') %] - [% locations.push(matches.0) %] - [% fakecomps.push(matches.1) %] -[% END %] -[% locations = locations.unique %] -[% fakecomps = fakecomps.unique %] - - - - - - - - - - - - - - - - - - -[% IF bug_status.size <= 1 %] - - - -[% ELSE %] - [% INCLUDE bug/field.html.tmpl - bug = default, field = bug_fields.bug_status, - editable = (bug_status.size > 1), value = default.bug_status - override_legal_values = bug_status %] -[% END %] +#pr_form .indent { + margin-left: 30px; +} - - [%# Calculate the number of rows we can use for flags %] - [% num_rows = 6 + (Param("useqacontact") ? 1 : 0) + - (user.is_timetracker ? 3 : 0) + - (Param("usebugaliases") ? 1 : 0) - %] - - - - - - - - - -[% IF Param("useqacontact") %] - - - - -[% END %] +#pr_form textarea { + font-family: inherit; + font-size: inherit; +} - - - - - - - - - - - - - - -[% IF user.is_timetracker %] - - - - - - - - - - - - -[% END %] +#pr_form .head { + font-weight: bold; + border-top: 1px solid silver; + border-bottom: 1px solid silver; + padding: 5px; + margin: 1em 0; + background: #ddd; +} + +#pr_form fieldset { + border: none; +} + +#pr_form .extra { + font-style: italic; +} + +#pr_form .extra a { + text-decoration: underline; +} + +#pr_form #commit { + margin-top: 20px; +} + +#pr_form .linked { + display: block; + margin-top: 2px; + width: 300px; +} -[% IF Param("usebugaliases") %] - - - - [% END %] - - - - - - - - - - - - - - - - - - - [% IF user.is_insider %] - - - - - [% END %] - - - - - - - - - [% IF user.in_group('editbugs', product.id) %] - [% IF use_keywords %] - - [% INCLUDE bug/field.html.tmpl - bug = default, field = bug_fields.keywords, editable = 1, - value = keywords, desc_url = "describekeywords.cgi", - value_span = 3 %] - - [% END %] - - - - - - - - - - - - - - [% END %] - - - - [%# exclude the default security from from the groups_available %] - [%# list, as it will be added by the BMO extension %] - [% groups_available = [] %] - [% FOREACH group = product.groups_available %] - [% NEXT IF group.name == product.default_security_group %] - [% groups_available.push(group) %] - [% END %] - [% IF groups_available.size %] - - - - - [% END %] - - - - [%# Form controls for entering additional data about the bug being created. %] - [% Hook.process("form") %] - - - - - - -
- Hide - Advanced Fields - [%# Show the link if the browser supports JS %] - - - (* = - Required Field) -
Product:[% product.name FILTER html %]Reporter:[% user.login FILTER html %]
- Location: - - - - -
- Request type: - - - - - [%# Enclose the fieldset in a nested table so that its width changes based - # on the length on the component description. %] - - - - -
-
- Request Description -
Select a request type to read its description.
-
-
- - - - -
 
Initial State:[% display_value("bug_status", default.bug_status) FILTER html %]  - [% IF product.flag_types(is_active=>1).bug.size > 0 %] - [% display_flag_headers = 0 %] - [% any_flags_requesteeble = 0 %] - - [% FOREACH flag_type = product.flag_types(is_active=>1).bug %] - [% display_flag_headers = 1 %] - [% SET any_flags_requesteeble = 1 IF flag_type.is_requestable && flag_type.is_requesteeble %] - [% END %] - - [% IF display_flag_headers %] - [% PROCESS "flag/list.html.tmpl" flag_types = product.flag_types(is_active=>1).bug - any_flags_requesteeble = any_flags_requesteeble - flag_table_id = "bug_flags" - %] - [% END %] - [% END %] -
Assign To: - [% INCLUDE global/userselect.html.tmpl - id => "assigned_to" - name => "assigned_to" - value => assigned_to - disabled => assigned_to_disabled - size => 30 - emptyok => 1 - custom_userlist => assignees_list - %] - -
QA Contact: - [% INCLUDE global/userselect.html.tmpl - id => "qa_contact" - name => "qa_contact" - value => qa_contact - disabled => qa_contact_disabled - size => 30 - emptyok => 1 - custom_userlist => qa_contacts_list - %] - -
CC: - [% INCLUDE global/userselect.html.tmpl - id => "cc" - name => "cc" - value => cc - disabled => cc_disabled - size => 30 - multiple => 5 - %] -
Default CC: -
-
-
 
Estimated Hours: - -
Deadline: - - (YYYY-MM-DD) -
 
Alias: - -
URL: - -
Summary: - -
Description: - [% defaultcontent = BLOCK %] - [% IF cloned_bug_id %] -+++ This [% terms.bug %] was initially created as a clone of [% terms.Bug %] #[% cloned_bug_id FILTER html %] +++ - - - [% END %] - [%-# We are within a BLOCK. The comment will be correctly HTML-escaped - # by global/textarea.html.tmpl. So we must not escape the comment here. %] - [% comment FILTER none %] - [%- END %] - [% INCLUDE global/textarea.html.tmpl - name = 'comment' - id = 'comment' - minrows = 10 - maxrows = 25 - cols = constants.COMMENT_COLS - defaultcontent = defaultcontent - %] -
-
  -    - - -
Attachment: - -
- Add an attachment - - [% PROCESS attachment/createformcontents.html.tmpl - flag_types = product.flag_types(is_active=>1).attachment - any_flags_requesteeble = 1 - flag_table_id ="attachment_flags" %] -
-
- -
Status Whiteboard: - -
Depends on: - -
Blocks: - -
  -
- - Only users in all of the selected groups can view this - [%+ terms.bug %]: - -
- - (Leave all boxes unchecked to make this a public [% terms.bug %].) - -
-
- - - - [% FOREACH group = groups_available %] - -
- [% END %] -
  - -      - -
- -
+[% inline_javascript = BLOCK %] +var pr_inited = false; -[%# Links or content with more information about the bug being created. %] -[% Hook.process("end") %] +function init_listener(id, event, fn) { + YAHOO.util.Event.addListener(id, event, fn); + bz_fireEvent(document.getElementById(id), event); +} + +function toggle_linked(id, value, suffix) { + var el = document.getElementById(id); + var show = el.type == 'checkbox' ? el.checked : el.value == value; + if (show) { + var linked = document.getElementById(id + suffix); + YAHOO.util.Dom.addClass(linked, 'linked'); + YAHOO.util.Dom.removeClass(linked, 'bz_default_hidden'); + if (pr_inited && linked.nodeName == "INPUT") { + linked.focus(); + linked.select(); + } + } + else { + YAHOO.util.Dom.addClass(id + suffix, 'bz_default_hidden'); + } +} -[% ELSE %] +function init_other(id) { + init_listener(id, 'change', function(o) { + toggle_linked(id, 'Other:', '_other'); + }); +} -

Sorry, you do not have access to this page.

+YAHOO.util.Event.onDOMReady(function() { + init_listener('metrica', 'change', function(o) { + toggle_linked('metrica', 'Yes', '_extra'); + }); + init_listener('budget', 'change', function(o) { + toggle_linked('budget', 'Extra', '_extra'); + }); + init_listener('proj_mat_online', 'click', function(o) { + toggle_linked('proj_mat_online', 0, '_extra'); + }); + init_listener('proj_mat_file', 'click', function(o) { + toggle_linked('proj_mat_file', 0, '_extra'); + }); + init_listener('pr_mat_online', 'click', function(o) { + toggle_linked('pr_mat_online', 0, '_extra'); + }); + init_listener('pr_mat_file', 'click', function(o) { + toggle_linked('pr_mat_file', 0, '_extra'); + }); + + init_other('pr_owner'); + init_other('group_focus'); + init_other('project_type'); + init_other('region'); + init_other('press_center'); + init_other('internal_resources'); + init_other('external_resources'); + init_other('localization'); + init_other('audience'); + + pr_inited = true; +}); + +function validate_other(id, value, suffix) { + var el = document.getElementById(id); + if (!value) value = 'Other:'; + if (!suffix) suffix = '_other'; + if (!el) { + console.error('Failed to find element: ' + elem_id); + return false; + } + if (el.type == 'checkbox') { + if (!el.checked) return true; + } + else if (el.value != value) { + return true; + } + return isFilledOut(id + suffix); +} + +function validate_form() { + var Dom = YAHOO.util.Dom; + + var old_missing = Dom.getElementsByClassName('missing'); + for (var i = 0, il = old_missing.length; i < il; i++) { + Dom.removeClass(old_missing[i], 'missing'); + } + + var missing = []; + if (!isFilledOut('short_desc')) missing.push(['short_desc', 'Project Title']); + if (!isFilledOut('desc')) missing.push(['desc', 'Project Description and Scope']); + + if (!isFilledOut('start_date')) missing.push(['start_date', 'Start Date']); + if (!isFilledOut('announce_date')) missing.push(['announce_date', 'Announcement Date']); + if (!isFilledOut('deadline')) missing.push(['deadline', 'Internal Deadline']); + + if (!isFilledOut('pr_owner')) missing.push(['pr_owner', 'Project PR Owner']); + if (!isFilledOut('owner')) missing.push(['owner', 'Project Owner']); + + if (!isFilledOut('rasci_a')) missing.push(['rasci_a', 'RASCI Approver']); + + if (!isFilledOut('tier')) missing.push(['tier', 'Tier']); + if (!isFilledOut('project_type')) missing.push(['project_type', 'Project Type']); + if (!isFilledOut('pr_approach')) missing.push(['pr_approach', 'PR Approach']); + if (!isFilledOut('group_focus')) missing.push(['group_focus', 'Product Group Focus']); + if (!validate_other('group_focus')) missing.push(['group_focus', 'Product Group Focus - Other']); + if (!isFilledOut('region')) missing.push(['region', 'Region']); + if (!validate_other('region')) missing.push(['region', 'Region - Other']); + + if (!isFilledOut('project_goals')) missing.push(['project_goals', 'Project Goals']); + if (!isFilledOut('pr_goals')) missing.push(['pr_goals', 'PR Goals']); + if (!isFilledOut('company_goal')) missing.push(['company_goal', 'Company Goal']); + if (!isOneChecked(document.forms.pr_form.audience)) + missing.push(['audience_group', 'Audiences']); + if (!validate_other('audience')) missing.push(['audience', 'Audience - Other']); + if (!isFilledOut('key_messages')) missing.push(['key_messages', 'Key Messages']); + + if (Dom.get('proj_mat_online').checked) { + if (!isFilledOut('proj_mat_online_desc')) missing.push(['proj_mat_online_desc', 'Project Materials - Online Description']); + if (!isFilledOut('proj_mat_online_link')) missing.push(['proj_mat_online_link', 'Project Materials - Online Link']); + } + if (Dom.get('proj_mat_file').checked) { + if (!isFilledOut('proj_mat_file_desc')) missing.push(['proj_mat_file_desc', 'Project Materials - Upload Description']); + if (!isFilledOut('proj_mat_file_attach')) missing.push(['proj_mat_file_attach', 'Project Materials - Upload File']); + } + if (Dom.get('pr_mat_online').checked) { + if (!isFilledOut('pr_mat_online_desc')) missing.push(['pr_mat_online_desc', 'PR Project Materials - Online Description']); + if (!isFilledOut('pr_mat_online_link')) missing.push(['pr_mat_online_link', 'PR Project Materials - Online Link']); + } + if (Dom.get('pr_mat_file').checked) { + if (!isFilledOut('pr_mat_file_desc')) missing.push(['pr_mat_file_desc', 'PR Project Materials - Upload Description']); + if (!isFilledOut('pr_mat_file_attach')) missing.push(['pr_mat_file_attach', 'PR Project Materials - Upload File']); + } + + if (!validate_other('press_center')) missing.push(['press_center', 'Press Center Update - Other']); + if (!validate_other('internal_resources')) missing.push(['internal_resources', 'Internal Resources Needed - Other']); + if (!validate_other('external_resources')) missing.push(['external_resources', 'External Resources Needed - Other']); + if (!validate_other('localization')) missing.push(['localization', 'Localization Needed - Other']); + + if (!isFilledOut('budget')) missing.push(['budget', 'Budget']); + if (!validate_other('budget', 'Extra', '_extra')) missing.push(['budget', 'Budget - Extra']); + + if (missing.length) { + var missing_text = []; + for (var i = 0, il = missing.length; i < il; i++) { + Dom.addClass(missing[i][0], 'missing'); + missing_text.push(missing[i][1]); + } + if (missing_text.length == 1) { + alert("The field '" + missing_text[0] + "' is required."); + } + else { + alert("The following fields are required:\n- " + missing_text.join("\n- ")); + } + return false; + } + + return true; +} [% END %] -[% PROCESS global/footer.html.tmpl %] +[% PROCESS global/header.html.tmpl + title = "PR Project Form" + style = inline_style + javascript = inline_javascript + javascript_urls = [ 'extensions/BMO/web/js/form_validate.js', + 'js/field.js', 'js/util.js' ] + yui = [ "autocomplete", "calendar" ] +%] -[% BLOCK build_userlist %] - [% user_found = 0 %] - [% default_login = default_user.login %] - [% RETURN UNLESS default_login %] - - [% FOREACH user = userlist %] - [% IF user.login == default_login %] - [% user_found = 1 %] - [% LAST %] - [% END %] - [% END %] - - [% userlist.push({login => default_login, - identity => default_user.identity, - visible => 1}) - UNLESS user_found %] +[% UNLESS user.in_group('pr-private') %] +
+ This form is only available to members of the Mozilla PR team. +
+ [% PROCESS global/footer.html.tmpl %] + [% RETURN %] [% END %] + +[% USE Bugzilla %] +[% cgi = Bugzilla.cgi %] + +
+ + + + + + + + + + + +
+ PR Project Form +
+ +
+ + +
+ +
+ + +
+ +
+ Timings +
+ +
+ + + +
+ +
+ +
+ + + +
+ +
+ +
+ + + +
+ +
+ +
+ Owners +
+ +
+ + + +
+ +
+ + +
+ +
+ RASCI +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ Details +
+ +
+ + +
+ +
+ + + +
+ +
+ + +
+ +
+ + + +
+ +
+ + + +
+ +
+ Goals, Audience, and Messages +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+ +
+ +
+ +
+ +
+ + +
+ +
+ Materials +
+ +
+ +
+ + +
+ + + + +
+
+
+ + +
+ + + + +
+
+
+ +
+ +
+ + +
+ + + + +
+
+
+ + +
+ + + + +
+
+
+ +
+ Requirements +
+ +
+ + +
+ Please fill out the + Metrica form + and submit to Metrica no later than a week before project starts. +
+
+ +
+ + +
+ +
+ +
+ +
+ +
+ + + +
+ +
+ +
+ +
+ +
+ +
+ + +
+ +
+ +
+ +
+ +
+ +
+ + + +
+ +
+ Budget +
+ +
+ + + +
+ + + +

+ [ * Required Field ] +

+ +
+ +[% PROCESS global/footer.html.tmpl %] diff --git a/extensions/BMO/web/js/form_validate.js b/extensions/BMO/web/js/form_validate.js index 6c8fa6f07..7e9746a5c 100644 --- a/extensions/BMO/web/js/form_validate.js +++ b/extensions/BMO/web/js/form_validate.js @@ -1,9 +1,16 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This Source Code Form is "Incompatible With Secondary Licenses", as + * defined by the Mozilla Public License, v. 2.0. */ + /** - * Some Form Validation and Interaction + * Form Validation and Interaction **/ -//Makes sure that there is an '@' in the address with a '.' -//somewhere after it (and at least one character in between them +//Makes sure that there is an '@' in the address with a '.' +//somewhere after it (and at least one character in between them) function isValidEmail(email) { var at_index = email.indexOf("@"); var last_dot = email.lastIndexOf("."); @@ -12,10 +19,23 @@ function isValidEmail(email) { //Takes a DOM element id and makes sure that it is filled out function isFilledOut(elem_id) { - var str = document.getElementById(elem_id).value; - return str.length>0 && str!="noneselected"; + var el = document.getElementById(elem_id); + if (!el) { + console.error('Failed to find element: ' + elem_id); + return false; + } + var str = el.value; + return str.length > 0 && str != "noneselected"; } function isChecked(elem_id) { return document.getElementById(elem_id).checked; } + +function isOneChecked(form_nodelist) { + for (var i = 0, il = form_nodelist.length; i < il; i++) { + if (form_nodelist[i].checked) + return true; + } + return false; +} -- cgit v1.2.3-24-g4f1b