| [%# 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/ |
| # |
| # 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): Chris Lahey <clahey@ximian.com> [javascript fixes] |
| # Christian Reis <kiko@async.com.br> [javascript rewrite] |
| # Gervase Markham <gerv@gerv.net> |
| # Guy Pyrzak <guy.pyrzak@gmail.com> |
| #%] |
| |
| [% PROCESS "global/field-descs.none.tmpl" %] |
| |
| <script type="text/javascript"> |
| |
| var first_load = true; [%# is this the first time we load the page? %] |
| var last_sel = new Array(); [%# caches last selection %] |
| |
| [% IF Param('useclassification') %] |
| var useclassification = true; |
| var prods = new Array(); |
| [% ELSE %] |
| var useclassification = false; |
| [% END %] |
| var cpts = new Array(); |
| var vers = new Array(); |
| [% IF Param('usetargetmilestone') %] |
| var tms = new Array(); |
| [% END %] |
| |
| [%# Create an array of products, indexed by the classification #%] |
| |
| [% nclass = 0 %] |
| [% FOREACH c = classification %] |
| prods[[% nclass FILTER js %]] = [ |
| [% sep = '' %] |
| [%- FOREACH item = user.get_selectable_products(c.id) -%] |
| [%- IF item.components.size -%] |
| [%- sep FILTER js %]'[% item.name FILTER js %]' |
| [%- sep = ',' -%] |
| [%- END -%] |
| [%- END -%] ]; |
| [% nclass = nclass+1 %] |
| [% END %] |
| |
| [%# Create three arrays of components, versions and target milestones, indexed |
| # numerically according to the product they refer to. #%] |
| |
| [% n = 0 %] |
| [% FOREACH p = product %] |
| [% NEXT IF NOT p.components.size %] |
| [% IF Param('useclassification') %] |
| prods['[% p.name FILTER js %]'] = [% n %] |
| [% END %] |
| cpts[[% n %]] = [ |
| [%- FOREACH item = p.components %]'[% item.name FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ]; |
| vers[[% n %]] = [ |
| [%- FOREACH item = p.versions -%]'[% item.name FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ]; |
| [% IF Param('usetargetmilestone') %] |
| tms[[% n %]] = [ |
| [%- FOREACH item = p.milestones %]'[% item.name FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ]; |
| [% END %] |
| [% n = n+1 %] |
| [% END %] |
| |
| /* |
| * doOnSelectProduct determines which selection should get updated |
| * |
| * - selectmode = 0 - init |
| * selectmode = 1 - classification selected |
| * selectmode = 2 - product selected |
| * |
| * globals: |
| * queryform - string holding the name of the selection form |
| */ |
| function doOnSelectProduct(selectmode) { |
| var f = document.forms[queryform]; |
| var milestone = (typeof(f.target_milestone) == "undefined" ? |
| null : f.target_milestone); |
| if (selectmode == 0) { |
| // If there is no classification selected, give us a chance to fill |
| // the select fields with values from the possibly selected product. |
| if (useclassification && f.classification.selectedIndex > -1) { |
| selectClassification(f.classification, f.product, f.component, f.version, milestone); |
| } else { |
| selectProduct(f.product, f.component, f.version, milestone, null); |
| } |
| } else if (selectmode == 1) { |
| selectClassification(f.classification, f.product, f.component, f.version, milestone); |
| } else { |
| selectProduct(f.product, f.component, f.version, milestone, null); |
| } |
| } |
| |
| // Hide the Advanced Fields by default, unless the user has a cookie |
| // that specifies otherwise. |
| // ▸ and ▾ are both utf8 escaped characters for right |
| // and down facing arrows respectivly. |
| TUI_alternates['history_query'] = '►'; |
| TUI_alternates['people_query'] = '►'; |
| TUI_alternates['information_query'] = '►'; |
| |
| TUI_hide_default('history_query'); |
| TUI_hide_default('people_query'); |
| TUI_hide_default('information_query'); |
| </script> |
| |
| [% query_types = [ |
| "allwordssubstr", |
| "anywordssubstr", |
| "substring", |
| "casesubstring", |
| "allwords", |
| "anywords", |
| "regexp", |
| "notregexp", |
| ] %] |
| |
| [%# If we resubmit to ourselves, we need to know if we are using a format. %] |
| [% thisformat = query_format != '' ? query_format : format %] |
| <input type="hidden" name="query_format" value="[% thisformat FILTER html %]"> |
| |
| [%# *** Summary *** %] |
| |
| <div class="search_field_row" id="summary_field"> |
| [% INCLUDE "search/field.html.tmpl" |
| field = bug_fields.short_desc |
| types = query_types |
| value = default.short_desc.0 |
| type_selected = default.short_desc_type.0 |
| accesskey = "s" |
| %] |
| <script type="text/javascript"> <!-- |
| document.forms[queryform].short_desc.focus(); |
| // --> |
| </script> |
| |
| [% IF button_name %] |
| <input type="submit" id="[% button_name FILTER css_class_quote %]_top" |
| value="[% button_name FILTER html %]"> |
| [% END %] |
| </div> |
| |
| [%# *** Classification Product Component *** %] |
| |
| [% Hook.process('before_selects_top') %] |
| [% IF Param('useclassification') %] |
| [% fake_classfication = { name => bug_fields.classification.name, |
| type => constants.FIELD_TYPE_SINGLE_SELECT } %] |
| [% INCLUDE "search/field.html.tmpl" |
| field => fake_classfication |
| accesskey => "c" |
| onchange => "doOnSelectProduct(1);" |
| value => default.classification |
| %] |
| [% END %] |
| |
| [% INCLUDE "search/field.html.tmpl" |
| field => bug_fields.product |
| accesskey => "p" |
| onchange => "doOnSelectProduct(2);" |
| value => default.product |
| %] |
| [% INCLUDE "search/field.html.tmpl" |
| field => bug_fields.component |
| accesskey => "m" |
| value => default.component |
| %] |
| [% INCLUDE "search/field.html.tmpl" |
| field => bug_fields.bug_status |
| accesskey => "a" |
| value => default.bug_status |
| %] |
| [% INCLUDE "search/field.html.tmpl" |
| field => bug_fields.resolution |
| accesskey => "r" |
| value => default.resolution |
| %] |
| |
| [% Hook.process('after_selects_top') %] |
| |
| <div id="detailed_information" class="bz_section_title"> |
| <div id="information_query_controller" class="arrow">▼</div> |
| <a href="javascript:TUI_toggle_class('information_query')"> |
| Detailed [% terms.Bug %] Information |
| </a> |
| <span class="section_help">Narrow results by the following fields: |
| [%+ field_descs.longdesc FILTER html %]s, [%+ field_descs.bug_file_loc FILTER html %], |
| [% IF Param('usestatuswhiteboard') %] [%+ field_descs.status_whiteboard FILTER html %], [%+ END %] |
| [% IF use_keywords %] [%+ field_descs.keywords FILTER html %], [%+ END %] |
| [% IF user.is_timetracker %] [%+ field_descs.deadline FILTER html %], [%+ END %] |
| [% terms.Bug %] Numbers, [%+ field_descs.version FILTER html %], |
| [% IF Param('usetargetmilestone') %] [%+ field_descs.target_milestone FILTER html %], [%+ END %] |
| [% field_descs.bug_severity FILTER html %], [%+ field_descs.priority FILTER html %], [%+ field_descs.rep_platform FILTER html %], |
| [%+ field_descs.op_sys FILTER html %] |
| </span> |
| </div> |
| [%# *** Comment URL Whiteboard Keywords *** %] |
| <div id="detailed_information_section" class="bz_search_section information_query"> |
| [% SET freetext_fields = [ |
| { field => bug_fields.longdesc, accesskey => 'c' }, |
| { field => bug_fields.bug_file_loc, accesskey => 'u' }, |
| { field => bug_fields.status_whiteboard, accesskey => 'w' }, |
| { field => bug_fields.keywords, accesskey => 'k', |
| qtypes => ['allwords', 'anywords', 'nowords', 'regexp', 'notregexp'] } |
| ] %] |
| [% Hook.process('before_freetext_fields') %] |
| |
| [%# loop through a bunch of free text fields and print out their text stuff %] |
| [% FOREACH field_container = freetext_fields %] |
| [% NEXT IF field_container.field.name == 'status_whiteboard' |
| AND NOT Param('usestatuswhiteboard') |
| %] |
| [% NEXT IF field_container.field.name == 'keywords' |
| AND NOT use_keywords |
| %] |
| <div class="search_field_row"> |
| [% type = field_container.field.name _ "_type" %] |
| [% INCLUDE "search/field.html.tmpl" |
| field => field_container.field |
| types => field_container.qtypes || query_types |
| accesskey => field_container.accesskey |
| value => default.${field_container.field.name}.0 |
| type_selected => default.$type.0 |
| %] |
| </div> |
| [% END %] |
| |
| [%# Deadline %] |
| [% IF user.is_timetracker %] |
| <div class="search_field_row"> |
| [% INCLUDE "search/field.html.tmpl" |
| field = bug_fields.deadline |
| accesskey = "l" |
| value = [ default.deadlinefrom.0, default.deadlineto.0 ] |
| %] |
| </div> |
| [% END %] |
| |
| <div class="search_field_row"> |
| <span class="field_label"><label for="bug_id">[% terms.Bugs %] numbered</label></span> |
| <div id="bug_id_container" > |
| <input type="text" name="bug_id" id="bug_id" |
| value="[% default.bug_id.0 FILTER html %]" size="20"> |
| <div class="field_help">(comma-separated list)</div> |
| </div> |
| should be |
| <select name="bug_id_type" id="bug_id_type"> |
| <option value="anyexact"[% " selected" IF default.bug_id_type.0 == "anyexact" %]>only included in</option> |
| <option value="nowords"[% " selected" IF default.bug_id_type.0 == "nowords" %]>excluded from</option> |
| </select> the results |
| </div> |
| |
| [% Hook.process('after_freetext_fields') %] |
| |
| [%# *** Status Resolution Severity Priority Hardware OS *** %] |
| <div> |
| [% Hook.process('before_selects_bottom') %] |
| [% fake_version_field = { name => bug_fields.version.name, |
| type => constants.FIELD_TYPE_SINGLE_SELECT }%] |
| [% INCLUDE "search/field.html.tmpl" |
| field => fake_version_field |
| value => default.version |
| %] |
| [% IF Param('usetargetmilestone') %] |
| [% fake_target_milestone_field = { name => bug_fields.target_milestone.name , |
| type => constants.FIELD_TYPE_SINGLE_SELECT } %] |
| [% INCLUDE "search/field.html.tmpl" |
| field => fake_target_milestone_field |
| value => default.target_milestone |
| %] |
| [% END %] |
| [% INCLUDE "search/field.html.tmpl" |
| field => bug_fields.bug_severity |
| accesskey=> "v" |
| value => default.bug_severity |
| %] |
| [% INCLUDE "search/field.html.tmpl" |
| field => bug_fields.priority |
| accesskey => "i" |
| value => default.priority |
| %] |
| [% INCLUDE "search/field.html.tmpl" |
| field => bug_fields.rep_platform |
| accesskey =>"h" |
| value => default.rep_platform |
| %] |
| [% INCLUDE "search/field.html.tmpl" |
| field => bug_fields.op_sys |
| accesskey =>"o" |
| value => default.op_sys |
| %] |
| [% Hook.process('after_selects_bottom') %] |
| </div> |
| </div> |
| [%# *** Email Numbering *** %] |
| <div class="bz_section_title" id="people_filter"> |
| <div id="people_query_controller" class="arrow">▼</div> |
| <a href="javascript:TUI_toggle_class('people_query')">Search By People</a> |
| <span>Narrow results to a role (i.e. [% field_descs.assigned_to FILTER html %], |
| [%+ field_descs.reporter FILTER html %], [% field_descs.commenter FILTER html %], |
| etc.) a person has on [% terms.abug %] |
| </span> |
| </div> |
| <div id="people_filter_section" class="bz_search_section people_query"> |
| [% FOREACH n = [1, 2, 3] %] |
| <div class="search_email_fields"> |
| Any of: |
| [% PROCESS role_types field = { count => n, name => "emailassigned_to", |
| label=> "the ${terms.Bug} ${field_descs.assigned_to}" } %] |
| [% PROCESS role_types field = { count => n, name => "emailreporter", |
| label=> "the ${field_descs.reporter}" } %] |
| [% IF Param('useqacontact') %] |
| [% PROCESS role_types field = { count => n, name => "emailqa_contact", |
| label=> "the ${field_descs.qa_contact}" } %] |
| [% END %] |
| [% PROCESS role_types field = { count => n, name => "emailcc", |
| label=> "a ${field_descs.cc} list member" } %] |
| [% PROCESS role_types field = { count => n, name => "emaillongdesc", |
| label=> " a ${field_descs.commenter}" } %] |
| <select name="emailtype[% n %]"> |
| [% FOREACH qv = [ |
| { name => "substring", description => "contains" }, |
| { name => "exact", description => "is" }, |
| { name => "notequals", description => "is not" }, |
| { name => "regexp", description => "matches regexp" }, |
| { name => "notregexp", description => "doesn't match regexp" } ] %] |
| <option value="[% qv.name %]" |
| [% " selected" IF default.emailtype.$n == qv.name %]>[% qv.description %]</option> |
| [% END %] |
| </select> |
| [% IF feature_enabled('jsonrpc') %] |
| <div id="email[% n %]_autocomplete"> |
| [% END %] |
| <input name="email[% n %]" class="email" id="email[% n %]" |
| value="[% default.email.$n FILTER html %]"> |
| [% IF feature_enabled('jsonrpc') %] |
| <div id="email[% n %]_autocomplete_container"></div> |
| </div> |
| <script type="text/javascript"> |
| YAHOO.bugzilla.userAutocomplete.init( "email[% n %]", |
| "email[% n %]_autocomplete_container"); |
| </script> |
| [% END %] |
| </div> |
| [% END %] |
| [% Hook.process('email_numbering_end') %] |
| </div> |
| [%# *** Bug Changes *** %] |
| <div class="bz_section_title" id="history_filter"> |
| <div id="history_query_controller" class="arrow">▼</div> |
| <a href="javascript:TUI_toggle_class('history_query')" >Search By Change History</a> |
| <span>Narrow results to how fields have changed during a specific time period</span> |
| </div> |
| <ul class="bug_changes bz_search_section history_query" id="history_filter_section" > |
| <li> |
| <label for="chfield">where ANY of the fields:</label> |
| [%# Create array, so we can sort it by description #%] |
| [% chfields = [] %] |
| [% FOREACH field = chfield %] |
| [% chfields.push({value => field, desc => (field_descs.$field || field) }) %] |
| [% END %] |
| <select name="chfield" id="chfield" multiple="multiple" size="4"> |
| [% FOREACH field = chfields.sort('desc') %] |
| <option value="[% field.value FILTER html %]" |
| [% " selected" IF default.chfield.contains(field.value) %]> |
| [% field.desc FILTER html %]</option> |
| [% END %] |
| </select> |
| </li> |
| <li> |
| <label for="chfieldvalue">[% search_descs.changedto FILTER html %]:</label> |
| <input name="chfieldvalue" id="chfieldvalue" |
| size="20" value="[% default.chfieldvalue.0 FILTER html %]"> |
| </li> |
| <li> |
| <label for="chfieldfrom">between:</label> |
| <input name="chfieldfrom" id="chfieldfrom" size="10" |
| value="[% default.chfieldfrom.0 FILTER html %]" onchange="updateCalendarFromField(this)"> |
| <button type="button" class="calendar_button" |
| id="button_calendar_chfieldfrom" |
| onclick="showCalendar('chfieldfrom')"><span>Calendar</span></button> |
| and |
| <div id="con_calendar_chfieldfrom"></div> |
| <input name="chfieldto" size="10" id="chfieldto" |
| value="[% default.chfieldto.0 || "Now" FILTER html %]" |
| onchange="updateCalendarFromField(this)"> |
| <button type="button" class="calendar_button" |
| id="button_calendar_chfieldto" |
| onclick="showCalendar('chfieldto')"><span>Calendar</span></button> |
| <div id="con_calendar_chfieldto"></div> |
| (YYYY-MM-DD or relative dates) |
| <script type="text/javascript"> |
| createCalendar('chfieldfrom'); |
| createCalendar('chfieldto'); |
| </script> |
| </li> |
| </ul> |
| |
| [%############################################################################%] |
| [%# Block for email role type use to select which email to search through #%] |
| [%############################################################################%] |
| [% BLOCK role_types %] |
| <div class="role_type"> |
| <input type="checkbox" name="[% field.name _ field.count FILTER html %]" |
| id="[% field.name _ field.count FILTER html %]" value="1" |
| [% " checked" IF default.${field.name}.${field.count} %]> |
| <label for="[% field.name _ field.count FILTER html%]"> |
| [% field.label FILTER html%] |
| </label> |
| </div> |
| [% END %] |