aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'template/en/custom/search')
-rw-r--r--template/en/custom/search/boolean-charts.html.tmpl205
-rw-r--r--template/en/custom/search/field.html.tmpl230
-rw-r--r--template/en/custom/search/form.html.tmpl376
-rw-r--r--template/en/custom/search/knob.html.tmpl86
-rw-r--r--template/en/custom/search/search-specific.html.tmpl89
-rw-r--r--template/en/custom/search/type-select.html.tmpl18
6 files changed, 1004 insertions, 0 deletions
diff --git a/template/en/custom/search/boolean-charts.html.tmpl b/template/en/custom/search/boolean-charts.html.tmpl
new file mode 100644
index 000000000..b4225f950
--- /dev/null
+++ b/template/en/custom/search/boolean-charts.html.tmpl
@@ -0,0 +1,205 @@
+[%# 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.
+ #%]
+
+[% types = [
+ "noop",
+ "equals",
+ "notequals",
+ "anyexact",
+ "substring",
+ "casesubstring",
+ "notsubstring",
+ "anywordssubstr",
+ "allwordssubstr",
+ "nowordssubstr",
+ "regexp",
+ "notregexp",
+ "lessthan",
+ "lessthaneq",
+ "greaterthan",
+ "greaterthaneq",
+ "anywords",
+ "allwords",
+ "nowords",
+ "changedbefore",
+ "changedafter",
+ "changedfrom",
+ "changedto",
+ "changedby",
+ "matches",
+ "notmatches",
+ "isempty",
+ "isnotempty",
+] %]
+
+<div class="panel panel-default">
+ <div class="panel-heading" id="CustomSearchHeading">
+ <h4 class="panel-title">
+ <a role="button" data-toggle="collapse" href="#CustomSearch" aria-expanded="true" aria-controls="CustomSearch">Custom Search
+ <small class="section_help">Didn't find what
+ you're looking for above? This area allows for ANDs, ORs,
+ and other more complex searches.
+ </small></a>
+ </h4>
+ </div>
+ <div id="CustomSearch" class="panel-collapse collapse" role="tabpanel" aria-labelledby="CustomSearchHeading">
+ <div class="panel-body">
+
+
+ [% SET indent_level = 0 %]
+ [% SET cond_num = 0 %]
+ [% FOREACH condition = default.custom_search %]
+ [% SET cond_num = loop.count - 1 %]
+ [% PROCESS one_condition with_buttons = 0 %]
+ [% END %]
+ [% PROCESS one_condition
+ with_buttons = 1
+ condition = { f => 'noop' }
+ cond_num = cond_num + 1 %]
+ <script type="text/javascript">
+ TUI_alternates['custom_search_query'] = '&#9658;';
+ TUI_hide_default('custom_search_query');
+ TUI_alternates['custom_search_advanced'] = "Show Advanced Features";
+ TUI_hide_default('custom_search_advanced');
+ </script>
+ <script type="text/javascript" src="[% 'js/custom-search.js' FILTER mtime %]"></script>
+ <script type="text/javascript">
+ redirect_html4_browsers();
+ [%# These are alternative labels for the AND and OR options in and_all_select %]
+ var cs_and_label = 'Match ALL of the following:';
+ var cs_or_label = 'Match ANY of the following:';
+ cs_reconfigure('custom_search_last_row');
+ </script>
+ <script type="text/javascript" src="[% 'js/history.js/native.history.js' FILTER mtime %]"></script>
+ </div>
+
+
+[% BLOCK one_condition %]
+ [%# Skip any conditions that don't have a field defined. %]
+ [% RETURN IF !condition.f %]
+
+ [% IF !top_level_any_shown %]
+ [% INCLUDE any_all_select
+ name = "j_top" selected = default.j_top.0
+ with_advanced_link = 1 %]
+ [% top_level_any_shown = 1 %]
+ [% END %]
+
+ [% IF condition.f == "CP" %]
+ [% indent_level = indent_level - 1 %]
+ [% END %]
+
+ <div class="custom_search_condition"
+ [% ' style="margin-left: ' _ (indent_level * 2) _ 'em"' IF indent_level %]
+ [% ' id="custom_search_last_row"' IF with_buttons %]>
+
+ [% IF previous_condition.f == "OP" %]
+ [% INCLUDE any_all_select
+ name = "j" _ (cond_num - 1)
+ selected = previous_condition.j %]
+ [% END %]
+
+ [% IF with_buttons %]
+ <button id="op_button" type="button" class="custom_search_advanced btn btn-default"
+ title="Start a new group of criteria, including this row"
+ onclick="custom_search_open_paren()">(</button>
+ [% END %]
+
+ [% UNLESS condition.f == "CP" %]
+ [%# This only gets hidden via custom_search_advanced if it isn't set. %]
+ <span id="custom_search_not_container_[% cond_num FILTER html %]"
+ class="custom_search_not_container
+ [%- ' custom_search_advanced' UNLESS condition.n %]"
+ title="Search for the opposite of the criteria here">
+ <input type="checkbox" id="n[% cond_num FILTER html %]"
+ class="custom_search_form_field"
+ name="n[% cond_num FILTER html %]" value="1"
+ onclick="custom_search_not_changed([% cond_num FILTER js %])"
+ [% ' checked="checked"' IF condition.n %]>
+ <label for="n[% cond_num FILTER html %]">Not</label>
+ </span>
+ [% END %]
+
+ [% IF condition.f == "OP" %]
+ <input type="hidden" name="f[% cond_num FILTER html %]"
+ id="f[% cond_num FILTER html %]" value="OP">
+ (
+ [% indent_level = indent_level + 1 %]
+ [% ELSIF condition.f == "CP" %]
+ <input type="hidden" name="f[% cond_num FILTER html %]"
+ id="f[% cond_num FILTER html %]" value="CP">
+ )
+ [% ELSE %]
+ <select name="f[% cond_num FILTER html %]" title="Field"
+ id="f[% cond_num FILTER html %]"
+ onchange="fix_query_string(this)"
+ class="custom_search_form_field form-control">
+ [%# Turn the array in to a hash with the name as the key %]
+ [%
+ field_hash = {};
+ FOREACH field IN fields;
+ field_hash.${field.name} = field;
+ END;
+ %]
+ [% FOREACH field_name = field_hash.keys.sort_by_field_name(field_descs) %]
+ [% field = field_hash.$field_name %]
+ <option value="[% field.name FILTER html %]"
+ [%~ ' selected="selected"' IF field.name == condition.f %]>
+ [% field_descs.${field.name} || field.description FILTER html %]
+ </option>
+ [% END %]
+ </select>
+
+ [% INCLUDE "search/type-select.html.tmpl"
+ name = "o${cond_num}", class = "custom_search_form_field"
+ types = types, selected = condition.o %]
+
+ <input name="v[% cond_num FILTER html %]" title="Value"
+ class="custom_search_form_field"
+ onchange="fix_query_string(this)"
+ value="[% condition.v FILTER html %]">
+ [% END %]
+
+ [% IF with_buttons %]
+ <button class="custom_search_add_button btn btn-default" type="button"
+ id="add_button" title="Add a new row"
+ onclick="custom_search_new_row()"><i class="fa fa-plus" aria-hidden="true"></i></button>
+ <span id="cp_container" [% ' class="bz_default_hidden"' IF !indent_level %]>
+ <button id="cp_button" type="button" class="btn btn-default"
+ title="End this group of criteria"
+ onclick="custom_search_close_paren()">)</button>
+ </span>
+ [% END %]
+ </div>
+
+ [% previous_condition = condition %]
+[% END %]
+
+[% BLOCK any_all_select %]
+ <div class="any_all_select">
+ <select name="[% name FILTER html %]" id="[% name FILTER html %]" class="form-control"
+ onchange="fix_query_string(this)">
+ <option value="AND">Match ALL of the following separately:</option>
+ <option value="OR" [% ' selected="selected"' IF selected == "OR" %]>
+ Match ANY of the following separately:</option>
+ <option value="AND_G" [% ' selected' IF selected == "AND_G" %]>
+ Match ALL of the following against the same field:</option>
+ </select>
+ [% IF with_advanced_link %]
+ <a id="custom_search_advanced_controller"
+ href="javascript:TUI_toggle_class('custom_search_advanced')">
+ Hide Advanced Features
+ </a>
+ [% END %]
+ </div>
+[% END %]
+
+
+</div>
+</div>
+</div> \ No newline at end of file
diff --git a/template/en/custom/search/field.html.tmpl b/template/en/custom/search/field.html.tmpl
new file mode 100644
index 000000000..0546e1e45
--- /dev/null
+++ b/template/en/custom/search/field.html.tmpl
@@ -0,0 +1,230 @@
+[%# 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.
+ #%]
+
+[% SWITCH field.type %]
+ [% CASE [ constants.FIELD_TYPE_FREETEXT,
+ constants.FIELD_TYPE_TEXTAREA,
+ constants.FIELD_TYPE_UNKNOWN ] %]
+ [%# INCLUDE "bug/field-label.html.tmpl"
+ # field = field
+ # class = "input-group-addon"
+ # tag_name = "span"
+ # editable = 1
+ #%]
+
+ <div class="col-sm-2 align-h-right align-v-center" style="padding-right: 0px;">
+ <a title="The bug summary is a short sentence which succinctly describes what the bug is about." style="color:#61538D;" class="field_help_link" href="page.cgi?id=fields.html#short_desc">[%- field_descs.${field.name} FILTER html %]:</a>
+ </div>
+
+ <div class="col-sm-10">
+ [% INCLUDE "search/type-select.html.tmpl"
+ name = field.name _ "_type",
+ types = types,
+ selected = type_selected
+ class = "selectwidthauto"
+ %]
+ <input name="[% field.name FILTER html %]"
+ id="[% field.name FILTER html %]" size="40" class="form-control selectwidthauto"
+ [% IF onchange %] onchange="[% onchange FILTER html %]"[% END %]
+ value="[% value FILTER html %]" [% 'autofocus' IF focus %]>
+ </div>
+
+ [% CASE constants.FIELD_TYPE_KEYWORDS %]
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = field
+ tag_name = "span"
+ editable = 1
+ %]
+ [% INCLUDE "search/type-select.html.tmpl"
+ name = field.name _ "_type",
+ types = types,
+ selected = type_selected
+ %]
+
+ <div id="[% field.name FILTER html %]_container">
+ <input name="[% field.name FILTER html %]"
+ id="[% field.name FILTER html %]" size="40"
+ [% IF onchange %] onchange="[% onchange FILTER html %]"[% END %]
+ value="[% value FILTER html %]" [% 'autofocus' IF focus %]>
+ <div id="[% field.name FILTER html %]_autocomplete"></div>
+ </div>
+ <script type="text/javascript">
+ if (typeof YAHOO.bugzilla.field_array === "undefined")
+ YAHOO.bugzilla.field_array = [];
+ YAHOO.bugzilla.field_array["[% field.name FILTER js %]"] = [
+ [%- FOREACH val = possible_values %]
+ [%-# %]"[% val FILTER js %]"
+ [%- "," IF NOT loop.last %][% END %]];
+ YAHOO.bugzilla.fieldAutocomplete.init('[% field.name FILTER js %]',
+ '[% field.name FILTER js %]_autocomplete');
+ </script>
+ [% CASE [constants.FIELD_TYPE_DATETIME, constants.FIELD_TYPE_DATE] %]
+ [%# INCLUDE "bug/field-label.html.tmpl"
+ # field = field
+ # tag_name = "span"
+ # editable = 1
+ #%]
+
+<div class="row equal">
+ <span class="col-sm-2 align-v-center align-h-right" style="padding-right: 0px;">
+ <a title="The bug summary is a short sentence which succinctly describes what the bug is about." style="color:#61538D;" class="field_help_link" href="page.cgi?id=fields.html#short_desc">[%- field_descs.${field.name} FILTER html %] from:</a>
+ </span>
+
+ <div class="col-sm-10">
+ <input name="[% field.name FILTER html %]from"
+ id="[% field.name FILTER html %]"
+ class="form-control selectwidthauto"
+ size="10" maxlength="10"
+ value="[% value.0 FILTER html %]"
+ onchange="updateCalendarFromField(this);[% onchange FILTER html %]" />
+ <button type="button" class="btn btn-default"
+ id="button_calendar_[% field.name FILTER html %]"
+ onclick="showCalendar('[% field.name FILTER js %]')">
+ <i class="fa fa-calendar" aria-hidden="true"></i>
+ </button>
+ <!-- class="align-v-center" -->
+ <span>to</span>
+
+ <input name="[% field.name FILTER html %]to"
+ id="[% field.name FILTER html %]to" size="10" maxlength="10"
+ class="form-control selectwidthauto"
+ value="[% value.1 FILTER html %]"
+ onchange="updateCalendarFromField(this);[% onchange FILTER html %]">
+
+ <button type="button" class="btn btn-default"
+ id="button_calendar_[% field.name FILTER html %]to"
+ onclick="showCalendar('[% field.name FILTER js %]to')">
+ <i class="fa fa-calendar" aria-hidden="true"></i>
+ </button>
+ <small>(YYYY-MM-DD or relative dates)</small>
+ </div>
+
+</div>
+
+ <span id="con_calendar_[% field.name FILTER html %]"></span>
+ <span id="con_calendar_[% field.name FILTER html %]to"></span>
+
+
+ <script type="text/javascript">
+ <!--
+ [%+ PROCESS "global/calendar.js.tmpl" id = field.name %]
+ [% PROCESS "global/calendar.js.tmpl" id = field.name _ 'to' %]
+ //--></script>
+ [% CASE [ constants.FIELD_TYPE_SINGLE_SELECT,
+ constants.FIELD_TYPE_MULTI_SELECT ] %]
+ <div id="container_[% field.name FILTER html %]" class="search_field_grid">
+ <div class="panel panel-default">
+ <div class="panel-heading">
+ <a
+ [% IF help_html.${field.name}.defined %]
+ title="[% help_html.${field.name} FILTER txt FILTER collapse FILTER html %]"
+ class="field_help_link"
+ [% END %]
+ [% IF desc_url %]
+ href="[% desc_url FILTER html %]"
+ [% ELSE %]
+ href="page.cgi?id=fields.html#[% field.name FILTER uri %]"
+ [% END %] style="color:#555;"
+ >
+ <b>[%- field_descs.${field.name} FILTER html %]:</b>
+ </a>
+ [%# INCLUDE "bug/field-label.html.tmpl"
+ # field = field
+ # editable = 1
+ # tag_name = "span"
+ #%]
+ </div>
+ <select name="[% field.name FILTER html%]" class="form-control"
+ id="[% field.name FILTER html %]"
+ [% IF onchange %] onchange="[% onchange FILTER html %]"[% END %]
+ multiple="multiple" size="7">
+ [% legal_values = ${field.name} %]
+ [% IF field.name == "component" %]
+ [% legal_values = ${"component_"} %]
+ [% END %]
+ [% FOREACH current_value = legal_values %]
+ [% SET v = current_value.name OR '---' -%]
+ [% SET display = display_value(field.name, current_value.name) %]
+ <option value="[% v FILTER html %]"
+ id="v[% current_value.id FILTER html %]_[% field.name FILTER html %]"
+ [% ' selected="selected"' IF value.contains( v ) %]>
+ [%~ display FILTER html ~%]
+ </option>
+ [% END %]
+ </select>
+ </div>
+ </div>
+
+ [% IF value_controllers.${field.name}.defined %]
+ <script type="text/javascript"><!--
+ [%+ FILTER collapse %]
+ [% FOREACH accessor = value_controllers.${field.name}.keys %]
+ [% PROCESS controller_js %]
+ [% END %]
+ [%~ END ~%]
+ // --></script>
+ [% END %]
+ [% IF duplicates.${field.name}.keys.size %]
+ [% SET field_dups = duplicates.${field.name} %]
+ [% SET dup_counts = duplicate_count.${field.name} %]
+ <script type="text/javascript">
+ [%+ FILTER collapse %]
+ bz_option_duplicates['[% field.name FILTER js %]'] = {
+ [% FOREACH dup = field_dups.keys %]
+ [% dup FILTER js %]:[% field_dups.$dup.id FILTER js %]
+ [%~ ',' UNLESS loop.last %]
+ [% END ~%]
+ };
+ bz_option_duplicate_count['[% field.name FILTER js %]'] = {
+ [% FOREACH dup_target = dup_counts.keys %]
+ [% dup_target FILTER js %]:[% dup_counts.$dup_target FILTER js %]
+ [%~ ',' UNLESS loop.last %]
+ [% END %]
+ };
+ [% END %]
+ </script>
+ [% END %]
+
+ [% END %]
+[%# END OF SWITCH %]
+
+[% BLOCK controller_js %]
+ [%# If there are selected values already, we need to fire the
+ # "change" event once the page has loaded, so we can set all
+ # the values in all the other <select>s properly.
+ #%]
+ YAHOO.util.Event.onDOMReady(function() {
+ var field = document.getElementById('[% field.name FILTER js %]');
+ if (field.selectedIndex != -1) bz_fireEvent(field, 'change');
+ });
+
+ [% SET sub_field = value_controllers.${field.name}.$accessor %]
+ [% SET prod_per_class = {} %]
+ [% IF field.name == "classification" %]
+ [% FOREACH p = product %]
+ [% prod_per_class.${p.classification_id}.${p.id} = 1 %]
+ [% END %]
+ [% END %]
+
+ [% FOREACH legal_value = legal_values %]
+ [% SET controlled_ids = [] %]
+ [% IF field.name == "classification" %]
+ [% controlled_ids = prod_per_class.${legal_value.id}.keys %]
+ [% ELSE %]
+ [% FOREACH sub_value = legal_value.$accessor %]
+ [% controlled_ids.push(sub_value.id) %]
+ [% END %]
+ [% END %]
+ [% NEXT IF !controlled_ids.size %]
+ showValueWhen('[% sub_field.name FILTER js %]',
+ [[% controlled_ids.join(',') FILTER js %]],
+ '[% field.name FILTER js %]',
+ [% legal_value.id FILTER js %],
+ true);
+ [% END %]
+[% END %]
diff --git a/template/en/custom/search/form.html.tmpl b/template/en/custom/search/form.html.tmpl
new file mode 100644
index 000000000..3208b06ce
--- /dev/null
+++ b/template/en/custom/search/form.html.tmpl
@@ -0,0 +1,376 @@
+[%# 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.
+ #%]
+
+[% PROCESS "global/field-descs.none.tmpl" %]
+
+<input type="hidden" id="no_redirect" name="no_redirect" value="0">
+<script type="text/javascript">
+ if (history && history.replaceState) {
+ var no_redirect = document.getElementById("no_redirect");
+ no_redirect.value = 1;
+ }
+
+// Hide the Advanced Fields by default, unless the user has a cookie
+// that specifies otherwise.
+// &#9656; and &#9662; are both utf8 escaped characters for right
+// and down facing arrows respectivly.
+TUI_alternates['history_query'] = '&#9658;';
+TUI_alternates['people_query'] = '&#9658;';
+TUI_alternates['information_query'] = '&#9658;';
+
+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="well" id="summary_field">
+ <div class="input-group">
+ [% 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"
+ focus = 1
+ %]
+
+ [% IF button_name %]
+ <span class="input-group-btn">
+ <input class="btn btn-default" type="submit" id="[% button_name FILTER css_class_quote %]_top"
+ value="[% button_name FILTER html %]">
+ </span>
+ [% END %]
+ </div>
+ </div>
+
+[%# *** Classification Product Component *** %]
+
+[% value_controllers = {
+ 'classification' => { 'products' => bug_fields.product },
+ 'product' => { 'components' => bug_fields.component,
+ 'versions' => bug_fields.version,
+ 'milestones' => bug_fields.target_milestone },
+} %]
+
+[% Hook.process('before_selects_top') %]
+[% IF Param('useclassification') %]
+ [% INCLUDE "search/field.html.tmpl"
+ field => bug_fields.classification
+ accesskey => "c"
+ value => default.classification
+ %]
+[% END %]
+
+[% INCLUDE "search/field.html.tmpl"
+ field => bug_fields.product
+ accesskey => "p"
+ 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 class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
+
+<div class="panel panel-default">
+ <div class="panel-heading" id="DetailedBugInformationHeading">
+ <h4 class="panel-title">
+ <a role="button" data-toggle="collapse" href="#DetailedBugInformation" aria-expanded="true" aria-controls="DetailedBugInformation">
+ Detailed [% terms.Bug %] Information
+
+ <small 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 Param('timetrackinggroup') %] [%+ 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 %]
+ </small></a>
+ </h4>
+ </div>
+ <div id="DetailedBugInformation" class="panel-collapse collapse" role="tabpanel" aria-labelledby="DetailedBugInformationHeading">
+ <div class="panel-body">
+
+
+
+[%# *** Comment URL Whiteboard Keywords *** %]
+ [% 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 row equal">
+ [% type = field_container.field.name _ "_type" %]
+ [% possible_values = field_container.field.name == 'keywords' ? all_keywords : [] %]
+ [% 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 %]
+
+ [% IF Param('timetrackinggroup') %]
+ <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 row equal">
+ <div class="col-sm-2 align-v-center align-h-right" style="padding-right: 0px;">
+ <a title="" style="color:#61538D;" class="">[%- field_descs.${field.name} FILTER html %] [% terms.Bugs %] numbered:</a>
+ </div>
+ <div class="col-sm-10">
+ <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>
+ <span class="field_label field_label_sup">
+ should be
+ <select name="bug_id_type" id="bug_id_type" class="form-control selectwidthauto">
+ <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
+ </span>
+ </div>
+ </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>
+</div>
+</div>
+[%# *** Email Numbering *** %]
+<div class="panel panel-default">
+ <div class="panel-heading" id="SearchByPeopleHeading">
+ <h4 class="panel-title">
+ <a role="button" data-toggle="collapse" href="#SearchByPeople" aria-expanded="true" aria-controls="SearchByPeople">Search By People
+ <small>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 %]
+ </small></a>
+ </h4>
+ </div>
+ <div id="SearchByPeople" class="panel-collapse collapse" role="tabpanel" aria-labelledby="SearchByPeopleHeading">
+ <div class="panel-body">
+ [% 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 %]" class="form-control">
+ [% FOREACH qv = [
+ { name => "substring", description => "contains" },
+ { name => "notsubstring", description => "doesn't contain" },
+ { name => "equals", 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') && Param('ajax_user_autocompletion') %]
+ <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') && Param('ajax_user_autocompletion') %]
+ <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>
+ </div>
+ </div>
+[%# *** Bug Changes *** %]
+<div class="panel panel-default">
+<div class="panel-heading" id="ChangeHistoryHeading">
+ <h4 class="panel-title">
+ <a role="button" data-toggle="collapse" href="#ChangeHistory" aria-expanded="true" aria-controls="ChangeHistory">Search By Change History
+ <small>Narrow results to how fields have changed during a specific time period
+
+ </small></a>
+</h4>
+ </div>
+<div id="ChangeHistory" class="panel-collapse collapse" role="tabpanel" aria-labelledby="ChangeHistoryHeading">
+<div class="panel-body">
+
+
+<ul class="bug_changes">
+ <li style="margin-right: 10px;">
+ <label style="font-weight: normal" 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 style="font-weight: normal" for="chfieldvalue">[% search_descs.changedto FILTER html %]:</label>
+ <input name="chfieldvalue" id="chfieldvalue"
+ size="20" value="[% default.chfieldvalue.0 FILTER html %]">
+ </li>
+ <li>
+ <label style="font-weight: normal" 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>
+ <small>and</small>
+ <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><br/>
+ <small>(YYYY-MM-DD or relative dates)</small>
+ <script type="text/javascript">
+ <!--
+ [%+ PROCESS "global/calendar.js.tmpl" id = 'chfieldfrom' %]
+ [% PROCESS "global/calendar.js.tmpl" id = 'chfieldto' %]
+ //--></script>
+ </li>
+</ul>
+
+</div>
+</div>
+</div>
+
+
+[%############################################################################%]
+[%# 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 style="font-weight: normal;" for="[% field.name _ field.count FILTER html%]">
+ [% field.label FILTER html%]
+ </label>
+ </div>
+[% END %]
diff --git a/template/en/custom/search/knob.html.tmpl b/template/en/custom/search/knob.html.tmpl
new file mode 100644
index 000000000..90b7181bb
--- /dev/null
+++ b/template/en/custom/search/knob.html.tmpl
@@ -0,0 +1,86 @@
+[%# 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.
+ #%]
+
+[%# INTERFACE:
+ # (incomplete!)
+ # ...
+ # known_name: string. Possibly known stored name for the query being
+ # edited. This value is just passed through in a
+ # hidden field.
+ #%]
+
+[%# This is not necessary for English templates, but useful for localizers. %]
+[% ordersdesc = {
+ "Reuse same sort as last time" => "Reuse same sort as last time",
+ "Bug Number" => "$terms.Bug Number",
+ "Importance" => "Importance",
+ "Assignee" => "Assignee",
+ "Last Changed" => "Last Changed" } %]
+
+<input type="hidden" name="cmdtype" value="doit">
+[% IF user.id %]
+ <input type="hidden" name="token" value="[% issue_hash_token(['searchknob']) FILTER html %]">
+[% END %]
+
+<p style="margin-top:20px;">
+ <div class="input-group">
+ <span class="input-group-addon" id="sizing-addon2">Sort results by</span>
+ <select name="order" id="order" class="form-control selectwidthauto">
+ [% FOREACH order = orders %]
+ <option value="[% order FILTER html %]"
+ [% " selected" IF default.order.0 == order %]>
+ [% ordersdesc.$order FILTER html %]</option>
+ [% END %]
+ </select>
+ </div>
+</p>
+
+ [% IF user.id %]
+
+ <p>
+ <a data-toggle="collapse" href="#rememberSearch" aria-expanded="false" aria-controls="rememberSearch">
+ Remember as default search options
+ </a>
+ <div class="collapse" id="rememberSearch">
+ <div class="input-group">
+ <span class="input-group-addon">
+ <input type="checkbox" id="remasdefault"
+ name="remtype" value="asdefault">
+ </span>
+ <input type="text" class="form-control" style="width:370px;" value="and remember these as my default search options" disabled />
+ </div><!-- /input-group -->
+ </div>
+ </p>
+ [% END %]
+
+ [% IF userdefaultquery %]
+ <p>
+ <a href="query.cgi?nukedefaultquery=1&amp;token=
+ [%- issue_hash_token(['nukedefaultquery']) FILTER uri %]">
+ Set my default search back to the system default</a>.
+ </p>
+ [% END %]
+
+
+<p>
+ <input class="btn btn-primary" type="submit" id="[% button_name FILTER html %]"
+ value="[% button_name FILTER html %]">
+ [% IF known_name %]
+ [%# We store known_name in case the user adds a boolean chart. %]
+ <input type="hidden" name="known_name" value="[% known_name FILTER html %]">
+
+ [%# The name of the existing query will be passed to buglist.cgi. %]
+ <input type="hidden" name="query_based_on" value="[% known_name FILTER html %]">
+ [% END %]
+ [%# Preserve any custom column list that might be set. %]
+ [% IF columnlist %]
+ <input type="hidden" name="columnlist" value="[% columnlist FILTER html %]">
+ [% END %]
+</p>
+
+
diff --git a/template/en/custom/search/search-specific.html.tmpl b/template/en/custom/search/search-specific.html.tmpl
new file mode 100644
index 000000000..e2e99e40b
--- /dev/null
+++ b/template/en/custom/search/search-specific.html.tmpl
@@ -0,0 +1,89 @@
+[%# 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.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Simple Search"
+ style_urls = ['skins/standard/buglist.css']
+ doc_section = "using/finding.html"
+%]
+
+[% WRAPPER search/tabs.html.tmpl %]
+
+<p>
+Find a specific [% terms.bug %] by entering words that describe it.
+Bugzilla will search [% terms.bug %] descriptions and comments
+for those words and return a list of matching [% terms.bugs %] sorted
+by relevance.
+</p>
+
+<p>
+For example, if the [% terms.bug %] you are looking for is a browser crash when you go to a secure web site with an embedded Flash animation, you might search
+for "crash secure SSL flash".
+</p>
+
+<form name="queryform" method="get" action="buglist.cgi">
+<input type="hidden" name="query_format" value="specific">
+<input type="hidden" name="order" value="Importance">
+<input type="hidden" id="no_redirect" name="no_redirect" value="0">
+<script type="text/javascript">
+ if (history && history.replaceState) {
+ var no_redirect = document.getElementById("no_redirect");
+ no_redirect.value = 1;
+ }
+</script>
+
+ <div class="row equal" style="margin-bottom: 10px;">
+ <div class="col-sm-1 align-v-center align-h-right" style="padding-right:0px;">
+ Status:
+ </div>
+ <div class="col-sm-11">
+ <select name="bug_status" id="bug_status" class="form-control selectwidthauto">
+ [% statuses = [ { name = 'open', label = "Open" },
+ { name = 'closed', label = "Closed" },
+ { name = 'all', label = "All" } ] %]
+ [% FOREACH status = statuses %]
+ <option value="__[% status.name %]__" [% " selected" IF default.bug_status.0 == "__${status.name}__" %]>
+ [% status.label FILTER html %]
+ </option>
+ [% END %]
+ </select>
+ </div>
+ </div>
+
+ <div class="row equal" style="margin-bottom: 10px;">
+ [% INCLUDE "global/product-select.html.tmpl"
+ id => "product"
+ name => "product"
+ add => "All"
+ classes => "selectwidthauto"
+ %]
+ </div>
+
+ <div class="row equal" style="margin-bottom: 10px;">
+ <div class="col-sm-1 align-v-center align-h-right" style="padding-right:0px;">
+ Words:
+ </div>
+ <div class="col-sm-11">
+ <input class="form-control selectwidthauto" name="content" size="40" id="content" autofocus
+ value="[% default.content.0 FILTER html %]"
+ [%- " required" UNLESS Param('search_allow_no_criteria') %]>
+ </div>
+ </div>
+
+ <div class="row equal" style="margin-bottom: 10px;">
+ <div class="col-sm-1 align-v-center align-h-right" style="padding-right:0px;">
+ </div>
+ <div class="col-sm-11">
+ <input class="btn btn-primary btn-sm" type="submit" id="search" value="Search">
+ </div>
+ </div>
+
+
+[% END %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/custom/search/type-select.html.tmpl b/template/en/custom/search/type-select.html.tmpl
new file mode 100644
index 000000000..4757fe947
--- /dev/null
+++ b/template/en/custom/search/type-select.html.tmpl
@@ -0,0 +1,18 @@
+[%# 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.
+ #%]
+
+[% PROCESS "global/field-descs.none.tmpl" %]
+
+<select name="[% name FILTER html %]" title="Search type"
+ class="[% class FILTER css_class_quote %] form-control">
+ [% FOREACH type = types %]
+ <option value="[% type FILTER html %]"
+ [%- ' selected="selected"' IF type == selected %]>
+ [%- search_descs.$type FILTER html %]</option>
+ [% END %]
+</select>