diff options
-rw-r--r-- | extensions/BMO/Extension.pm | 117 | ||||
-rw-r--r-- | extensions/BMO/lib/Constants.pm | 12 | ||||
-rw-r--r-- | extensions/BMO/template/en/default/bug/create/comment-dev-engagement-event.txt.tmpl | 90 | ||||
-rw-r--r-- | extensions/BMO/template/en/default/bug/create/create-dev-engagement-event.html.tmpl | 906 | ||||
-rw-r--r-- | extensions/BMO/web/js/dev_engagement.js | 290 | ||||
-rw-r--r-- | extensions/BMO/web/js/form_validate.js | 15 |
6 files changed, 917 insertions, 513 deletions
diff --git a/extensions/BMO/Extension.pm b/extensions/BMO/Extension.pm index 700199f51..321cdb29e 100644 --- a/extensions/BMO/Extension.pm +++ b/extensions/BMO/Extension.pm @@ -1199,6 +1199,9 @@ sub post_bug_after_creation { elsif ($format eq 'mozpr') { $self->_post_mozpr_bug($args); } + elsif ($format eq 'dev-engagement-event') { + $self->_post_dev_engagement($args); + } } sub _post_employee_incident_bug { @@ -1370,6 +1373,120 @@ sub _post_mozpr_bug { $bug->update($bug->creation_ts); } +sub _post_dev_engagement { + my ($self, $args) = @_; + my $vars = $args->{vars}; + my $parent_bug = $vars->{bug}; + my $template = Bugzilla->template; + my $cgi = Bugzilla->cgi; + my $params = Bugzilla->input_params; + my $old_user = Bugzilla->user; + + my $error_mode_cache = Bugzilla->error_mode; + Bugzilla->error_mode(ERROR_MODE_DIE); + + my $discussion_bug; + eval { + # Add attachment containing tab delimited field values for + # spreadsheet import. + my @columns = qw(event start_date end_date location attendees + audience desc mozilla_attending_list); + my @attach_values; + foreach my $column(@columns) { + my $value = $params->{$column} || ""; + $value =~ s/"/""/g; + push(@attach_values, qq{"$value"}); + } + + my @requested; + foreach my $param (grep(/^request_/, keys %$params)) { + next if !$params->{$param} || $param eq 'request_other_text'; + $param =~ s/^request_//; + push(@requested, ucfirst($param)); + } + push(@attach_values, '"' . join(",", @requested) . '"'); + + my $attachment = Bugzilla::Attachment->create({ + bug => $parent_bug, + creation_ts => $parent_bug->creation_ts, + data => join("\t", @attach_values), + description => 'Spreadsheet Data', + filename => 'dev_engagement_submission.txt', + ispatch => 0, + isprivate => 0, + mimetype => 'text/plain' + }); + + # Insert comment for attachment + $parent_bug->add_comment('', { isprivate => 0, + type => CMT_ATTACHMENT_CREATED, + extra_data => $attachment->id }); + delete $parent_bug->{'attachments'}; # So the new attachment displays properly + + # File discussion bug + Bugzilla->set_user(Bugzilla::User->new({ name => 'nobody@mozilla.org' })); + my $new_user = Bugzilla->user; + + # HACK: User needs to be in the editbugs and primary bug's group to allow + # setting of dependencies. + $new_user->{'groups'} = [ + Bugzilla::Group->new({ name => 'editbugs' }), + Bugzilla::Group->new({ name => 'mozilla-employee-confidential' }) + ]; + + my $recipients = { changer => $new_user }; + $vars->{original_reporter} = $old_user; + + $discussion_bug = Bugzilla::Bug->create({ + short_desc => '[discussion] ' . $parent_bug->short_desc, + product => 'Developer Engagement', + component => 'Events Request Discussion', + keywords => ['event-discussion-needs-review'], + bug_severity => 'normal', + groups => ['mozilla-employee-confidential'], + comment => 'This is the discussion for the request ' . + 'described in bug ' . $parent_bug->id . '.', + op_sys => 'All', + rep_platform => 'All', + version => 'unspecified' + }); + + # Set the needinfo flag on the discussion bug + my @new_flags; + foreach my $type (@{ $discussion_bug->flag_types }) { + next if $type->name ne 'needinfo'; + foreach my $requestee (DEV_ENGAGE_DISCUSS_NEEDINFO()) { + my $needinfo_flag = { + type_id => $type->id, + status => '?', + requestee => $requestee, + }; + push(@new_flags, $needinfo_flag); + } + } + $discussion_bug->set_flags(\@new_flags, []) if @new_flags; + $discussion_bug->update($discussion_bug->creation_ts); + Bugzilla::BugMail::Send($discussion_bug->id, $recipients); + + # Add discussion comment to the parent bug pointing to new bug + # and dependency link + $parent_bug->set_all({ dependson => { add => [ $discussion_bug->id ] } }); + $parent_bug->add_comment('This request is being discussed in bug ' . + $discussion_bug->id); + $parent_bug->update($parent_bug->creation_ts); + # No need to send mail for parent bug + }; + my $error = $@; + + Bugzilla->set_user($old_user); + Bugzilla->error_mode($error_mode_cache); + + if ($error || !$discussion_bug) { + warn "Failed to create additional dev-engagement bug: $error" if $error; + $vars->{'message'} = 'dev_engagement_creation_failed'; + } +} + sub _add_attachment { my ($self, $args, $attachment_args) = @_; diff --git a/extensions/BMO/lib/Constants.pm b/extensions/BMO/lib/Constants.pm index 23eaae9cb..b60c8fd37 100644 --- a/extensions/BMO/lib/Constants.pm +++ b/extensions/BMO/lib/Constants.pm @@ -24,10 +24,22 @@ use strict; use base qw(Exporter); our @EXPORT = qw( REQUEST_MAX_ATTACH_LINES + DEV_ENGAGE_DISCUSS_NEEDINFO ); # Maximum attachment size in lines that will be sent with a # requested attachment flag notification. use constant REQUEST_MAX_ATTACH_LINES => 1000; +# Requestees who need a needinfo flag set for the dev engagement +# discussion bug +use constant DEV_ENGAGE_DISCUSS_NEEDINFO => qw( + afabbro@mozilla.com + dcamp@mozilla.com + jswisher@mozilla.com + rchau@mozilla.com + stormy@mozilla.com + spersing@mozilla.com +); + 1; diff --git a/extensions/BMO/template/en/default/bug/create/comment-dev-engagement-event.txt.tmpl b/extensions/BMO/template/en/default/bug/create/comment-dev-engagement-event.txt.tmpl index cb7473e22..0cfcf7887 100644 --- a/extensions/BMO/template/en/default/bug/create/comment-dev-engagement-event.txt.tmpl +++ b/extensions/BMO/template/en/default/bug/create/comment-dev-engagement-event.txt.tmpl @@ -20,8 +20,33 @@ Email Address: Role in relation to event: [%+ cgi.param('role') %] +Vouched Mozillian: +[%+ cgi.param('vouched_mozillian') %] + +[% IF cgi.param('vouched_mozillian') == 'Yes' %] +Mozillian URL: +[%+ cgi.param('mozillian_profile_url') %] +[% END %] + :: +Developer Event?: +[%+ cgi.param('developer_event') %] + +Is Mozilla Attending?: +[%+ cgi.param('mozilla_attending') %] + +[% IF cgi.param('mozilla_attending') == 'Yes' %] +Mozilla Attending List: +[%+ cgi.param('mozilla_attending_list') %] +[% END %] + +Code of Conduct?: +[%+ cgi.param('code_of_conduct') %] + +Code of Conduct URL: +[%+ cgi.param('code_of_conduct_url') %] + Event Name: [%+ cgi.param('event') %] @@ -32,6 +57,9 @@ End Date: [%+ cgi.param('end_date') %] Event Location: +[%+ cgi.param('event_location') %] + +Event Location Description: [%+ cgi.param('location') || "-" %] Venue: @@ -46,39 +74,55 @@ Expected Attendees: Event Description: [%+ cgi.param('desc') || "-" %] -Primary Audience: -[%+ cgi.param('audience') || "-" %] +:: Relevant Products: -[% "\n* Firefox OS" IF cgi.param('product-fxos') %] -[% "\n* Firefox Web Browser" IF cgi.param('product-fx') %] -[% "\n* Webmaker" IF cgi.param('product-webmaker') %] -[% "\n* Persona" IF cgi.param('product-persona') %] -[% "\n* Marketplace" IF cgi.param('product-marketplace') %] -[% "\n* Thunderbird" IF cgi.param('product-tb') %] -[% "\n* The Free and Open Web" IF cgi.param('product-fow') %] -[% "\n* Other: " _ cgi.param('product-other-text') IF cgi.param('product-other') %] +[% "\n* Firefox OS" IF cgi.param('product_fxos') %] +[% "\n* Firefox Web Browser" IF cgi.param('product_fx') %] +[% "\n* Webmaker" IF cgi.param('product_webmaker') %] +[% "\n* Persona" IF cgi.param('product_persona') %] +[% "\n* Marketplace" IF cgi.param('product_marketplace') %] +[% "\n* Thunderbird" IF cgi.param('product_tb') %] +[% "\n* The Free and Open Web" IF cgi.param('product_fow') %] +[% "\n* Developer Tools" IF cgi.param('product_devtools') %] +[% "\n* Other: " _ cgi.param('product_other_text') IF cgi.param('product_other') %] + +Option to Sponsor a Booth?: +[%+ cgi.param('sponsor_booth') %] + +Need a Speaker?: +[%+ cgi.param('speaker_needed') %] + +[% IF cgi.param('speaker_needed') == 'Yes' %] +Speaker Needed Topic: +[%+ cgi.param('speaker_needed_topic') %] +[% END %] + +Development Session?: +[%+ cgi.param('development_session') %] :: Requests: -[% "\n* Keynote Presentation" IF cgi.param('request-keynote') %] -[% "\n* Talk Presentation" IF cgi.param('request-talk') %] -[% "\n* Workshop" IF cgi.param('request-workshop') %] -[% "\n* Sponsorship" IF cgi.param('request-sponsorship') %] -[% "\n* Other: " _ cgi.param('request-other-text') IF cgi.param('request-other') %] +[% "\n* Keynote Presentation" IF cgi.param('request_keynote') %] +[% "\n* Talk Presentation" IF cgi.param('request_talk') %] +[% "\n* Workshop" IF cgi.param('request_workshop') %] +[% "\n* Sponsorship" IF cgi.param('request_sponsorship') %] +[% "\n* Other: " _ cgi.param('request_other_text') IF cgi.param('request_other') %] -Suggested sponsorship amount/level: -[%+ cgi.param('sponsorship-suggestion') || "-" %] +Mozilla Sponsored Event Before?: +[%+ cgi.param('previous_event') %] -Already Registered Mozillians: -[%+ cgi.param('mozillians') || "-" %] +[% IF cgi.param('previous_event') == 'Yes' %] +Previous Event Year: +[%+ cgi.param('previous_event_year') %] -Requesting A Specific Person: -[%+ cgi.param('specific') || "-" %] +Previous Event Name: +[%+ cgi.param('previous_event_name') %] +[% END %] -Alternative Person: -[%+ cgi.param('fallback') || "-" %] +Suggested sponsorship amount/level: +[%+ cgi.param('sponsorship_suggestion') || "-" %] Anything Else: [%+ cgi.param('else') || "-" %] diff --git a/extensions/BMO/template/en/default/bug/create/create-dev-engagement-event.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-dev-engagement-event.html.tmpl index ef6737098..9665bcc27 100644 --- a/extensions/BMO/template/en/default/bug/create/create-dev-engagement-event.html.tmpl +++ b/extensions/BMO/template/en/default/bug/create/create-dev-engagement-event.html.tmpl @@ -9,164 +9,49 @@ [% PROCESS global/variables.none.tmpl %] [% inline_css = BLOCK %] - #bug_form { - max-width: 50em; - } - - #bug_form th { - text-align: left; - padding-top: 0.5em; - } - - #bug_form .section-head { - font-size: larger; - padding-top: 1em; - } - - #bug_form th:not(.section-head), #bug_form td { - padding-left: 2em; - } - - #bug_form .mandatory { - color: red; - } - - #bug_form .blurb { - font-style: italic; - } - - #bug_form .wide { - width: 40em; - } - - #bug_form input[disabled] { - background: transparent; - } -[% END %] - -[% inline_js = BLOCK %] -// <script> - function onRequestOtherChange() { - var cb = document.getElementById('request-other'); - var input = document.getElementById('request-other-text'); - input.disabled = !cb.checked; - if (cb.checked) - input.focus(); - } - - function onRequestSponsorshipChange() { - var cb = document.getElementById('request-sponsorship'); - if (cb.checked) { - YAHOO.util.Dom.removeClass('sponsorship-suggestion-fields', 'bz_default_hidden'); - } - else { - YAHOO.util.Dom.addClass('sponsorship-suggestion-fields', 'bz_default_hidden'); - } - } - - function onProductOtherChange() { - var cb = document.getElementById('product-other'); - var input = document.getElementById('product-other-text'); - input.disabled = !cb.checked; - if (cb.checked) - input.focus(); - } - - function onSubmit() { - if (document.getElementById('request-other').checked - && !isFilledOut('request-other-text') - ) { - document.getElementById('request-other').checked = false; - onRequestOtherChange(); - } - - var alert_text = ''; - - if (!isFilledOut('name')) - alert_text += "Please enter your name.\n"; - if (!isFilledOut('email')) - alert_text += "Please enter your email address.\n"; - if (!isFilledOut('role')) - alert_text += "Please enter your role.\n"; - - if (!isFilledOut('event')) - alert_text += "Please enter the event name.\n"; - if (!isFilledOut('start_date')) - alert_text += "Please enter the event start date.\n"; - if (!isFilledOut('end_date')) - alert_text += "Please enter the event end date.\n"; - if (!isFilledOut('attendees')) - alert_text += "Please enter number of expected attendees.\n"; - if (!isFilledOut('audience')) - alert_text += "Please enter primary audience.\n"; - - - var wb = ''; - if (document.getElementById('request-keynote').checked) - wb += '[keynote] '; - if (document.getElementById('request-talk').checked) - wb += '[talk] '; - if (document.getElementById('request-workshop').checked) - wb += '[workshop] '; - if (document.getElementById('request-sponsorship').checked) - wb += '[sponsorship] '; - if (document.getElementById('request-other').checked) - wb += '[other] '; - if (wb == '') - alert_text += "Please select what you're requesting.\n"; - - if (alert_text != '') { - alert(alert_text); - return false; - } - - document.getElementById('status_whiteboard').value = wb.replace(/ $/, ''); - var summary = document.getElementById('event').value + ', ' + long_start_date(); - var loc = document.getElementById('location').value; - if (loc) - summary = summary + ' (' + loc + ')'; - document.getElementById('short_desc').value = summary; - document.getElementById('bug_file_loc').value = document.getElementById('link').value; - document.getElementById('cf_due_date').value = document.getElementById('start_date').value; - - return true; - } - - function long_start_date() { - var ymd = document.getElementById('start_date').value.split('-'); - if (ymd.length != 3) - return ''; - var month = YAHOO.bugzilla.calendar_start_date.cfg.getProperty('MONTHS_LONG')[ymd[1] - 1]; - return month + ' ' + ymd[0]; - } - - YAHOO.util.Event.onDOMReady(function() { - createCalendar('start_date'); - createCalendar('end_date'); - onRequestOtherChange(); - onRequestSponsorshipChange(); - onProductOtherChange(); - }); -// </script> -[% END %] - -[% mandatory = BLOCK %] - <span class="mandatory" title="Mandatory">*</span> +#dev_form { + width: 60%; +} +#dev_form .required:after { + content: " *"; + color: red; +} +#dev_form .field_label { + text-align: left; + font-weight: bold; +} +#dev_form .field_desc, +#dev_form .head_desc { + word-wrap: normal; +} +#dev_form .head_desc { + font-size: 1.5em; + padding-bottom: .5em; +} +#dev_form .form_section { + margin-bottom: 1em; + padding-left: 2em; +} +.yui-calcontainer { + z-index: 2; +} [% END %] [% PROCESS global/header.html.tmpl title = "Developer Events Request Form" style = inline_css style_urls = [ 'skins/standard/enter_bug.css' ] - javascript = inline_js - javascript_urls = [ 'extensions/BMO/web/js/form_validate.js', 'js/field.js', 'js/util.js' ] + javascript_urls = [ 'js/field.js', + 'js/util.js', + 'extensions/BMO/web/js/form_validate.js', + 'extensions/BMO/web/js/dev_engagement.js' ] yui = [ 'calendar' ] %] <h2>Developer Events Request Form</h2> -<form method="post" action="post_bug.cgi" id="bug_form" class="enter_bug_form" - enctype="multipart/form-data" onsubmit="return onSubmit();"> +<form method="post" action="post_bug.cgi" id="dev_form" + class="enter_bug_form" enctype="multipart/form-data"> <input type="hidden" name="format" value="dev-engagement-event"> <input type="hidden" name="product" value="Developer Engagement"> <input type="hidden" name="short_desc" id="short_desc" value=""> @@ -175,6 +60,7 @@ <input type="hidden" name="op_sys" value="All"> <input type="hidden" name="priority" value="--"> <input type="hidden" name="version" value="unspecified"> +<input type="hidden" name="keywords" value="event-request-under-review"> <input type="hidden" name="bug_severity" id="bug_severity" value="normal"> <input type="hidden" name="comment" id="comment" value=""> <input type="hidden" name="status_whiteboard" id="status_whiteboard" value=""> @@ -183,354 +69,394 @@ <input type="hidden" name="groups" id="groups" value="mozilla-employee-confidential"> <input type="hidden" name="token" value="[% token FILTER html %]"> -<table id="bug_form"> - -<tr> - <td> - <p> - Hi! Thanks so much for asking Mozilla to participate at your event! - </p> - <p> - The Developer Events Team evaluates each request individually, based on - multiple criteria, including quarterly goals and priorities. We meet at - least biweekly, and this form is designed to gather all the information - we need to evaluate each request at these meetings. Please take a minute - to fill it out thoroughly so we can process your request as soon as - possible. - </p> - <p> - Please review our <a href="https://wiki.mozilla.org/Engagement/Developer_Engagement/Event_request_guidelines"> - event request guidelines</a> for information about how we evaluate requests. - </p> - </td> -</tr> - -<tr> - <th class="section-head"> - First, tell us about yourself! - </th> -</tr> - -<tr> - <th> - What is your name? [% mandatory FILTER none %] - </th> -</tr> -<tr> - <td> - <input type="text" name="name" id="name" size="40" class="wide" - value="[% user.name FILTER html %]"> - </td> -</tr> - -<tr> - <th> - Please provide your email address. [% mandatory FILTER none %] - </th> -</tr> -<tr> - <td> - <input type="text" name="email" id="email" size="40" class="wide" - value="[% user.login FILTER html %]"> - </td> -</tr> - -<tr> - <th> - What is your role in relation to this event? [% mandatory FILTER none %] - </th> -</tr> -<tr> - <td> - <div class="blurb"> - eg. organizer, speaker/atendee (past), speaker/attendee (current), etc. - </div> - <input type="text" name="role" id="role" size="40" class="wide"> - </td> -</tr> - -<tr> - <th class="section-head"> - Let's start with the basics. - </th> -</tr> - -<tr> - <th> - Event Name [% mandatory FILTER none %] - </th> -</tr> -<tr> - <td> - <input type="text" name="event" id="event" size="40" class="wide"> - </td> -</tr> - -<tr> - <th> - Start Date [% mandatory FILTER none %] - </th> -</tr> -<tr> - <td> - <input type="text" name="start_date" id="start_date" size="15" class="date" - onchange="updateCalendarFromField(this)"> - <button type="button" class="calendar_button" - id="button_calendar_start_date" - onclick="showCalendar('start_date')"> - <span>Calendar</span> - </button> - <div id="con_calendar_start_date"></div> - </td> -</tr> - -<tr> - <th> - End Date [% mandatory FILTER none %] - </th> -</tr> -<tr> - <td> - <input type="text" name="end_date" id="end_date" size="15" class="date" - onchange="updateCalendarFromField(this)"> - <button type="button" class="calendar_button" - id="button_calendar_end_date" - onclick="showCalendar('end_date')"> - <span>Calendar</span> - </button> - <div id="con_calendar_end_date"></div> - </td> -</tr> - -<tr> - <th> +<p>Hi! Thanks so much for asking Mozilla to participate at your event!</p> +<p>The Developer Events Team evaluates each request individually, based on + multiple criteria, including quarterly goals and priorities. We meet at + least biweekly, and this form is designed to gather all the information + we need to evaluate each request at these meetings. Please take a minute + to fill it out thoroughly so we can process your request as soon as + possible.</p> +<p>Please review our + <a href="https://wiki.mozilla.org/Engagement/Developer_Engagement/Event_request_guidelines"> + event request guidelines</a> for information about how we evaluate requests.</p> + +<div class="head_desc"> + First, tell us about yourself! +</div> + +<div class="form_section"> + <div class="field_label required"> + What is your name? + </div> + <input type="text" name="name" id="name" size="40" class="wide" + value="[% user.name FILTER html %]"> +</div> + +<div class="form_section"> + <div class="field_label required"> + Please provide your email address. + </div> + <input type="text" name="email" id="email" size="40" class="wide" + value="[% user.login FILTER html %]"> +</div> + +<div class="form_section"> + <div class="field_label required"> + What is your role in relation to this event? + </div> + <div class="field_desc"> + eg. organizer, speaker/attendee (past), speaker/attendee (current), etc. + </div> + <input type="text" name="role" id="role" size="40" class="wide"> +</div> + +<div class="form_section"> + <div class="field_label required"> + Are you a vouched Mozillian? + </div> + <select id="vouched_mozillian" name="vouched_mozillian"> + <option value="">Select</option> + <option value="Yes">Yes</option> + <option value="No">No</option> + </select> +</div> + +<div id="mozillian_profile_url_section" class="form_section bz_default_hidden"> + <div class="field_label required"> + Mozillian profile URL + </div> + <input type="text" name="mozillian_profile_url" + id="mozillian_profile_url" size="40" class="wide"> +</div> + +<div class="head_desc"> + Let's start with the basics. +</div> + +<div class="form_section"> + <div class="field_label"> + Is this a developer event? + </div> + <select id="developer_event" name="developer_event"> + <option value="">Select</option> + <option value="Yes">Yes</option> + <option value="No">No</option> + </select> + <div id="developer_event_warning" class="bz_default_hidden"> + The Developer Events Team only participates in developer events. + Form submission has been disabled. + </div> +</div> + +<div class="form_section"> + <div class="field_label"> + Is someone from Mozilla attending? + </div> + <select id="mozilla_attending" name="mozilla_attending"> + <option value="">Select</option> + <option value="Yes">Yes</option> + <option value="No">No</option> + </select> + <div id="mozilla_attending_warning" class="warning bz_default_hidden"> + The Developer Events Team usually doesn’t sponsor an event unless someone + from Mozilla is attending. If you would like to request a speaker, there’s + an opportunity to do so later on this page. + </div> +</div> + +<div id="mozilla_attending_list_section" class="form_section bz_default_hidden"> + <div class="field_label required"> + Please list the names of anyone from Mozilla who are already registered to + attend, speak, or participate in this event. + </div> + <input type="text" name="mozilla_attending_list" + id="mozilla_attending_list" size="40" class="wide"> +</div> + +<div class="form_section"> + <div class="field_label required"> + Do you have a code of conduct? + </div> + <select id="code_of_conduct" name="code_of_conduct"> + <option value="">Select</option> + <option value="Yes">Yes</option> + <option value="No">No</option> + </select> + <div id="code_of_conduct_warning" class="warning bz_default_hidden"> + Mozilla only participates in events that have a code of conduct. + Fom submission has been disabled. + </div> +</div> + +<div id="code_of_conduct_url_section" class="form_section bz_default_hidden"> + <div class="field_label required"> + Code of Conduct URL + </div> + <input type="text" name="code_of_conduct_url" + id="code_of_conduct_url" size="40" class="wide"> +</div> + +<div class="form_section"> + <div class="field_label required"> + Event Name + </div> + <input type="text" name="event" id="event" size="40" class="wide"> +</div> + +<div class="form_section"> + <div class="field_label required"> + Start Date + </div> + <input type="text" name="start_date" id="start_date" size="15" class="date" + onchange="updateCalendarFromField(this)"> + <button type="button" class="calendar_button" + id="button_calendar_start_date" + onclick="showCalendar('start_date')"> + <span>Calendar</span> + </button> + <div id="con_calendar_start_date"></div> +</div> + +<div class="form_section"> + <div class="field_label required"> + End Date + </div> + <input type="text" name="end_date" id="end_date" size="15" class="date" + onchange="updateCalendarFromField(this)"> + <button type="button" class="calendar_button" + id="button_calendar_end_date" + onclick="showCalendar('end_date')"> + <span>Calendar</span> + </button> + <div id="con_calendar_end_date"></div> +</div> + +<div class="form_section"> + <div class="field_label required"> Event Location - </th> -</tr> -<tr> - <td> - <div class="blurb"> - Include city, state, and country. Please write "Multiple" if this event - takes place across several locations. - </div> - <input type="text" name="location" id="location" size="40" class="wide"> - </td> -</tr> - -<tr> - <th> + </div> + <select id="event_location" name="event_location"> + <option value="">Select</option> + <option value="Africa">Africa</option> + <option value="Asia">Asia</option> + <option value="Australia">Australia</option> + <option value="Europe">Europe</option> + <option value="North America">North America</option> + <option value="Central / South America">Central / South America</option> + <option value="Multiple">Multiple</option> + <option value="Online only">Online only</option> + </select> +</div> + +<div class="form_section"> + <div class="field_label required"> + Event Location Description + </div> + <div class="field_desc"> + Include city, state, and country. + </div> + <input type="text" name="location" id="location" size="40" class="wide"> +</div> + +<div class="form_section"> + <div class="field_label"> Venue - </th> -</tr> -<tr> - <td> - <div class="blurb"> - What is the name of the venue where your event will be held? Enter TBD if - you don't know yet. - </div> - <input type="text" name="venue" id="venue" size="40" class="wide"> - </td> -</tr> - -<tr> - <th> + </div> + <div class="field_desc"> + What is the name of the venue where your event will be held? Enter TBD if + you don't know yet. + </div> + <input type="text" name="venue" id="venue" size="40" class="wide"> +</div> + +<div class="form_section"> + <div class="field_label"> Weblink - </th> -</tr> -<tr> - <td> - <div class="blurb"> - Weblink to the event site, Eventbrite page, Lanyrd page, Meetup page, etc. - </div> - <input type="text" name="link" id="link" size="40" class="wide"> - </td> -</tr> - -<tr> - <th> - Number of expected attendees [% mandatory FILTER none %] - </th> -</tr> -<tr> - <td> - <input type="text" name="attendees" id="attendees" size="15"> - </td> -</tr> - -<tr> - <th> - Please give a [short] description of the event. [% mandatory FILTER none %] - </th> -</tr> -<tr> - <td> - <div class="blurb"> - Include track topics, presentation topics, event format. - </div> - <textarea name="desc" id="desc" rows="10" cols="40" class="wide"></textarea> - </td> -</tr> - -<tr> - <th> - Who is the primary audience for this event? [% mandatory FILTER none %] - </th> -</tr> -<tr> - <td> - <div class="blurb"> - Developers (specify coding language and platform), business development, - marketing associates, corporate executives, etc. - </div> - <input type="text" name="audience" id="audience" size="40" class="wide"> - </td> -</tr> - -<tr> - <th> - Which Mozilla products/projects are most relevant to this event? [% mandatory FILTER none %] - </th> -</tr> -<tr> - <td> - <div class="blurb"> - Please select all that apply. - See <a href="https://www.mozilla.org/en-US/products/" target="_blank">mozilla.org/products</a> - for more information about Mozilla products. - </div> - <input type="checkbox" name="product-fxos" id="product-fxos"> - <label for="product-fxos">Firefox OS</label><br> - <input type="checkbox" name="product-fx" id="product-fx"> - <label for="product-fx">Firefox Web Browser</label><br> - <input type="checkbox" name="product-webmaker" id="product-webmaker"> - <label for="product-webmaker">Webmaker</label><br> - <input type="checkbox" name="product-persona" id="product-persona"> - <label for="product-persona">Persona</label><br> - <input type="checkbox" name="product-marketplace" id="product-marketplace"> - <label for="product-marketplace">Marketplace</label><br> - <input type="checkbox" name="product-tb" id="product-tb"> - <label for="product-tb">Thunderbird</label><br> - <input type="checkbox" name="product-fow" id="product-fow"> - <label for="product-fow">The Free and Open Web</label><br> - <input type="checkbox" name="product-other" id="product-other" onchange="onProductOtherChange()"> - <label for="product-other">Other:</label> - <input type="text" name="product-other-text" id="product-other-text" size="40" disabled> - </td> -</tr> - -<tr> - <th class="section-head"> - Tell us more about what you're looking for! - </th> -</tr> - -<tr> - <th> - What are you requesting from Mozilla? [% mandatory FILTER none %] - </th> -</tr> -<tr> - <td> - <div class="blurb"> - Please select all that apply. - </div> - <input type="checkbox" name="request-keynote" id="request-keynote"> - <label for="request-keynote">Keynote Presentation</label><br> - <input type="checkbox" name="request-talk" id="request-talk"> - <label for="request-talk">Talk Presentation (non-keynote)</label><br> - <input type="checkbox" name="request-workshop" id="request-workshop"> - <label for="request-workshop">Workshop</label><br> - <input type="checkbox" name="request-sponsorship" id="request-sponsorship" onchange="onRequestSponsorshipChange()"> - <label for="request-sponsorship">Sponsorship</label><br> - <input type="checkbox" name="request-other" id="request-other" onchange="onRequestOtherChange()"> - <label for="request-other">Other:</label> - <input type="text" name="request-other-text" id="request-other-text" size="40" disabled> - </td> -</tr> - -<tbody id="sponsorship-suggestion-fields"> - <tr> - <th> - If requesting sponsorship, what amount/level do you suggest? - </th> - </tr> - <tr> - <td> - <input type="text" name="sponsorship-suggestion" id="sponsorship-suggestion" size="40" class="wide"> - </td> - </tr> -</tbody> - -<tr> - <th> - Please list the names of anyone from Mozilla who are already registered to - attend, speak, or participate in this event. - </th> -</tr> -<tr> - <td> - <input type="text" name="mozillians" id="mozillians" size="40" class="wide"> - </td> -</tr> - -<tr> - <th> - Are you requesting a specific person to present or participate at this - event? If so, please list their name(s). - </th> -</tr> -<tr> - <td> - <input type="text" name="specific" id="specific" size="40" class="wide"> - </td> -</tr> - -<tr> - <th> - If this individual is unable to attend/speak/participate in this event, is - there anyone else you would like to request? - </th> -</tr> -<tr> - <td> - <input type="text" name="fallback" id="fallback" size="40" class="wide"> - </td> -</tr> - -<tr> - <th> + </div> + <div class="field_desc"> + Weblink to the event site, Eventbrite page, Lanyrd page, Meetup page, etc. + </div> + <input type="text" name="link" id="link" size="40" class="wide"> +</div> + +<div class="form_section"> + <div class="field_label required"> + Number of expected attendees + </div> + <input type="text" name="attendees" id="attendees" size="15"> +</div> + +<div class="form_section"> + <div class="field_label required"> + Please give a [short] description of the event. + </div> + <div class="field_desc"> + Include track topics, presentation topics, event format. + </div> + <textarea name="desc" id="desc" rows="10" cols="40" class="wide"></textarea> +</div> + +<div class="head_desc"> + Some more detail on the event. +</div> + +<div class="form_section"> + <div class="field_label required"> + Which Mozilla products/projects are most relevant to this event? + </div> + <div class="field_desc"> + Please select all that apply. See + <a href="https://www.mozilla.org/en-US/products/" target="_blank"> + mozilla.org/products</a> for more information about Mozilla products. + </div> + <input type="checkbox" name="product_fxos" id="product_fxos"> + <label for="product_fxos">Firefox OS</label><br> + <input type="checkbox" name="product_fx" id="product_fx"> + <label for="product_fx">Firefox Web Browser</label><br> + <input type="checkbox" name="product_webmaker" id="product_webmaker"> + <label for="product_webmaker">Webmaker</label><br> + <input type="checkbox" name="product_persona" id="product_persona"> + <label for="product_persona">Persona</label><br> + <input type="checkbox" name="product_marketplace" id="product_marketplace"> + <label for="product_marketplace">Marketplace</label><br> + <input type="checkbox" name="product_tb" id="product_tb"> + <label for="product_tb">Thunderbird</label><br> + <input type="checkbox" name="product_fow" id="product_fow"> + <label for="product_fow">The Free and Open Web</label><br> + <input type="checkbox" name="product_devtools" id="product_devtools"> + <label for="product_devtools">Developer Tools</label><br> + <input type="checkbox" name="product_other" id="product_other"> + <label for="product_other">Other:</label> + <input type="text" name="product_other_text" id="product_other_text" + size="40" disabled> +</div> + +<div class="form_section"> + <div class="field_label required"> + Do you have an option to sponsor a booth? + </div> + <select id="sponsor_booth" name="sponsor_booth"> + <option value="">Select</option> + <option value="Yes">Yes</option> + <option value="No">No</option> + </select> +</div> + +<div class="form_section"> + <div class="field_label required"> + Do you need a speaker? + </div> + <select id="speaker_needed" name="speaker_needed"> + <option value="">Select</option> + <option value="Yes">Yes</option> + <option value="No">No</option> + </select> +</div> + +<div id="speaker_needed_detail_section" class="form_section bz_default_hidden"> + <div class="field_label required"> + What topic do you want someone to speak about? + </div> + <div class="field_desc"> + Please be specific so that we can find a great speaker for you. Examples: + Developer Tools for Firefox, the future of the Web, CSS media queries. + </div> + <input type="text" name="speaker_needed_topic" + id="speaker_needed_topic" size="40" class="wide"> +</div> + +<div class="form_section"> + <div class="field_label required"> + Will this event include a session about developing with HTML, CSS, or + JavaScript? + </div> + <select id="development_session" name="development_session"> + <option value="">Select</option> + <option value="Yes">Yes</option> + <option value="No">No</option> + <option value="To be determined">To be determined</option> + </select> +</div> + +<div class="head_desc"> + Tell us more about what you're looking for! +</div> + +<div class="form_section"> + <div class="field_label required"> + What are you requesting from Mozilla? + </div> + <div class="field_desc"> + Please select all that apply. + </div> + <input type="checkbox" name="request_keynote" id="request_keynote"> + <label for="request_keynote">Keynote Presentation</label><br> + <input type="checkbox" name="request_talk" id="request_talk"> + <label for="request_talk">Talk Presentation (non-keynote)</label><br> + <input type="checkbox" name="request_workshop" id="request_workshop"> + <label for="request_workshop">Workshop</label><br> + <input type="checkbox" name="request_sponsorship" id="request_sponsorship" + onchange="onRequestSponsorshipChange()"> + <label for="request_sponsorship">Sponsorship</label><br> + <input type="checkbox" name="request_other" id="request_other"> + <label for="request_other">Other:</label> + <input type="text" name="request_other_text" id="request_other_text" + size="40" disabled> +</div> + +<div class="form_section"> + <div class="field_label required"> + Has Mozilla sponsored this event before? + </div> + <select id="previous_event" name="previous_event"> + <option value="">Select</option> + <option value="Yes">Yes</option> + <option value="No">No</option> + </select> +</div> + +<div id="previous_event_details_section" class="form_section bz_default_hidden"> + <div class="field_label required"> + Year + </div> + <input type="text" name="previous_event_year" + id="previous_event_year" size="40" class="wide"> + <div class="field_label required"> + Name of Event + </div> + <input type="text" name="previous_event_name" + id="previous_event_name" size="40" class="wide"> +</div> + +<div class="form_section"> + <div class="field_label"> + If requesting sponsorship, what amount/level do you suggest? + </div> + <div class="field_desc"> + Please include the currency. + </div> + <input type="text" name="sponsorship_suggestion" id="sponsorship_suggestion" + size="40" class="wide"> +</div> + +<div class="form_section"> + <div class="field_label"> Please upload a Sponsorship Prospectus if you have one. - </th> -</tr> -<tr> - <td> - <input type="file" name="data" id="data" size="40"> - <input type="hidden" name="contenttypemethod" value="autodetect"> - <input type="hidden" id="description" name="description" value="Sponsorship Prospectus"> - </td> -</tr> - -<tr> - <th> + </div> + <input type="file" name="data" id="data" size="40"> + <input type="hidden" name="contenttypemethod" value="autodetect"> + <input type="hidden" id="description" name="description" + value="Sponsorship Prospectus"> +</div> + +<div class="form_section"> + <div class="field_label"> Anything else that may help us review this request? - </th> -</tr> -<tr> - <td> - <input type="text" name="else" id="else" size="40" class="wide"> - </td> -</tr> - -<tr> - <td> </td> -</tr> -<tr> - <td> - <input type="submit" id="commit" value="Submit Request"> - </td> -</tr> - -</table> + </div> + <input type="text" name="else" id="else" size="40" class="wide"> +</div> + +<input type="submit" id="commit" value="Submit Request"> </form> diff --git a/extensions/BMO/web/js/dev_engagement.js b/extensions/BMO/web/js/dev_engagement.js new file mode 100644 index 000000000..0bb7313b1 --- /dev/null +++ b/extensions/BMO/web/js/dev_engagement.js @@ -0,0 +1,290 @@ +/* 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. */ + +var DE = { + formUpdate: function () { + var sections = { + developer_event_warning: false, + code_of_conduct_warning: false, + mozilla_attending_warning: false, + mozillian_profile_url_section: false, + mozilla_attending_list_section: false, + code_of_conduct_url_section: false, + speaker_needed_detail_section: false, + previous_event_details_section: false + }; + var commit_disabled = false; + + if (fieldValue('developer_event') == 'No') { + commit_disabled = true; + sections.developer_event_warning = true; + } + + if (fieldValue('mozilla_attending') == 'No') { + sections.mozilla_attending_warning = true; + } + else if (fieldValue('mozilla_attending') == 'Yes') { + sections.mozilla_attending_list_section = true; + } + + if (fieldValue('code_of_conduct') == 'No') { + commit_disabled = true; + sections.code_of_conduct_warning = true; + } + else if (fieldValue('code_of_conduct') == 'Yes') { + sections.code_of_conduct_url_section = true; + } + + if (fieldValue('vouched_mozillian') == 'Yes') { + sections.mozillian_profile_url_section = true; + } + + if (fieldValue('previous_event') == 'Yes') { + sections.previous_event_details_section = true; + } + + if (fieldValue('speaker_needed') == 'Yes') { + sections.speaker_needed_detail_section = true; + } + + for (section in sections) { + if (sections[section]) { + DE.removeClass(document.getElementById(section), + 'bz_default_hidden'); + } + else { + DE.addClass(document.getElementById(section), + 'bz_default_hidden'); + } + } + YAHOO.util.Dom.get('commit').disabled = commit_disabled; + }, + focusOther: function (id, other_id) { + var cb = document.getElementById(id); + var input = document.getElementById(other_id); + input.disabled = !cb.checked; + if (cb.checked) input.focus(); + }, + onSubmit: function (ev) { + var alert_text = ''; + // Required fields check + var required_text_fields = { + 'name' : 'Please enter your name.', + 'email' : 'Please enter your email address.', + 'role' : 'Please enter your role.', + 'event' : 'Please enter the event name.', + 'start_date' : 'Please enter the event start date.', + 'end_date' : 'Please enter the event end date.', + 'location' : 'Please enter a location description for the event.', + 'attendees' : 'Please enter number of expected attendees.', + 'desc' : 'Please enter a description of the event.', + }; + + var required_selects = { + 'vouched_mozillian' : 'Please select if you are a vouched mozillian.', + 'developer_event' : 'Please select if this is a developer event.', + 'mozilla_attending' : 'Please select if Mozilla is attending the event.', + 'code_of_conduct' : 'Please select if the event has a code of conduct.', + 'event_location' : 'Please a location for the event.', + 'previous_event' : 'Please select if Mozilla has sponsored this event before.', + 'development_session' : 'Please select if this event includes a development session.', + }; + + if (fieldValue('vouched_mozillian') == 'Yes') + required_text_fields['mozillian_profile_url'] + = 'Please enter your mozillian profile url.'; + if (fieldValue('mozilla_attending') == 'Yes') + required_text_fields['mozilla_attending_list'] + = 'Please enter a list of Mozilla persons attending the event.'; + if (fieldValue('code_of_conduct') == 'Yes') + required_text_fields['code_of_conduct_url'] + = 'Please enter a code of conduct url.'; + if (fieldValue('previous_event') == 'Yes') { + required_text_fields['previous_event_year'] + = 'Please select a year for the previous sponsored event.'; + required_text_fields['previous_event_name'] + = 'Please enter a name for the previous sponsored event.'; + } + + var relevant_products = [ + 'product_fxos', + 'product_fx', + 'product_webmaker', + 'product_persona', + 'product_marketplace', + 'product_tb', + 'product_fow', + 'product_devtools', + 'product_other', + ]; + var found = 0; + for (var i = 0, l = relevant_products.length; i < l; i ++) { + if (isChecked(relevant_products[i])) found = 1; + } + if (!found) + alert_text += "Please check one or more relevant products.\n"; + if (isChecked('product_other')) + required_text_fields['product_other_text'] + = 'Please enter a value for other relevant product.'; + + var request_types = [ + 'request_keynote', + 'request_talk', + 'request_workshop', + 'request_sponsorship', + 'request_other' + ]; + found = 0; + for (var i = 0, l = request_types.length; i < l; i ++) { + if (isChecked(request_types[i])) found = 1; + } + if (!found) + alert_text += "Please check one or more items being requested of Mozilla.\n"; + if (isChecked('request_other')) + required_text_fields['request_other_text'] + = 'Please enter a value for other item being requested.'; + + for (field in required_text_fields) { + if (!isFilledOut(field)) + alert_text += required_text_fields[field] + "\n"; + } + for (field in required_selects) { + if (!fieldValue(field)) + alert_text += required_selects[field] + "\n"; + } + if (alert_text != '') { + alert(alert_text); + YAHOO.util.Event.stopEvent(ev); + } + + // Whiteboard value + var wb = ''; + var location_wb_map = { + 'Africa' : 'africa', + 'Asia' : 'asia', + 'Australia' : 'australia', + 'Europe' : 'europe', + 'North America' : 'north-america', + 'Central / South America' : 'central-south-america', + 'Multiple' : 'multiple', + 'Online only' : 'online', + }; + wb += '[location:' + location_wb_map[fieldValue('event_location')] + '] '; + + var request_items = []; + if (document.getElementById('request_keynote').checked) + request_items.push('keynote'); + if (document.getElementById('request_talk').checked) + request_items.push('talk'); + if (document.getElementById('request_workshop').checked) + request_items.push('workshop'); + if (document.getElementById('request_sponsorship').checked) + request_items.push('sponsorship'); + if (document.getElementById('request_other').checked) + request_items.push('other'); + wb += '[requesting:' + request_items.join(',') + '] '; + + var product_items = []; + if (document.getElementById('product_fxos').checked) + product_items.push('firefox-os'); + if (document.getElementById('product_fx').checked) + product_items.push('firefox-web-browser'); + if (document.getElementById('product_webmaker').checked) + product_items.push('webmaker'); + if (document.getElementById('product_persona').checked) + product_items.push('persona'); + if (document.getElementById('product_marketplace').checked) + product_items.push('marketplace'); + if (document.getElementById('product_tb').checked) + product_items.push('thunderbird'); + if (document.getElementById('product_fow').checked) + product_items.push('open-web'); + if (document.getElementById('product_devtools').checked) + product_items.push('developer-tools'); + if (document.getElementById('product_other').checked) + product_items.push('other'); + wb += '[products:' + product_items.join(',') + '] '; + + if (fieldValue('developer_event') == 'Yes') + wb += '[developer-event:true] '; + var mozilla_attending = fieldValue('mozilla_attending') == 'Yes' ? 'true' : 'false'; + wb += '[mozilla-already-attending:' + mozilla_attending + '] '; + var vouched = fieldValue('vouched_mozillian') == 'Yes' ? 'true' : 'false'; + wb += '[requested-by-mozillian:' + vouched + '] '; + if (fieldValue('code_of_conduct') == 'Yes') + wb += '[code-of-conduct:true] '; + var previous_event = fieldValue('previous_event') == 'Yes' ? 'true' : 'false'; + wb += '[past-sponsorship:' + previous_event + '] '; + var needs_speaker = fieldValue('speaker_needed') == 'Yes' ? 'true' : 'false'; + wb += '[needs-speaker:' + needs_speaker + '] '; + var sponsor_booth = fieldValue('sponsor_booth') == 'Yes' ? 'true' : 'false'; + wb += '[option-to-sponsor-booth:' + sponsor_booth + '] '; + var dev_session_map = { + 'Yes' : 'true', + 'No' : 'false', + 'To be determined' : 'tbd', + }; + wb += '[open-web-session-at-event:' + + dev_session_map[fieldValue('development_session')] + '] '; + wb += '[expected-attendees:' + fieldValue('attendees') + '] '; + var prospectus = fieldValue('data') ? 'true' : 'false'; + wb += '[prospectus:' + prospectus + '] '; + document.getElementById('status_whiteboard').value = wb.replace(/ $/, ''); + + var summary = document.getElementById('event').value + ', ' + DE.long_start_date(); + var loc = document.getElementById('location').value; + if (loc) + summary = summary + ' (' + loc + ')'; + document.getElementById('short_desc').value = summary; + document.getElementById('bug_file_loc').value = document.getElementById('link').value; + document.getElementById('cf_due_date').value = document.getElementById('start_date').value; + }, + long_start_date: function () { + var ymd = document.getElementById('start_date').value.split('-'); + if (ymd.length != 3) + return ''; + var month = YAHOO.bugzilla.calendar_start_date.cfg.getProperty('MONTHS_LONG')[ymd[1] - 1]; + return month + ' ' + ymd[0]; + }, + hasClass: function (element, class_name) { + return element.className.match(new RegExp('(\\s|^)' + class_name + '(\\s|$)')); + }, + addClass: function (element, class_name) { + if (!DE.hasClass(element, class_name)) + element.className += " " + class_name; + }, + removeClass: function (element, class_name) { + if (DE.hasClass(element, class_name)) { + var reg = new RegExp('(\\s|^)' + class_name + '(\\s|$)'); + element.className = element.className.replace(reg,' '); + } + }, + init: function() { + YAHOO.util.Event.on('dev_form', 'submit', DE.onSubmit); + YAHOO.util.Event.on('product_other', 'change', function () { + DE.focusOther('product_other', 'product_other_text'); + }); + YAHOO.util.Event.on('request_other', 'change', function () { + DE.focusOther('request_other', 'request_other_text'); + }); + var select_inputs = [ + 'developer_event', + 'code_of_conduct', + 'vouched_mozillian', + 'mozilla_attending', + 'speaker_needed', + 'previous_event' + ]; + for (var i = 0, l = select_inputs.length; i < l; i++) { + YAHOO.util.Event.on(select_inputs[i], 'change', DE.formUpdate); + } + DE.formUpdate(); + createCalendar('start_date'); + createCalendar('end_date'); + } +}; +YAHOO.util.Event.onDOMReady(DE.init); diff --git a/extensions/BMO/web/js/form_validate.js b/extensions/BMO/web/js/form_validate.js index 7e9746a5c..53b16ab1c 100644 --- a/extensions/BMO/web/js/form_validate.js +++ b/extensions/BMO/web/js/form_validate.js @@ -39,3 +39,18 @@ function isOneChecked(form_nodelist) { } return false; } + +function fieldValue(elem_id) { + var el = document.getElementById(elem_id); + if (!el) { + console.error('Failed to find element: ' + elem_id); + return false; + } + if (el.type == 'text' + || el.type == 'textarea' + || el.type == 'file') + { + return el.value; + } + return el.options[el.selectedIndex].value; +} |