aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Bugzilla/Constants.pm2
-rw-r--r--extensions/Gentoo/template/en/default/hook/bug/create/create-after_cc_field.html.tmpl59
-rw-r--r--extensions/Gentoo/template/en/default/hook/bug/edit-after_cc_field.html.tmpl4
-rw-r--r--extensions/Gentoo/template/en/default/hook/global/header-additional_header.html.tmpl9
-rw-r--r--extensions/Gentoo/template/en/default/hook/global/header-after_body_start.html.tmpl85
-rw-r--r--extensions/Gentoo/template/en/default/hook/index-intro.html.tmpl7
-rw-r--r--extensions/InlineHistory/web/inline-history.js5
-rw-r--r--extensions/Voting/template/en/default/hook/search/form-after_freetext_fields.html.tmpl14
-rw-r--r--js/comments.js11
-rw-r--r--js/global.js2
-rw-r--r--skins/contrib/Gentoo/global.css265
-rw-r--r--skins/contrib/Gentoo/select-icon.svg1
-rw-r--r--skins/contrib/Gentoo/sort-down.pngbin0 -> 140 bytes
-rw-r--r--skins/standard/bug.css23
-rw-r--r--skins/standard/global.css15
-rw-r--r--skins/standard/index/file-a-bug.png.bakbin0 -> 6395 bytes
-rw-r--r--skins/standard/index/search.pngbin7912 -> 1319 bytes
-rw-r--r--skins/standard/index/search.svg1
-rw-r--r--template/en/custom/account/auth/login-small.html.tmpl40
-rw-r--r--template/en/custom/account/auth/login.html.tmpl167
-rw-r--r--template/en/custom/account/create.html.tmpl101
-rw-r--r--template/en/custom/account/prefs/prefs.html.tmpl112
-rw-r--r--template/en/custom/account/prefs/settings.html.tmpl68
-rw-r--r--template/en/custom/admin/custom_fields/edit.html.tmpl56
-rw-r--r--template/en/custom/admin/fieldvalues/create.html.tmpl93
-rw-r--r--template/en/custom/admin/fieldvalues/edit.html.tmpl103
-rw-r--r--template/en/custom/admin/flag-type/confirm-delete.html.tmpl40
-rw-r--r--template/en/custom/admin/flag-type/edit.html.tmpl262
-rw-r--r--template/en/custom/admin/flag-type/list.html.tmpl154
-rw-r--r--template/en/custom/admin/params/common.html.tmpl126
-rw-r--r--template/en/custom/admin/params/editparams.html.tmpl92
-rw-r--r--template/en/custom/admin/products/confirm-delete.html.tmpl241
-rw-r--r--template/en/custom/admin/products/create.html.tmpl75
-rw-r--r--template/en/custom/admin/products/edit.html.tmpl141
-rw-r--r--template/en/custom/admin/settings/edit.html.tmpl80
-rw-r--r--template/en/custom/admin/table.html.tmpl160
-rw-r--r--template/en/custom/admin/users/create.html.tmpl50
-rw-r--r--template/en/custom/admin/users/edit.html.tmpl176
-rw-r--r--template/en/custom/admin/users/search.html.tmpl83
-rw-r--r--template/en/custom/attachment/list.html.tmpl167
-rw-r--r--template/en/custom/bug/comment.html.tmpl38
-rw-r--r--template/en/custom/bug/comments.html.tmpl262
-rw-r--r--template/en/custom/bug/create/create-guided.html.tmpl621
-rw-r--r--template/en/custom/bug/create/create.html.tmpl831
-rw-r--r--template/en/custom/bug/create/user-message.html.tmpl24
-rw-r--r--template/en/custom/bug/edit.html.tmpl1612
-rw-r--r--template/en/custom/bug/field.html.tmpl290
-rw-r--r--template/en/custom/bug/navigate.html.tmpl84
-rw-r--r--template/en/custom/bug/show.html.tmpl43
-rw-r--r--template/en/custom/global/choose-product.html.tmpl246
-rw-r--r--template/en/custom/global/common-links.html.tmpl153
-rw-r--r--template/en/custom/global/footer.html.tmpl121
-rw-r--r--template/en/custom/global/header.html.tmpl278
-rw-r--r--template/en/custom/global/product-select.html.tmpl98
-rw-r--r--template/en/custom/global/select-menu.html.tmpl52
-rw-r--r--template/en/custom/global/tabs.html.tmpl50
-rw-r--r--template/en/custom/global/textarea.html.tmpl58
-rw-r--r--template/en/custom/global/useful-links.html.tmpl74
-rw-r--r--template/en/custom/index.html.tmpl197
-rw-r--r--template/en/custom/list/list.html.tmpl379
-rw-r--r--template/en/custom/list/table.html.tmpl267
-rw-r--r--template/en/custom/reports/components.html.tmpl150
-rw-r--r--template/en/custom/reports/duplicates-simple.html.tmpl27
-rw-r--r--template/en/custom/reports/duplicates-table.html.tmpl112
-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
-rw-r--r--template/en/custom/whine/schedule.html.tmpl412
71 files changed, 10467 insertions, 106 deletions
diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm
index a6516774b..4e0141550 100644
--- a/Bugzilla/Constants.pm
+++ b/Bugzilla/Constants.pm
@@ -306,7 +306,7 @@ use constant DEFAULT_MILESTONE => '---';
use constant SAVE_NUM_SEARCHES => 10;
# The column width for comment textareas and comments in bugmails.
-use constant COMMENT_COLS => 80;
+use constant COMMENT_COLS => 60;
# Used in _check_comment(). Gives the max length allowed for a comment.
use constant MAX_COMMENT_LENGTH => 16384;
diff --git a/extensions/Gentoo/template/en/default/hook/bug/create/create-after_cc_field.html.tmpl b/extensions/Gentoo/template/en/default/hook/bug/create/create-after_cc_field.html.tmpl
index eb625e6bf..491ac5e29 100644
--- a/extensions/Gentoo/template/en/default/hook/bug/create/create-after_cc_field.html.tmpl
+++ b/extensions/Gentoo/template/en/default/hook/bug/create/create-after_cc_field.html.tmpl
@@ -1,32 +1,27 @@
-<tr>
- <td>
- <button onclick="add_arches_create()" type="button">Add arches:</button>
- </td>
- <td>
- <select name="addarches" multiple size="5" class="arch-selector">
- <option value="alpha@gentoo.org">ALPHA</option>
- <option value="amd64@gentoo.org">AMD64</option>
- <option value="arm@gentoo.org">ARM</option>
- <option value="arm64@gentoo.org">ARM64</option>
- <option value="ia64@gentoo.org">IA64</option>
- <option value="ppc@gentoo.org">PPC</option>
- <option value="ppc64@gentoo.org">PPC64</option>
- <option value="x86@gentoo.org">X86</option>
- <optgroup label="exp profiles">
- <option value="hppa@gentoo.org">HPPA</option>
- <option value="m68k@gentoo.org">M68K</option>
- <option value="s390@gentoo.org">S390</option>
- <option value="sh@gentoo.org">SH</option>
- <option value="sparc@gentoo.org">SPARC</option>
- </optgroup>
- <optgroup label="pure ~arch">
- <option value="mips@gentoo.org">MIPS</option>
- <option value="riscv@gentoo">RISC-V</option>
- </optgroup>
- <optgroup label="other teams">
- <option value="prefix@gentoo.org">Prefix</option>
- <option value="release@gentoo.org">Release</option>
- </optgroup>
- </select>
- </td>
-</div>
+<select name="addarches" multiple size="5" class="arch-selector form-control">
+ <option value="alpha@gentoo.org">ALPHA</option>
+ <option value="amd64@gentoo.org">AMD64</option>
+ <option value="arm@gentoo.org">ARM</option>
+ <option value="arm64@gentoo.org">ARM64</option>
+ <option value="ia64@gentoo.org">IA64</option>
+ <option value="ppc@gentoo.org">PPC</option>
+ <option value="ppc64@gentoo.org">PPC64</option>
+ <option value="x86@gentoo.org">X86</option>
+ <optgroup label="exp profiles">
+ <option value="hppa@gentoo.org">HPPA</option>
+ <option value="m68k@gentoo.org">M68K</option>
+ <option value="s390@gentoo.org">S390</option>
+ <option value="sh@gentoo.org">SH</option>
+ <option value="sparc@gentoo.org">SPARC</option>
+ </optgroup>
+ <optgroup label="pure ~arch">
+ <option value="mips@gentoo.org">MIPS</option>
+ <option value="riscv@gentoo">RISC-V</option>
+ </optgroup>
+ <optgroup label="other teams">
+ <option value="prefix@gentoo.org">Prefix</option>
+ <option value="release@gentoo.org">Release</option>
+ </optgroup>
+</select>
+<br>
+<button class="btn btn-primary" onclick="add_arches_create()" type="button">Add arches</button>
diff --git a/extensions/Gentoo/template/en/default/hook/bug/edit-after_cc_field.html.tmpl b/extensions/Gentoo/template/en/default/hook/bug/edit-after_cc_field.html.tmpl
index 71253cab4..83172fc10 100644
--- a/extensions/Gentoo/template/en/default/hook/bug/edit-after_cc_field.html.tmpl
+++ b/extensions/Gentoo/template/en/default/hook/bug/edit-after_cc_field.html.tmpl
@@ -1,7 +1,7 @@
<br />
<div>
- <button onclick="add_arches_edit()" type="button">Add arches:</button>
- <select name="addarches" multiple size="5" class="arch-selector">
+ <button class="btn btn-default" onclick="add_arches_edit()" type="button">Add arches:</button>
+ <select name="addarches" multiple size="5" class="arch-selector form-control">
<option value="alpha@gentoo.org">ALPHA</option>
<option value="amd64@gentoo.org">AMD64</option>
<option value="arm@gentoo.org">ARM</option>
diff --git a/extensions/Gentoo/template/en/default/hook/global/header-additional_header.html.tmpl b/extensions/Gentoo/template/en/default/hook/global/header-additional_header.html.tmpl
index a1a946dc7..6340c439d 100644
--- a/extensions/Gentoo/template/en/default/hook/global/header-additional_header.html.tmpl
+++ b/extensions/Gentoo/template/en/default/hook/global/header-additional_header.html.tmpl
@@ -1 +1,8 @@
-<script language="JavaScript" src="extensions/Gentoo/web/gentoo.js"></script> \ No newline at end of file
+<script language="JavaScript" src="extensions/Gentoo/web/gentoo.js"></script>
+
+<link href="https://assets.gentoo.org/tyrian/bootstrap.min.css" rel="stylesheet" media="screen">
+<link href="https://assets.gentoo.org/tyrian/tyrian.min.css" rel="stylesheet" media="screen">
+
+<script language="JavaScript" src="https://assets.gentoo.org/tyrian/jquery.min.js"></script>
+<script language="JavaScript" src="https://assets.gentoo.org/tyrian/bootstrap.min.js"></script>
+<!-- <script language="JavaScript" src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/js/all.js"></script> -->
diff --git a/extensions/Gentoo/template/en/default/hook/global/header-after_body_start.html.tmpl b/extensions/Gentoo/template/en/default/hook/global/header-after_body_start.html.tmpl
index d059fef48..32278a02f 100644
--- a/extensions/Gentoo/template/en/default/hook/global/header-after_body_start.html.tmpl
+++ b/extensions/Gentoo/template/en/default/hook/global/header-after_body_start.html.tmpl
@@ -1,18 +1,69 @@
-<div id="gentoo-bar">
- <a href="/" title="Go to the Gentoo Bugzilla homepage" class="home-link">
- <img src="extensions/Gentoo/web/gentoo_org.png" alt="Gentoo Websites Logo" />
- </a>
+ <div class="site-title">
+ <div class="container">
+ <div class="row">
+ <div class="site-title-buttons">
+ <div class="btn-group btn-group-sm">
+ <a href="https://get.gentoo.org/" role="button" class="btn get-gentoo"><span class="fa fa-fw fa-download"></span> <strong>Get Gentoo!</strong></a>
+ <div class="btn-group btn-group-sm">
+ <a class="btn gentoo-org-sites dropdown-toggle" data-toggle="dropdown" data-target="#" href="#">
+ <span class="fa fa-fw fa-map-o"></span> <span class="hidden-xs">gentoo.org sites</span> <span class="caret"></span>
+ </a>
+ <ul class="dropdown-menu dropdown-menu-right">
+ <li><a href="https://www.gentoo.org/" title="Main Gentoo website"><span class="fa fa-home fa-fw"></span> gentoo.org</a></li>
+ <li><a href="https://wiki.gentoo.org/" title="Find and contribute documentation"><span class="fa fa-file-text-o fa-fw"></span> Wiki</a></li>
+ <li><a href="https://bugs.gentoo.org/" title="Report issues and find common issues"><span class="fa fa-bug fa-fw"></span> Bugs</a></li>
+ <li><a href="https://forums.gentoo.org/" title="Discuss with the community"><span class="fa fa-comments-o fa-fw"></span> Forums</a></li>
+ <li><a href="https://packages.gentoo.org/" title="Find software for your Gentoo"><span class="fa fa-hdd-o fa-fw"></span> Packages</a></li>
+ <li class="divider"></li>
+ <li><a href="https://planet.gentoo.org/" title="Find out what's going on in the developer community"><span class="fa fa-rss fa-fw"></span> Planet</a></li>
+ <li><a href="https://archives.gentoo.org/" title="Read up on past discussions"><span class="fa fa-archive fa-fw"></span> Archives</a></li>
+ <li><a href="https://gitweb.gentoo.org/" title="Browse our source code in Gitweb"><span class="fa fa-code fa-fw"></span> Gitweb</a></li>
+ <li><a href="https://sources.gentoo.org/" title="Browse our source code in CVS"><span class="fa fa-code fa-fw"></span> CVS sources</a></li>
+ <li class="divider"></li>
+ <li><a href="https://infra-status.gentoo.org/" title="Get updates on the services provided by Gentoo"><span class="fa fa-server fa-fw"></span> Infra status</a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ <div class="logo">
+ <a href="/" title="Back to the homepage" class="site-logo">
+ <object data="https://assets.gentoo.org/tyrian/site-logo.svg" type="image/svg+xml">
+ <img src="https://assets.gentoo.org/tyrian/site-logo.png" alt="Gentoo Linux logo">
+ </object>
+ </a>
+ <span class="site-label">Bugs</span>
+ </div>
+ </div>
+ </div>
+ </div>
- <div>
- Go to:
- <a href="https://www.gentoo.org/">Gentoo Home</a>
- <a href="https://www.gentoo.org/support/documentation/">Documentation</a>
- <a href="https://forums.gentoo.org/">Forums</a>
- <a href="https://www.gentoo.org/get-involved/mailing-lists/">Lists</a>
- <a href="/" class="active">Bugs</a>
- <a href="https://planet.gentoo.org/">Planet</a>
- <a href="https://www.gentoo.org/inside-gentoo/stores/">Store</a>
- <a href="https://wiki.gentoo.org/">Wiki</a>
- <strong><a href="https://www.gentoo.org/downloads/">Get Gentoo!</a></strong>
- </div>
-</div>
+ <!--
+ <nav class="tyrian-navbar" role="navigation">
+ <div class="container">
+ <div class="row">
+ <div class="navbar-header">
+ <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-main-collapse">
+ <span class="sr-only">Toggle navigation</span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ </button>
+ </div>
+ <div class="collapse navbar-collapse navbar-main-collapse">
+ <ul class="nav navbar-nav">
+ <li class="active"><a href="/">Home</a></li>
+<li class=""><a href="/get-started/">Get started</a></li>
+<li class=""><a href="/downloads/">Downloads</a></li>
+<li class=""><a href="/inside-gentoo/">Inside Gentoo</a></li>
+<li class=""><a href="/support/">Support</a></li>
+<li class=""><a href="/get-involved/">Get involved</a></li>
+
+ </ul>
+ <ul class="nav navbar-nav navbar-right">
+ <li class=""><a href="/donate/"><span class="fa fa-heart" style="color:#d9534f;"></span> Donate</a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ </nav>
+--> \ No newline at end of file
diff --git a/extensions/Gentoo/template/en/default/hook/index-intro.html.tmpl b/extensions/Gentoo/template/en/default/hook/index-intro.html.tmpl
index 55eead5f5..b384f4e55 100644
--- a/extensions/Gentoo/template/en/default/hook/index-intro.html.tmpl
+++ b/extensions/Gentoo/template/en/default/hook/index-intro.html.tmpl
@@ -1,4 +1,3 @@
-<p>Welcome to the Gentoo Bug tracking system.</p>
-<p>Before reporting bugs, please ensure that you read the <a href="https://www.gentoo.org/doc/en/bugzilla-howto.xml">Gentoo Bug Reporting Guide</a>.</p>
-<p>Do you run a spider, bot or some automated process against the Gentoo bugzilla? Please read the <a href="/bots.html">Bot Policy</a>.</p>
-<hr width="100%" />
+Before reporting bugs, please ensure that you read the <a href="https://www.gentoo.org/doc/en/bugzilla-howto.xml">Gentoo Bug Reporting Guide</a>.<br>
+Do you run a spider, bot or some automated process against the Gentoo bugzilla? Please read the <a href="/bots.html">Bot Policy</a>.
+<!-- <hr width="100%" /> -->
diff --git a/extensions/InlineHistory/web/inline-history.js b/extensions/InlineHistory/web/inline-history.js
index c59c2932c..55af3bd36 100644
--- a/extensions/InlineHistory/web/inline-history.js
+++ b/extensions/InlineHistory/web/inline-history.js
@@ -20,7 +20,7 @@ var inline_history = {
var comments = Dom.getElementsByClassName("bz_comment", 'div', 'comments');
for (var i = 1, il = comments.length; i < il; i++) {
// remove 'has been marked as a duplicate of this bug' comments
- var textDiv = Dom.getElementsByClassName('bz_comment_text', 'pre', comments[i]);
+ var textDiv = Dom.getElementsByClassName('panel-body', 'div', comments[i]);
if (textDiv) {
var match = reDuplicate.exec(textDiv[0].textContent || textDiv[0].innerText);
if (match) {
@@ -114,6 +114,7 @@ var inline_history = {
commentHead.parentNode.appendChild(currentDiv);
currentDiv.innerHTML = item[2];
Dom.addClass(currentDiv, 'ih_inlinehistory');
+ Dom.addClass(currentDiv, 'panel-footer');
Dom.addClass(currentDiv, containerClass);
if (item[6])
this.setFlagChangeID(item, commentHead.parentNode.id);
@@ -148,7 +149,7 @@ var inline_history = {
} else {
currentDiv.insertBefore(itemContainer, currentDiv.firstChild);
}
- currentDiv.setAttribute("class", "bz_comment ih_history");
+ currentDiv.setAttribute("class", "bz_comment ih_history panel panel-default");
if (item[6])
this.setFlagChangeID(item, 'h' + i);
}
diff --git a/extensions/Voting/template/en/default/hook/search/form-after_freetext_fields.html.tmpl b/extensions/Voting/template/en/default/hook/search/form-after_freetext_fields.html.tmpl
index cb549e3e4..a37777548 100644
--- a/extensions/Voting/template/en/default/hook/search/form-after_freetext_fields.html.tmpl
+++ b/extensions/Voting/template/en/default/hook/search/form-after_freetext_fields.html.tmpl
@@ -6,11 +6,13 @@
# defined by the Mozilla Public License, v. 2.0.
#%]
-<div class="search_field_row">
- <span class="field_label ">
- <label for="votes">Only [% terms.bugs %] with at least</label>:
- </span>
+<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="">Only [% terms.bugs %] with at least:</a>
+ </div>
+ <div class="col-sm-10">
<input name="votes" id="votes" size="3"
- value="[% default.votes.0 FILTER html %]"> votes
- <input type="hidden" name="votes_type" value="greaterthaneq">
+ value="[% default.votes.0 FILTER html %]"/> votes
+ <input type="hidden" name="votes_type" value="greaterthaneq"/>
+ </div>
</div>
diff --git a/js/comments.js b/js/comments.js
index 43e6fe96e..7841688aa 100644
--- a/js/comments.js
+++ b/js/comments.js
@@ -54,13 +54,13 @@ function toggle_all_comments(action) {
}
function collapse_comment(link, comment, comment_id) {
- link.innerHTML = "[+]";
+ link.innerHTML = "<i class=\"fa fa-expand\" aria-hidden=\"true\"></i>";
YAHOO.util.Dom.addClass(comment, 'collapsed');
YAHOO.util.Dom.addClass('comment_tag_' + comment_id, 'collapsed');
}
function expand_comment(link, comment, comment_id) {
- link.innerHTML = "[&minus;]";
+ link.innerHTML = "<i class=\"fa fa-compress\" aria-hidden=\"true\"></i>";
YAHOO.util.Dom.addClass('cr' + comment_id, 'collapsed');
YAHOO.util.Dom.removeClass('c' + comment_id, 'bz_default_collapsed');
YAHOO.util.Dom.removeClass(comment, 'collapsed');
@@ -116,13 +116,12 @@ function wrapReplyText(text) {
/* This way, we are sure that browsers which do not support JS
* won't display this link */
-
function addCollapseLink(count, collapsed, title) {
- document.write(' <a href="#" class="bz_collapse_comment"' +
+ document.write(' <a href="#" class="bz_collapse_comment btn btn-default btn-xs"' + 'style="background:transparent;color:#505050;border:none;"' +
' id="comment_link_' + count +
'" onclick="toggle_comment_display(this, ' + count +
- '); return false;" title="' + title + '">[' +
- (collapsed ? '+' : '&minus;') + ']<\/a> ');
+ '); return false;" title="' + title + '">' +
+ (collapsed ? '<i class="fa fa-expand" aria-hidden="true"></i>' : '<i class="fa fa-compress" aria-hidden="true"></i>') + '<\/a> ');
}
function goto_add_comments( anchor ){
diff --git a/js/global.js b/js/global.js
index ea1a11dd3..4735e84a7 100644
--- a/js/global.js
+++ b/js/global.js
@@ -33,7 +33,7 @@ function hide_mini_login_form( suffix ) {
function show_forgot_form( suffix ) {
var forgot_link = document.getElementById('forgot_link' + suffix);
var forgot_form = document.getElementById('forgot_form' + suffix);
- var login_container = document.getElementById('mini_login_container'
+ var login_container = document.getElementById('mini_login_container'
+ suffix);
YAHOO.util.Dom.addClass(forgot_link, 'bz_default_hidden');
YAHOO.util.Dom.removeClass(forgot_form, 'bz_default_hidden');
diff --git a/skins/contrib/Gentoo/global.css b/skins/contrib/Gentoo/global.css
index 20f79a607..b0f5d817a 100644
--- a/skins/contrib/Gentoo/global.css
+++ b/skins/contrib/Gentoo/global.css
@@ -21,10 +21,12 @@
*/
body {
- background: #D2D0D4;
+ background: #FAFAFA;
font-family: Helvetica, Arial, Geneva;
- padding: 1.5em;
+ min-height: 100vh;
+ position: relative;
margin: 0;
+ padding-bottom: 245px;
}
a img {
@@ -41,13 +43,24 @@ a img {
border-top-left-radius: 5px;
border-top-right-radius: 5px;
background-color: #54487A;
+ display: none;
}
-#header .links, #footer {
- background-color: #8076A1;
+#header .links {
+ background-color: #4D4270;
color: #ddd;
}
+#footer {
+ background-color: #E1E1E1;
+ color: #000;
+ position: absolute;
+ margin-top: 70px;
+ bottom: 0;
+ width: 100%;
+}
+
+
#header {
-webkit-border-bottom-right-radius: 5px;
-webkit-border-bottom-left-radius: 5px;
@@ -59,34 +72,43 @@ a img {
}
#header .links {
- border-bottom: 1px solid #67539B;
- border-left: 1px solid #67539B;
- border-right: 1px solid #67539B;
- -webkit-border-bottom-right-radius: 5px;
- -webkit-border-bottom-left-radius: 5px;
- -moz-border-radius-bottomright: 5px;
- -moz-border-radius-bottomleft: 5px;
- border-bottom-right-radius: 5px;
- border-bottom-left-radius: 5px;
+ border-bottom: 1px solid #4D4270;
+ border-left: 1px solid #4D4270;
+ border-right: 1px solid #4D4270;
+ -webkit-border-bottom-right-radius: 0px!important;
+ -webkit-border-bottom-left-radius: 0px!important;
+ -moz-border-radius-bottomright: 0px!important;
+ -moz-border-radius-bottomleft: 0px!important;
+ border-bottom-right-radius: 0px!important;
+ border-bottom-left-radius: 0px!important;
+}
+
+#header a {
+ color: white;
+ text-decoration: none;
}
-#header a, #footer a {
- color: white;
+#footer a {
+ color: black;
text-decoration: none;
}
-#header a:hover, #footer a:hover {
+#header a:hover {
+ text-decoration: none!important;
+}
+
+#footer a:hover {
text-decoration: underline;
}
/* body */
#bugzilla-body {
- background: #f0f0f0;
+ background: #FAFAFA;
color: black;
- border: 1px solid #747e93;
+ border: 0px solid #747e93;
padding: 10px;
- font-size: 10pt;
+ font-size: 14px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
@@ -329,3 +351,208 @@ body.bz_group_Security .bz_alias_short_desc_container:before {
}
/* vim: set expandtab ts=4: */
+
+#common_links {
+ background-color: #4D4270;
+}
+
+#bugs-actions {
+ border-radius: 0px!important;
+}
+
+.index_page_icon:hover {
+ color:#493f6a!important;
+}
+
+.index_page_icon {
+ color:#54487A;
+}
+
+.nav-pills > li > a {
+ background-color: #eeeeee!important;
+ color: #23457f!important;
+}
+
+.nav-pills > li.active > a {
+ background-color: #ffffff!important;
+ color: #23457f!important;
+}
+
+.selectwidthauto {
+ width:auto !important;
+ display: inline-block !important;
+}
+
+/* Backported from BS4 */
+
+select.form-control:not([multiple]) {
+ display: inline-block;
+ width: 100%;
+ height: 34px;
+ padding: 0.375rem 1.75rem 0.375rem 0.75rem;
+ font-size: 1rem;
+ font-weight: 400;
+ line-height: 1.5;
+ color: #495057;
+ vertical-align: middle;
+ background : url(./select-icon.svg) no-repeat;
+ background-repeat: no-repeat;
+ background-position: right 0.75rem center;
+ background-size: 8px 10px;
+ background-color: #fff;
+ border: 1px solid #ced4da;
+ border-radius: 0.25rem;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+
+ padding-top: .5rem;
+
+ padding-bottom: .5rem;
+
+ padding-left: 1rem;
+
+ font-size: 1.25rem;
+}
+
+select.form-control:focus {
+ border-color: #80bdff;
+ outline: 0;
+ box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
+}
+
+
+/* Make it compatible with BS */
+.collapsed {
+ display: block;
+}
+
+
+/*----------------------------*/
+
+#newBugTabs > .active {
+ font-weight: bold;
+}
+
+.nav > li > a.bgo_tab {
+ background-color: #FFFFFF !important;
+}
+
+.nav > li.active > a.bgo_tab {
+ color: #FFF !important;
+ background-color: #4D4270 !important;
+}
+
+.panel > .panel-body:before, .panel > .panel-body:after {
+ white-space: normal;
+}
+
+.email, .email:hover {
+ color: #000;
+}
+
+.comment-textarea {
+ width: 100%;
+ border-radius: 4px;
+ border: 1px solid #c9c9c9;
+}
+
+.comment-textarea:focus {
+ border: 1px solid #54487a;
+}
+
+#comment_tabs {
+ padding-left:8px;
+}
+
+.active_comment_tab {
+ background: transparent;
+ border-bottom: 4px solid #54487a;
+ color: #54487a;
+}
+
+.comment_tab {
+ border-top: none;
+ border-left: none;
+ border-right: none;
+ font-size: 13px;
+}
+
+
+.comment_tab:not(.active_comment_tab){
+ border-bottom: none;
+}
+
+@media (min-width: 768px) {
+ .row.equal {
+ display: flex;
+ display: -webkit-flex;
+ flex-wrap: wrap;
+ }
+}
+
+.align-h-right {
+ /* Internet Explorer 10 */
+ display:-ms-flexbox;
+ -ms-flex-pack:end;
+
+ /* Firefox */
+ display:-moz-box;
+ -moz-box-pack:end;
+
+ /* Safari, Opera, and Chrome */
+ display:-webkit-box;
+ -webkit-box-pack:end;
+
+ /* W3C */
+ display:box;
+ box-pack:end;
+}
+
+.align-h-center {
+ /* Internet Explorer 10 */
+ display:-ms-flexbox;
+ -ms-flex-pack:center;
+
+ /* Firefox */
+ display:-moz-box;
+ -moz-box-pack:center;
+
+ /* Safari, Opera, and Chrome */
+ display:-webkit-box;
+ -webkit-box-pack:center;
+
+ /* W3C */
+ display:box;
+ box-pack:center;
+}
+
+.align-v-center {
+ /* Internet Explorer 10 */
+ display:-ms-flexbox;
+ -ms-flex-align:center;
+
+ /* Firefox */
+ display:-moz-box;
+ -moz-box-align:center;
+
+ /* Safari, Opera, and Chrome */
+ display:-webkit-box;
+ -webkit-box-align:center;
+
+ /* W3C */
+ display:box;
+ box-align:center;
+}
+
+#con_calendar_deadlineto,#con_calendar_deadline {
+ z-index: 9999;
+}
+
+#guided_form > .row {
+ margin-bottom: 20px;
+}
+
+#Create > .row {
+ margin-bottom: 20px;
+} \ No newline at end of file
diff --git a/skins/contrib/Gentoo/select-icon.svg b/skins/contrib/Gentoo/select-icon.svg
new file mode 100644
index 000000000..58f4ea790
--- /dev/null
+++ b/skins/contrib/Gentoo/select-icon.svg
@@ -0,0 +1 @@
+<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'><path fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/></svg> \ No newline at end of file
diff --git a/skins/contrib/Gentoo/sort-down.png b/skins/contrib/Gentoo/sort-down.png
new file mode 100644
index 000000000..64306325d
--- /dev/null
+++ b/skins/contrib/Gentoo/sort-down.png
Binary files differ
diff --git a/skins/standard/bug.css b/skins/standard/bug.css
index 851b1bdba..4d86b3b43 100644
--- a/skins/standard/bug.css
+++ b/skins/standard/bug.css
@@ -94,7 +94,19 @@ table#attachment_flags th, table#attachment_flags td {
/* CSS rules for the guided form. */
.guided_form_field {
- background-color: #ffc;
+ background-color: #FCF8E3;
+ border-color: #faebcc;
+ border: 1px solid #faebcc;
+ border-radius: 4px!important;
+/* color: #8a6d3b;*/
+}
+
+.guided_form_field > td, .guided_form_field > th {
+ padding: 5px 2px;
+}
+
+.spacer {
+ height:20px;
}
#somebugs {
@@ -117,8 +129,8 @@ table#attachment_flags th, table#attachment_flags td {
.bz_short_desc_container {
margin: 8px 0;
padding: 0.3em;
- background-color: rgb(208, 208, 208);
- border-radius: 0.5em;
+ background-color: #E1E1E1;
+ border-radius: 4px;
font-size: 125%;
font-weight: bold;
}
@@ -129,6 +141,11 @@ table#attachment_flags th, table#attachment_flags td {
.bz_bug .edit_form table {
width: 100%;
}
+
+.field_help_link {
+ color: #493F6B;
+}
+
.bz_bug #alias {
min-width: 0;
width: 10em;
diff --git a/skins/standard/global.css b/skins/standard/global.css
index fea45d1c6..a4385ea34 100644
--- a/skins/standard/global.css
+++ b/skins/standard/global.css
@@ -10,7 +10,7 @@
body {
font-family: sans-serif;
color: #000;
- background: #fff url("global/body-back.gif") repeat-x;
+ /* background: #fff url("global/body-back.gif") repeat-x; */
}
body, td, th, input, dt, #titles {
font-family: Verdana, sans-serif;
@@ -847,7 +847,7 @@ tr.shared_search {
#page-index {
padding: 0.2em 0.2em 0.15em 0.2em;
- max-width: 1000px;
+/* max-width: 1000px; */
}
/* By default these contain nothing, but these CSS rules make things
@@ -910,15 +910,6 @@ tr.shared_search {
#account { background: url(index/new-account.png) no-repeat; }
#help { background: url(index/help.png) no-repeat; }
-#quicksearchForm {
- clear: both;
- text-align: center;
- margin-bottom: 2em;
-}
-
-#quicksearchForm #quicksearch_main {
- width: 27em;
-}
#quicksearchForm {
margin: 0;
@@ -971,7 +962,7 @@ ul.additional_links li.bz_default_hidden {
body.narrow_page #bugzilla-body > * {
/* People have an easier time reading narrower columns of text. */
- max-width: 45em;
+ //max-width: 45em;
}
/*****************/
diff --git a/skins/standard/index/file-a-bug.png.bak b/skins/standard/index/file-a-bug.png.bak
new file mode 100644
index 000000000..a3e48c79d
--- /dev/null
+++ b/skins/standard/index/file-a-bug.png.bak
Binary files differ
diff --git a/skins/standard/index/search.png b/skins/standard/index/search.png
index a41998902..30837c251 100644
--- a/skins/standard/index/search.png
+++ b/skins/standard/index/search.png
Binary files differ
diff --git a/skins/standard/index/search.svg b/skins/standard/index/search.svg
new file mode 100644
index 000000000..865b962e2
--- /dev/null
+++ b/skins/standard/index/search.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"/></svg> \ No newline at end of file
diff --git a/template/en/custom/account/auth/login-small.html.tmpl b/template/en/custom/account/auth/login-small.html.tmpl
new file mode 100644
index 000000000..9678cf840
--- /dev/null
+++ b/template/en/custom/account/auth/login-small.html.tmpl
@@ -0,0 +1,40 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# Use the current script name. If an empty name is returned,
+ # then we are accessing the home page. %]
+
+[% USE Bugzilla %]
+[% cgi = Bugzilla.cgi %]
+
+[% login_target = cgi.url("-relative" => 1, "-query" => 1) %]
+[% IF !login_target OR login_target.match("^token.cgi") %]
+ [% login_target = "index.cgi" %]
+[% END %]
+
+<li>
+ [% connector = "?" %]
+ [% IF cgi.request_method == "GET" AND cgi.query_string %]
+ [% connector = "&" %]
+ [% END %]
+ [% script_url = login_target _ connector _ "GoAheadAndLogIn=1" %]
+ <!--<a id="login_link[% qs_suffix %]" href="[% script_url FILTER html %]"-->
+ <!--onclick="return show_mini_login_form('[% qs_suffix %]')" style="color:#262626">Log In</a>-->
+ <a id="login_link[% qs_suffix %]" href="enter_bug.cgi?format=guided" style="color:#262626">Log In</a>
+
+</li>
+
+[% Hook.process('additional_methods') %]
+
+[% IF user.authorizer.can_change_password %]
+ <li>
+
+ <a id="forgot_link[% qs_suffix %]" href="[% script_url FILTER html %]#forgot"
+ onclick="return show_forgot_form('[% qs_suffix %]')" style="color:#262626">Forgot Password</a>
+ </li>
+[% END %]
diff --git a/template/en/custom/account/auth/login.html.tmpl b/template/en/custom/account/auth/login.html.tmpl
new file mode 100644
index 000000000..a42165333
--- /dev/null
+++ b/template/en/custom/account/auth/login.html.tmpl
@@ -0,0 +1,167 @@
+[%# 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:
+ # target: string. URL to go to after login.
+ #%]
+
+[% IF !target %]
+ [% target = "index.cgi" %]
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = "Log in to $terms.Bugzilla"
+%]
+
+[% USE Bugzilla %]
+
+<div class="container">
+ <div class="row" style="margin-top:100px;">
+ <div class="col-sm-3"></div>
+ <div class="col-sm-6">
+
+ <div class="panel panel-primary">
+ <div class="panel-heading">[% terms.Bugzilla %] needs a legitimate login and password to continue.</div>
+ <div class="panel-body">
+ <div class="text-center" style="margin-bottom:20px;">
+ <object data="https://assets.gentoo.org/tyrian/site-logo.svg" type="image/svg+xml">
+ <img src="https://assets.gentoo.org/tyrian/site-logo.png" alt="Gentoo Linux logo">
+ </object>
+ </div>
+
+<form name="login" action="[% urlbase FILTER html %][% target FILTER html %]" method="POST"
+[%- IF Bugzilla.cgi.param("data") %] enctype="multipart/form-data"[% END %]>
+ <table>
+ <tr>
+ <td style="padding-bottom:20px!important;padding-left:40px!important;padding-right:40px!important;">
+ <div class="input-group">
+ <span class="input-group-addon" style="width: 160px;text-align: right;">[% IF login_not_email %]Login:[% ELSE %]Email Address:[% END %]</span>
+ <input size="35" id="Bugzilla_login" name="Bugzilla_login" class="form-control"
+ [%- ' type="email"' UNLESS login_not_email %] autofocus required>
+ </div>
+ [% Param('emailsuffix') FILTER html %]
+ </td>
+ </tr>
+ <tr>
+ <td style="padding-bottom:10px!important;padding-left:40px!important;padding-right:40px!important;">
+ <div class="input-group">
+ <span class="input-group-addon" style="width: 160px;text-align: right;">Password:</span>
+ <input type="password" size="35" id="Bugzilla_password" name="Bugzilla_password" class="form-control" required>
+ </div>
+ </td>
+ </tr>
+
+ [% IF Param('rememberlogin') == 'defaulton' ||
+ Param('rememberlogin') == 'defaultoff' %]
+ <tr>
+ <td>
+ <input type="checkbox" id="Bugzilla_remember" name="Bugzilla_remember" value="on"
+ [%+ "checked" IF Param('rememberlogin') == "defaulton" %]>
+ <label for="Bugzilla_remember">Remember my Login</label>
+ </td>
+ </tr>
+ [% END %]
+
+ <tr>
+ <td style="padding-bottom:5px!important;">
+ <input type="checkbox" id="Bugzilla_restrictlogin" name="Bugzilla_restrictlogin" checked="checked">
+ <small>Restrict this session to this IP address
+ (using this option improves security)</small>
+ </td>
+ </tr>
+ </table>
+ <small>
+ (Note: you should make sure cookies are enabled for this site.
+ Otherwise, you will be required to log in frequently.)
+ </small><br>
+
+ [% PROCESS "global/hidden-fields.html.tmpl"
+ exclude="^Bugzilla_(login|password|restrictlogin)$" %]
+
+ <input type="hidden" name="Bugzilla_login_token"
+ value="[% get_login_request_token() FILTER html %]">
+ <div class="text-right" style="width:100%;">
+ <input type="submit" class="btn btn-primary" name="GoAheadAndLogIn" value="Log in" id="log_in">
+ </div>
+</form>
+
+[% Hook.process('additional_methods') %]
+
+[%# Allow the user to create a new account, or request a token to change
+ # their password, assuming that our auth method allows that.
+ #%]
+
+ <hr>
+ <div style="text-align:right;width:100%;"><a href="createaccount.cgi">Create a new account</a> - <a data-toggle="collapse" href="#collapseExample" aria-expanded="false" aria-controls="collapseExample">Reset password</a>
+ </div>
+
+ <div class="collapse" id="collapseExample">
+ <hr>
+ <form id="forgot" method="get" action="token.cgi">
+ <input type="hidden" name="a" value="reqpw">
+ If you have an account, but have forgotten your password,
+ enter your login name below and submit a request
+ to change your password.<br><br>
+ <input type="hidden" id="token" name="token" value="1573865609-H__9K8FmfSYj3SvcdQVGY6v05L46viUZLFxC82u85Gc">
+ <div class="input-group" style="max-width:450px;">
+ <input size="35" class="form-control" name="loginname" required="">
+ <div class="input-group-btn">
+ <button type="submit" class="btn btn-default" id="request" value="Reset Password">Reset Password</button>
+ </div>
+ </div>
+ </form>
+ </div>
+
+<!--
+ [% IF Param("createemailregexp") && user.authorizer.user_can_create_account %]
+ <hr>
+
+ <p>
+ If you don't have a [% terms.Bugzilla %] account, you can
+ <a href="createaccount.cgi">create a new account</a>.
+ [% IF Param("requirelogin") %]
+ A user account is required because this Bugzilla
+ installation is only accessible to authenticated users.
+ [% ELSIF target.match("_bug\.cgi$") %]
+ A user account is required to file a new [% terms.bug %] or to comment
+ into existing ones so that you can be contacted if more information is
+ needed.
+ [% END %]
+ </p>
+ [% END %]
+
+ [% IF user.authorizer.can_change_password %]
+ <hr>
+
+ <form id="forgot" method="get" action="token.cgi">
+ <input type="hidden" name="a" value="reqpw">
+ If you have an account, but have forgotten your password,
+ enter your login name below and submit a request
+ to change your password.<br>
+ <input type="hidden" id="token" name="token" value="[% issue_hash_token(['reqpw']) FILTER html %]">
+ <div class="input-group" style="max-width:450px;">
+ <input size="35" class="form-control" name="loginname" required>
+ <div class="input-group-btn">
+ <button type="submit" class="btn btn-default" id="request" value="Reset Password">Reset Password</button>
+ </div>
+ </div>
+ </form>
+ [% END %]
+
+ -->
+
+ </div>
+ </div>
+
+ </div>
+ <div class="col-sm-3"></div>
+ </div>
+
+</div>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/custom/account/create.html.tmpl b/template/en/custom/account/create.html.tmpl
new file mode 100644
index 000000000..d6f788acb
--- /dev/null
+++ b/template/en/custom/account/create.html.tmpl
@@ -0,0 +1,101 @@
+[%# 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
+ # none
+ #
+ # Param("maintainer") is used to display the maintainer's email.
+ # Param("emailsuffix") is used to pre-fill the email field.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Create a new $terms.Bugzilla account"
+%]
+
+<div class="panel panel-default">
+ <div class="panel-heading">
+ <h3 class="panel-title">Create a new account</h3>
+ </div>
+ <div class="panel-body">
+
+<p>
+ To create a [% terms.Bugzilla %] account, all you need to do is to enter
+[% IF Param('emailsuffix') == '' %]
+ a legitimate email address.
+[% ELSE %]
+ an account name which when combined with [% Param('emailsuffix') %]
+ corresponds to an address where you receive email.
+[% END %]
+ You will receive an email at this address to confirm the creation of your
+ account. <b>You will not be able to log in until you receive the email.</b>
+ If it doesn't arrive within a reasonable amount of time, you may contact
+ the maintainer of this Bugzilla installation
+ at <a href="mailto:[% Param("maintainer") %]">[% Param("maintainer") %]</a>.
+</p>
+
+[% IF Param('allowemailchange') %]
+<p>
+ If you already have an account and want to change your
+ [% IF Param('emailsuffix') == '' %]
+ email address,
+ [% ELSE %]
+ login name,
+ [% END %]
+ you can change it from the Preferences page after logging in.
+</p>
+[% END %]
+
+<p>
+ A user account is required to report new [% terms.bugs %] or to comment into
+ existing ones, as you may be contacted for more information if needed.
+ This also lets other users clearly identify who is the author of comments
+ or changes made into [% terms.bugs %]. <b>Note that your email address will
+ <em>never</em> be displayed to logged out users. Only registered users will be
+ able to see it.</b>
+</p>
+
+[% IF Param('createemailregexp') == '.*' && Param('emailsuffix') == '' %]
+<p>
+ <b>PRIVACY NOTICE:</b> [% terms.Bugzilla %] is an open [% terms.bug %]
+ tracking system. Activity on most [% terms.bugs %], including email
+ addresses, will be visible to registered users. We <b>recommend</b> using a
+ secondary account or free web email service (such as Gmail, Yahoo,
+ Hotmail, or similar) to avoid receiving spam at your primary email address.
+</p>
+<p>
+<b>Please do not use temporary/throwaway email addresses to register, they cause
+too many mail bounces later when developers follow up bugs.</b>
+</p>
+[% END %]
+
+<form id="account_creation_form" method="get" action="createaccount.cgi" style="max-width:400px;">
+ <span class="label">
+ [% IF Param('emailsuffix') %]
+ Login:
+ [% ELSE %]
+ Email address:
+ [% END %]
+ </span>
+ <input type="hidden" id="token" name="token" value="[% issue_hash_token(['create_account']) FILTER html %]">
+
+ <div class="input-group">
+ <input size="35" id="login" name="login" class="form-control" autofocus
+ [%- ' type="email"' UNLESS Param('emailsuffix') %] required>
+ [% Param('emailsuffix') FILTER html %]
+ <div class="input-group-btn">
+ <div class="btn-group">
+ <button type="submit" class="btn btn-default" id="send" value="Send">Send</button>
+ </div>
+ </div>
+ </div>
+</form>
+
+</div>
+</div>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/custom/account/prefs/prefs.html.tmpl b/template/en/custom/account/prefs/prefs.html.tmpl
new file mode 100644
index 000000000..ecf5fdca9
--- /dev/null
+++ b/template/en/custom/account/prefs/prefs.html.tmpl
@@ -0,0 +1,112 @@
+[%# 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:
+ # tabs: List of hashes. May not be empty. Each hash has three members:
+ # name: string. Name of the tab (used internally.)
+ # description: string. Description of the tab (used in tab title).
+ # saveable: boolean. True if tab has a form which can be submitted.
+ # True if user is not receiving self-generated mail.
+ # Note: For each tab name, a template "prefs/${tab.name}.tmpl" must exist,
+ # and its interface must be fulfilled.
+ # current_tab: A direct reference to one of the hashes in the tabs list.
+ # This tab will be displayed.
+ # changes_saved: boolean/string. True if the CGI processed form data before
+ # displaying anything, and can contain an optional custom
+ # message if required (which Perl still evaluates as True).
+ # dont_show_button: boolean. Prevent the display of the "Submit Changes" button.
+ #%]
+
+[% filtered_login = user.login FILTER html %]
+
+[% tabs = [{ name => "settings", label => "General Preferences",
+ link => "userprefs.cgi?tab=settings", saveable => "1",
+ doc_section => "using/preferences.html#general-preferences" },
+ { name => "email", label => "Email Preferences",
+ link => "userprefs.cgi?tab=email", saveable => "1",
+ doc_section => "using/preferences.html#email-preferences" },
+ { name => "saved-searches", label => "Saved Searches",
+ link => "userprefs.cgi?tab=saved-searches", saveable => "1",
+ doc_section => "using/preferences.html#saved-searches" },
+ { name => "account", label => "Account Information",
+ link => "userprefs.cgi?tab=account", saveable => "1",
+ doc_section => "using/preferences.html#account-information" },
+ { name => "apikey", label => "API Keys",
+ link => "userprefs.cgi?tab=apikey", saveable => "1",
+ doc_section => "using/preferences.html#api-keys" },
+ { name => "permissions", label => "Permissions",
+ link => "userprefs.cgi?tab=permissions", saveable => "0",
+ doc_section => "using/preferences.html#permissions" } ] %]
+
+[% Hook.process('tabs') %]
+
+[% FOREACH tab IN tabs %]
+ [% IF tab.name == current_tab_name %]
+ [% current_tab = tab %]
+ [% LAST %]
+ [% END %]
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = current_tab.label
+ subheader = filtered_login
+ generate_api_token = 1
+ style_urls = ['skins/standard/admin.css']
+ javascript_urls = ['js/util.js', 'js/field.js', 'js/TUI.js']
+ doc_section = current_tab.doc_section
+ yui = ['autocomplete']
+ %]
+
+[% WRAPPER global/tabs.html.tmpl
+ tabs = tabs
+ current_tab = current_tab
+%]
+
+[% IF changes_saved %]
+ <div id="message">
+ The changes to your [% current_tab.label FILTER lower %] have been saved.
+
+ [% IF email_changes_saved %]
+ <p>
+ In order to confirm your request, we have sent an email to your
+ new email address. As a precaution, an email has also been sent
+ to your old address allowing you to cancel this change if needed.
+ If you don't receive the email, you can
+ <a href="token.cgi?t=[% email_token FILTER uri %]&amp;a=cxlem">
+ cancel the email address change</a> from here if you wish (especially
+ if you mistyped the new email address).
+ </p>
+ [% END %]
+ </div>
+[% END %]
+
+<h3>[% current_tab.label %]</h3>
+
+[% IF current_tab.saveable %]
+ <form name="userprefsform" method="post" action="userprefs.cgi">
+ <input type="hidden" name="tab" value="[% current_tab.name %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+[% END %]
+
+[% PROCESS "account/prefs/${current_tab.name}.html.tmpl"
+ IF current_tab.name.defined %]
+
+[% IF current_tab.saveable %]
+ <input type="hidden" name="dosave" value="1">
+ [% UNLESS dont_show_button %]
+ <p>
+ <input type="submit" class="btn btn-primary" id="update" value="Submit Changes">
+ </p>
+ [% END %]
+ </form>
+[% END %]
+
+[% END %]
+
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/custom/account/prefs/settings.html.tmpl b/template/en/custom/account/prefs/settings.html.tmpl
new file mode 100644
index 000000000..984abcc98
--- /dev/null
+++ b/template/en/custom/account/prefs/settings.html.tmpl
@@ -0,0 +1,68 @@
+[%# 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:
+ # setting_names: an array of strings
+ # settings: a hash of hashes, keyed by setting_name.
+ # Each hash contains:
+ # is_enabled - boolean
+ # default_value - string (global default for this setting)
+ # value - string (user-defined preference)
+ # is_default - boolean (true if user has no preference)
+ # has_settings_enabled : boolean; is true if there is at least one user pref
+ # enabled by the maintainer.
+ #%]
+
+[% PROCESS "global/setting-descs.none.tmpl" %]
+
+[% IF settings.size %]
+ [% UNLESS has_settings_enabled %]
+ <p class="criticalmessages">
+ All user preferences have been disabled by the
+ <a href="mailto:[% Param("maintainer") %]">maintainer</a>
+ of this installation, and so you cannot customize any.
+ </p>
+ [% END %]
+
+ <table id="user_prefs">
+ [% FOREACH name = setting_names %]
+ [% default_name = name _ '-isdefault' %]
+ [% default_val = settings.${name}.default_value %]
+ <tr>
+ <td class="right">
+ [% setting_descs.$name OR name FILTER html %]
+ </td>
+ <td>
+ [% IF settings.${name}.is_enabled %]
+ <select name="[% name FILTER html %]" id="[% name FILTER html %]" class="form-control">
+ <option value="[% default_name FILTER html %]"
+ [% ' selected="selected"' IF settings.${name}.is_default %]>
+ Site Default ([% setting_descs.${default_val} OR default_val FILTER html %])
+ </option>
+ [% FOREACH x = settings.${name}.legal_values %]
+ <option value="[% x FILTER html %]"
+ [% ' selected="selected"'
+ IF x == settings.${name}.value
+ AND NOT settings.${name}.is_default %]>
+ [% setting_descs.${x} OR x FILTER html %]
+ </option>
+ [% END %]
+ </select>
+ [% ELSE %]
+ <select name="[% name FILTER html %]" id="[% name FILTER html %]" disabled="disabled" class="form-control">
+ <option value="[% default_name FILTER html %]">
+ Site Default ([% setting_descs.${default_val} OR default_val FILTER html %])
+ </option>
+ </select>
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+ </table>
+[% END %]
+<br>
diff --git a/template/en/custom/admin/custom_fields/edit.html.tmpl b/template/en/custom/admin/custom_fields/edit.html.tmpl
new file mode 100644
index 000000000..e685e43d1
--- /dev/null
+++ b/template/en/custom/admin/custom_fields/edit.html.tmpl
@@ -0,0 +1,56 @@
+[%# 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:
+ # field: Bugzila::Field; the current field being edited
+ #%]
+
+[% title = BLOCK %]
+ Edit the Custom Field '[% field.name FILTER html %]' ([% field.description FILTER html %])
+[% END %]
+
+[% javascript = BLOCK %]
+ [% INCLUDE "admin/custom_fields/cf-js.js.tmpl" %]
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ onload = "toggleCheckbox(document.getElementById('enter_bug'), 'new_bugmail');"
+ javascript_urls = [ 'js/util.js' ]
+ doc_section = "administering/custom-fields.html#editing-custom-fields"
+ style_urls = ['skins/standard/admin.css']
+%]
+
+<p>
+ Descriptions are a very short string describing the field and will be used as
+ the label for this field in the user interface.
+</p>
+
+<form id="edit_field" action="editfields.cgi" method="GET">
+ [% PROCESS "admin/custom_fields/edit-common.html.tmpl" field = field %]
+
+ <input type="hidden" name="action" value="update">
+ <input type="hidden" name="name" value="[% field.name FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ <input type="submit" class="btn btn-primary" id="edit" value="Submit">
+</form>
+
+[% IF field.obsolete %]
+<p>
+ <a href="editfields.cgi?action=del&amp;name=[% field.name FILTER html %]">Remove
+ this custom field from the database.</a><br>
+ This action will only be successful if the custom field has never been used
+ in [% terms.abug %].<br>
+</p>
+[% END %]
+
+<p>
+ <a href="editfields.cgi">Back to the list of existing custom fields</a>
+</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/custom/admin/fieldvalues/create.html.tmpl b/template/en/custom/admin/fieldvalues/create.html.tmpl
new file mode 100644
index 000000000..22bcc3398
--- /dev/null
+++ b/template/en/custom/admin/fieldvalues/create.html.tmpl
@@ -0,0 +1,93 @@
+[%# 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:
+ # field: object; the field the value is being created for
+ #%]
+
+[% title = BLOCK %]
+ Add Value for the '[% field.description FILTER html %]' ([% field.name FILTER html %]) field
+[% END %]
+[% PROCESS global/header.html.tmpl
+ title = title
+ style_urls = ['skins/standard/admin.css']
+%]
+
+<p>
+ This page allows you to add a new value for the
+ '[% field.description FILTER html %]' field.
+</p>
+
+<form method="post" action="editvalues.cgi">
+ <table id="admin_table_edit">
+ <tr>
+ <th><label for="value">Value:</label></th>
+ <td>
+ <input id="value" name="value" size="30"
+ maxlength="[% constants.MAX_FIELD_VALUE_SIZE FILTER none %]" required>
+ </td>
+ </tr>
+ <tr>
+ <th><label for="sortkey">Sortkey:</label></th>
+ <td><input id="sortkey" name="sortkey" size="6" maxlength="6"></td>
+ </tr>
+ [% IF field.name == "bug_status" %]
+ <tr>
+ <th><label for="is_open">Status Type:</label></th>
+ <td>
+ <input type="radio" id="open_status" name="is_open" value="1"
+ checked="checked">
+ <label for="open_status">Open</label><br>
+ <input type="radio" id="closed_status" name="is_open" value="0">
+ <label for="closed_status">Closed (requires a Resolution)</label>
+ </td>
+ </tr>
+ <tr>
+ <th>&nbsp;</th>
+ <td>
+ Note: The open/close attribute can only be set now, when you create
+ the status. It cannot be edited later.
+ </td>
+ </tr>
+ [% END %]
+ [% IF field.value_field %]
+ <tr>
+ <th>
+ <label for="visibility_value_id">Only appears when
+ [%+ field.value_field.description FILTER html %] is set to:
+ </label>
+ </th>
+ <td>
+ <select name="visibility_value_id" id="visibility_value_id">
+ <option></option>
+ [% FOREACH field_value = field.value_field.legal_values %]
+ [% NEXT IF field_value.name == '' %]
+ <option value="[% field_value.id FILTER none %]">
+ [% IF field.value_field.name == 'component' %]
+ [% field_value.product.name FILTER html %]:
+ [% END %]
+ [%- field_value.name FILTER html -%]
+ </option>
+ [% END %]
+ </select>
+ <span class="bz_info">(Leave unset to have this value always appear.)</span>
+ </td>
+ </tr>
+ [% END %]
+ </table>
+ <input type="submit" class="btn btn-primary" id="create" value="Add">
+ <input type="hidden" name="action" value="new">
+ <input type="hidden" name='field' value="[% field.name FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+</form>
+
+[% PROCESS admin/fieldvalues/footer.html.tmpl
+ no_add_link = 1
+ %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/custom/admin/fieldvalues/edit.html.tmpl b/template/en/custom/admin/fieldvalues/edit.html.tmpl
new file mode 100644
index 000000000..3ca91c849
--- /dev/null
+++ b/template/en/custom/admin/fieldvalues/edit.html.tmpl
@@ -0,0 +1,103 @@
+[%# 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:
+ # value: Bugzilla::Field::Choice; The field value we are editing.
+ # field: Bugzilla::Field; The field this value belongs to.
+ #%]
+
+[% title = BLOCK %]
+ Edit Value '[% value.name FILTER html %]' for the
+ '[% field.description FILTER html %]' ([% field.name FILTER html %]) field
+[% END %]
+[% PROCESS global/header.html.tmpl
+ title = title
+ style_urls = ['skins/standard/admin.css']
+%]
+
+<form method="post" action="editvalues.cgi">
+ <table id="admin_table_edit">
+ <tr>
+ <th><label for="value_new">Field Value:</label></th>
+ <td>
+ [% IF value.is_static %]
+ <input type="hidden" name="value_new" id="value_new"
+ value="[% value.name FILTER html %]">
+ [%- value.name FILTER html %]
+ [% ELSE %]
+ <input id="value_new" name="value_new" size="20"
+ maxlength="[% constants.MAX_FIELD_VALUE_SIZE FILTER none %]"
+ value="[% value.name FILTER html %]" required>
+ [% END %]
+ </td>
+ </tr>
+ <tr>
+ <th><label for="sortkey">Sortkey:</label></th>
+ <td><input id="sortkey" size="6" maxlength="6" name="sortkey"
+ value="[%- value.sortkey FILTER html %]"></td>
+ </tr>
+ [% IF field.name == "bug_status" %]
+ <tr>
+ <th><label for="is_open">Status Type:</label></th>
+ <td>[% IF value.is_open %]Open[% ELSE %]Closed[% END %]</td>
+ </tr>
+ [% END %]
+ [% IF field.value_field %]
+ <tr>
+ <th>
+ <label for="visibility_value_id">Only appears when
+ [%+ field.value_field.description FILTER html %] is set to:
+ </label>
+ </th>
+ <td>
+ <select name="visibility_value_id" id="visibility_value_id">
+ <option></option>
+ [% FOREACH field_value = field.value_field.legal_values %]
+ [% NEXT IF field_value.name == '' %]
+ <option value="[% field_value.id FILTER none %]"
+ [% ' selected="selected"'
+ IF field_value.id == value.visibility_value.id %]>
+ [% IF field.value_field.name == 'component' %]
+ [% field_value.product.name FILTER html %]:
+ [% END %]
+ [% field_value.name FILTER html -%]
+ </option>
+ [% END %]
+ </select>
+ <span class="bz_info">(Leave unset to have this value always appear.)</span>
+ </td>
+ </tr>
+ [% END %]
+ <tr>
+ <th><label for="is_active">Enabled for [% terms.bugs %]:</label></th>
+ <td><input id="is_active" name="is_active" type="checkbox" value="1"
+ [%+ 'checked="checked"' IF value.is_active %]
+ [%+ 'disabled="disabled"' IF value.is_default OR value.is_static %]>
+ [% IF value.is_default %]
+ This value is selected as default in the parameters for this field. It cannot be disabled.
+ [% ELSIF value.is_static %]
+ This value is non-deletable and cannot be disabled.
+ [% END %]
+ [% IF !(value.is_default OR value.is_static) %]
+ <input id="defined_is_active" name="defined_is_active"
+ type="hidden" value="1">
+ [% END %]
+ </td>
+ </tr>
+ </table>
+ <input type="hidden" name="value" value="[% value.name FILTER html %]">
+ <input type="hidden" name="action" value="update">
+ <input type="hidden" name="field" value="[% field.name FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ <input type="submit" class="btn btn-primary" id="update" value="Save Changes">
+</form>
+
+[% PROCESS admin/fieldvalues/footer.html.tmpl
+ no_edit_link = 1 %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/custom/admin/flag-type/confirm-delete.html.tmpl b/template/en/custom/admin/flag-type/confirm-delete.html.tmpl
new file mode 100644
index 000000000..0f3a12b59
--- /dev/null
+++ b/template/en/custom/admin/flag-type/confirm-delete.html.tmpl
@@ -0,0 +1,40 @@
+[%# 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.
+ #%]
+
+[% title = BLOCK %]Confirm Deletion of Flag Type '[% flag_type.name FILTER html %]'[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ style_urls = ['skins/standard/admin.css']
+ doc_section = "administering/flags.html#deleting-a-flag"
+%]
+
+<p>
+ [% IF flag_type.flag_count %]
+ There are [% flag_type.flag_count %] flags of type [% flag_type.name FILTER html %].
+ If you delete this type, those flags will also be deleted.
+ [% END %]
+
+ Note that instead of deleting the type you can
+ <a href="editflagtypes.cgi?action=deactivate&amp;id=[% flag_type.id %]&amp;token=
+ [%- token FILTER html %]">deactivate it</a>,
+ in which case the type [% IF flag_type.flag_count %] and its flags [% END %] will remain
+ in the database but will not appear in the Bugzilla UI.
+</p>
+
+<div class="alert alert-danger">
+ Do you really want to delete this type?
+</div>
+
+<p>
+ <a href="editflagtypes.cgi?action=delete&amp;id=[% flag_type.id %]&amp;token=
+ [%- token FILTER html %]">Yes, delete</a> -
+ <a href="editflagtypes.cgi">No, don't delete</a>
+</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/custom/admin/flag-type/edit.html.tmpl b/template/en/custom/admin/flag-type/edit.html.tmpl
new file mode 100644
index 000000000..17f852271
--- /dev/null
+++ b/template/en/custom/admin/flag-type/edit.html.tmpl
@@ -0,0 +1,262 @@
+[%# 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/js-products.html.tmpl" %]
+
+[% IF action == "insert" %]
+ [% title = BLOCK %]
+ Create Flag Type for [% type.target_type == "bug" ? terms.Bugs : "Attachments" %]
+ [% IF type.id %]
+ Based on [% type.name FILTER html %]
+ [% END %]
+ [% END %]
+[% ELSE %]
+ [% title = BLOCK %]Edit Flag Type [% type.name FILTER html %][% END %]
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ style_urls = ['skins/standard/admin.css']
+ onload="var f = document.forms['flagtype_properties'];
+ selectProduct(f.product, f.component, '__Any__');"
+ javascript_urls=["js/productform.js"]
+ doc_section = "administering/flags.html"
+%]
+
+<form id="flagtype_properties" method="post" action="editflagtypes.cgi">
+ <input type="hidden" name="action" value="[% action FILTER html %]">
+ <input type="hidden" name="can_fully_edit" value="[% can_fully_edit FILTER html %]">
+ <input type="hidden" name="id" value="[% type.id FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ <input type="hidden" name="target_type" value="[% type.target_type FILTER html %]">
+ <input type="hidden" name="check_clusions" value="[% check_clusions FILTER none %]">
+ [% FOREACH category = inclusions.values %]
+ <input type="hidden" name="inclusions" value="[% category FILTER html %]">
+ [% END %]
+ [% FOREACH category = exclusions.values %]
+ <input type="hidden" name="exclusions" value="[% category FILTER html %]">
+ [% END %]
+
+ [%# Add a hidden button at the top of the form so that the user pressing "return"
+ # really submit the form, as expected. %]
+ <input type="submit" id="commit" value="Submit" class="bz_default_hidden">
+
+ <table id="admin_table_edit">
+ <tr>
+ <th>Name:</th>
+ <td>
+ a short name identifying this type.<br>
+ <input type="text" name="name" value="[% type.name FILTER html %]" size="50"
+ maxlength="50" [%- ' disabled="disabled"' UNLESS can_fully_edit %] required>
+ </td>
+ </tr>
+
+ <tr>
+ <th>Description:</th>
+ <td>
+ a comprehensive description of this type.<br>
+ [% INCLUDE global/textarea.html.tmpl
+ name = 'description'
+ minrows = 4
+ cols = 80
+ defaultcontent = type.description
+ disabled = !can_fully_edit
+ mandatory = 1
+ %]
+ </td>
+ </tr>
+
+ <tr>
+ <th>Category:</th>
+
+ <td>
+ the products/components to which [% type.target_type == "bug" ? terms.bugs : "attachments" %]
+ must (inclusions) or must not (exclusions) belong in order for users
+ to be able to set flags of this type for them.
+ [% UNLESS can_fully_edit %]
+ <p class="warning">This flagtype also applies to some products you are not allowed
+ to edit (and so which are not displayed in the lists below). Your limited privileges
+ means you are only allowed to add and remove this flagtype to/from products you can
+ edit, but not to edit other properties of the flagtype.</p>
+ [% END %]
+ <table>
+ <tr>
+ <th class="top left">
+ Product/Component:<br>
+ [% INCLUDE "global/product-select.html.tmpl"
+ id => "product"
+ name => "product"
+ add => "__Any__"
+ onchange => "selectProduct(this, this.form.component, '__Any__');"
+ products => products
+ %]<br>
+ <select name="component" class="form-control selectwidthauto">
+ <option value="">__Any__</option>
+ [% FOREACH comp = components %]
+ <option value="[% comp FILTER html %]">[% comp FILTER html %]</option>
+ [% END %]
+ </select><br>
+ <input type="submit" class="btn btn-default" id="categoryAction-include"
+ name="categoryAction-include" value="Include">
+ <input type="submit" class="btn btn-default" id="categoryAction-exclude"
+ name="categoryAction-exclude" value="Exclude">
+ </th>
+ <th class="top left">
+ Inclusions:<br>
+ [% PROCESS category_select name="inclusion_to_remove" categories = inclusions %]<br>
+ <input type="submit" class="btn btn-default" id="categoryAction-removeInclusion"
+ name="categoryAction-removeInclusion" value="Remove Inclusion">
+ </th>
+ <th class="top left">
+ Exclusions:<br>
+ [% PROCESS category_select name="exclusion_to_remove" categories = exclusions %]<br>
+ <input type="submit" class="btn btn-default" id="categoryAction-removeExclusion"
+ name="categoryAction-removeExclusion" value="Remove Exclusion">
+ </th>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th>Sort Key:</th>
+ <td>
+ a number between 0 and [% constants.MAX_SMALLINT FILTER none %] by which
+ this type will be sorted when displayed to users in a list; ignore if you
+ don't care what order the types appear in or if you want them to appear
+ in alphabetical order.<br>
+ <input type="text" name="sortkey" value="[% type.sortkey || 0 FILTER html %]" size="5"
+ maxlength="5" [% ' disabled="disabled"' UNLESS can_fully_edit %] required>
+ </td>
+ </tr>
+
+ <tr>
+ <th>&nbsp;</th>
+ <td>
+ <input type="checkbox" id="is_active" name="is_active"
+ [%- ' disabled="disabled"' UNLESS can_fully_edit %]
+ [% " checked" IF type.is_active || !type.is_active.defined %]>
+ <label for="is_active">active (flags of this type appear in the UI and can be set)</label>
+ </td>
+ </tr>
+
+ <tr>
+ <th>&nbsp;</th>
+ <td>
+ <input type="checkbox" id="is_requestable" name="is_requestable"
+ [%- ' disabled="disabled"' UNLESS can_fully_edit %]
+ [% " checked" IF type.is_requestable || !type.is_requestable.defined %]>
+ <label for="is_requestable">requestable (users can ask for flags of this type to be set)</label>
+ </td>
+ </tr>
+
+ <tr>
+ <th>CC List:</th>
+ <td>
+ if requestable, who should get carbon copied on email notification of requests.
+ This is a comma-separated list of full e-mail addresses which do not
+ need to be [% terms.Bugzilla %] logins.
+ [% IF Param('emailsuffix') %]
+ Note that the configured emailsuffix
+ <kbd>[% Param('emailsuffix') %]</kbd> will <em>not</em> be appended
+ to these addresses, so you should add it explicitly if so desired.
+ [% END %]<br>
+ <input type="text" name="cc_list" value="[% type.cc_list FILTER html %]" size="80"
+ maxlength="200" [%- ' disabled="disabled"' UNLESS can_fully_edit %]>
+ </td>
+ </tr>
+
+ <tr>
+ <th>&nbsp;</th>
+ <td>
+ <input type="checkbox" id="is_requesteeble" name="is_requesteeble"
+ [%- ' disabled="disabled"' UNLESS can_fully_edit %]
+ [% " checked" IF type.is_requesteeble || !type.is_requesteeble.defined %]>
+ <label for="is_requesteeble">specifically requestable (users can ask specific other users
+ to set flags of this type as opposed to just asking the wind)</label>
+ </td>
+ </tr>
+
+ <tr>
+ <th>&nbsp;</th>
+ <td>
+ <input type="checkbox" id="is_multiplicable" name="is_multiplicable"
+ [%- ' disabled="disabled"' UNLESS can_fully_edit %]
+ [% " checked" IF type.is_multiplicable || !type.is_multiplicable.defined %]>
+ <label for="is_multiplicable">multiplicable (multiple flags of this type can be set on
+ the same [% type.target_type == "bug" ? terms.bug : "attachment" %])</label>
+ </td>
+ </tr>
+
+ <tr>
+ <th>Grant Group:</th>
+ <td>
+ the group allowed to grant/deny flags of this type
+ (to allow all users to grant/deny these flags, select no group).<br>
+ [% PROCESS group_select selname = "grant_group" %]
+ </td>
+ </tr>
+
+ <tr>
+ <th>Request Group:</th>
+ <td>
+ if flags of this type are requestable, the group allowed to request them
+ (to allow all users to request these flags, select no group).<br>
+ Note that the request group alone has no effect if the grant group is not defined!<br>
+ [% PROCESS group_select selname = "request_group" %]
+ </td>
+ </tr>
+
+ <tr>
+ <th>&nbsp;</th>
+ <td>
+ <input type="submit" id="save" class="btn btn-primary" value="[% action == "insert" ? "Create" : "Save Changes" %]">
+ </td>
+ </tr>
+
+ </table>
+
+</form>
+
+[% PROCESS global/footer.html.tmpl %]
+
+
+[%############################################################################%]
+[%# Block for SELECT fields #%]
+[%############################################################################%]
+
+[% BLOCK group_select %]
+ <select name="[% selname %]" id="[% selname %]" [%- ' disabled="disabled"' UNLESS can_fully_edit %] class="form-control selectwidthauto">
+ <option value="">(no group)</option>
+ [% group_found = 0 %]
+ [% FOREACH group = groups %]
+ <option value="[% group.name FILTER html %]"
+ [% IF type.${selname} && type.${selname}.name == group.name %]
+ [% ' selected="selected"' %]
+ [% group_found = 1 %]
+ [% END %]>
+ [%- group.name FILTER html ~%]
+ </option>
+ [% END %]
+ [% IF !group_found && type.${selname}.name %]
+ <option value="[% type.${selname}.name FILTER html %]" selected="selected">
+ [%- type.${selname}.name FILTER html ~%]
+ </option>
+ [% END %]
+ </select>
+[% END %]
+
+[% BLOCK category_select %]
+ <select name="[% name FILTER html %]" multiple="multiple" size="7">
+ [% FOREACH option = categories.keys.sort %]
+ <option value="[% categories.$option FILTER html %]">
+ [% option FILTER html %]
+ </option>
+ [% END %]
+ </select>
+[% END %]
diff --git a/template/en/custom/admin/flag-type/list.html.tmpl b/template/en/custom/admin/flag-type/list.html.tmpl
new file mode 100644
index 000000000..b62f5fcba
--- /dev/null
+++ b/template/en/custom/admin/flag-type/list.html.tmpl
@@ -0,0 +1,154 @@
+[%# 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/js-products.html.tmpl" %]
+
+[% PROCESS global/header.html.tmpl
+ title = 'Administer Flag Types'
+ style_urls = ['skins/standard/admin.css']
+ onload="var f = document.flagtype_form; selectProduct(f.product, f.component, '__All__');"
+ javascript_urls=["js/productform.js"]
+ doc_section = "administering/flags.html"
+%]
+
+<p>
+ Flags are markers that identify whether [% terms.abug %] or attachment has been granted
+ or denied some status. Flags appear in the UI as a name and a status symbol
+ ("+" for granted, "-" for denied, and "?" for statuses requested by users).
+</p>
+
+<p>
+ For example, you might define a "review" status for users to request review
+ for their patches. When a patch writer requests review, the string "review?"
+ will appear in the attachment. When a patch reviewer reviews the patch,
+ either the string "review+" or the string "review-" will appear in the patch,
+ depending on whether the patch passed or failed review.
+</p>
+
+<p>
+ You can restrict the list of flag types to those available for a given product
+ and component. If a product is selected with no component, only flag types
+ which are available to at least one component of the product are shown.
+</p>
+
+<form id="flagtype_form" name="flagtype_form" action="editflagtypes.cgi" method="get">
+ <div class="inline">
+ <label for="product">Product:</label>
+ [% INCLUDE "global/product-select.html.tmpl"
+ id => "product"
+ name => "product"
+ add => "__Any__"
+ onchange => "selectProduct(this, this.form.component, '__Any__');"
+ products => products
+ %]
+ </div>
+<br/>
+ <div class="inline">
+ <label for="component">Component:</label>
+ <select name="component" class="form-control selectwidthauto">
+ <option value="">__Any__</option>
+ [% FOREACH comp = components %]
+ <option value="[% comp FILTER html %]"
+ [%+ 'selected="selected"' IF selected_component == comp %]>
+ [%- comp FILTER html %]</option>
+ [% END %]
+ </select>
+ </div>
+
+ <div class="inline">
+ <input type="checkbox" id="show_flag_counts" name="show_flag_counts" value="1"
+ [%+ 'checked="checked"' IF show_flag_counts %]>
+ <label for="show_flag_counts">Show flag counts</label>
+ </div>
+
+ <input type="submit" class="btn btn-primary" id="submit" value="Filter">
+</form>
+
+<h3>Flag Types for [% terms.Bugs %]</h3>
+
+[% PROCESS display_flag_types types=bug_types types_id='bugs' %]
+
+<p>
+ <a href="editflagtypes.cgi?action=enter&amp;target_type=bug">Create Flag Type for [% terms.Bugs %]</a>
+</p>
+
+<h3>Flag Types for Attachments</h3>
+
+[% PROCESS display_flag_types types=attachment_types types_id='attachments' %]
+
+<p>
+ <a href="editflagtypes.cgi?action=enter&amp;target_type=attachment">Create Flag Type For Attachments</a>
+</p>
+
+[% PROCESS global/footer.html.tmpl %]
+
+
+[% BLOCK display_flag_types %]
+ <table id="" class="table">
+
+ <tr class="active">
+ <th>Edit name ...</th>
+ <th>Description</th>
+ <th>Sortkey</th>
+ <th>Properties</th>
+ <th>Grant group</th>
+ <th>Request group</th>
+ [% IF show_flag_counts %]
+ <th>Flags</th>
+ [%# Note to translators: translate the strings in quotes only. %]
+ [% state_desc = {granted = 'granted' denied = 'denied' pending = 'pending'} %]
+ [% END %]
+ <th>Actions</th>
+ </tr>
+
+ [% FOREACH type = types %]
+
+ <tr class="[% IF type.is_active %]active[% ELSE %]inactive[% END %]">
+ <td class="nowrap">
+ <a href="editflagtypes.cgi?action=edit&amp;id=[% type.id %]">[% type.name FILTER html %]</a>
+ </td>
+ <td>[% type.description FILTER html %]</td>
+ <td class="right">[% type.sortkey FILTER html %]</td>
+ <td>
+ [% IF type.is_requestable %]
+ <span class="requestable">requestable</span>
+ [% END %]
+ [% IF type.is_requestable && type.is_requesteeble %]
+ <span class="requesteeble">(specifically)</span>
+ [% END %]
+ [% IF type.is_multiplicable %]
+ <span class="multiplicable">multiplicable</span>
+ [% END %]
+ </td>
+ <td>[% IF type.grant_group %][% type.grant_group.name FILTER html %][% END %]</td>
+ <td>[% IF type.request_group %][% type.request_group.name FILTER html %][% END %]</td>
+ [% IF show_flag_counts %]
+ <td>
+ [% FOREACH state = ['granted', 'pending', 'denied'] %]
+ [% bug_list = bug_lists.${type.id}.$state || [] %]
+ [% IF bug_list.size %]
+ <a href="buglist.cgi?bug_id=[% bug_list.unique.nsort.join(",") FILTER html %]">
+ [% bug_list.size FILTER html %] [%+ state_desc.$state FILTER html %]
+ </a>
+ <br>
+ [% ELSE %]
+ 0 [% state_desc.$state FILTER html %]<br>
+ [% END %]
+ [% END %]
+ </td>
+ [% END %]
+ <td>
+ <a href="editflagtypes.cgi?action=copy&amp;id=[% type.id %]">Copy</a>
+ | <a href="editflagtypes.cgi?action=confirmdelete&amp;id=[% type.id %]">Delete</a>
+ </td>
+ </tr>
+
+ [% END %]
+
+ </table>
+[% END %]
diff --git a/template/en/custom/admin/params/common.html.tmpl b/template/en/custom/admin/params/common.html.tmpl
new file mode 100644
index 000000000..64de0a4e0
--- /dev/null
+++ b/template/en/custom/admin/params/common.html.tmpl
@@ -0,0 +1,126 @@
+[%# 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.
+ #%]
+
+[% sortlist_separator = '---' %]
+
+
+[% FOREACH param = panel.param_list %]
+<div class="panel panel-default">
+ <div class="panel-heading" id="[% param.name FILTER html %]_desc"><b>[% param.name FILTER html %]</b></div>
+ <div class="panel-body">[% panel.param_descs.${param.name} FILTER none %]
+ <p>
+ [% IF param.type == "t" %]
+ <input type="text" size="80" name="[% param.name FILTER html %]"
+ id="[% param.name FILTER html %]" value="[% Param(param.name) FILTER html %]">
+ [% ELSIF param.type == "p" %]
+ <input type="password" size="80" name="[% param.name FILTER html %]"
+ id="[% param.name FILTER html %]" value="[% Param(param.name) FILTER html %]"
+ autocomplete="off">
+ [% ELSIF param.type == "l" %]
+ <textarea name="[% param.name FILTER html %]" id="[% param.name FILTER html %]"
+ rows="10" cols="80">[% Param(param.name) FILTER html %]</textarea>
+ [% ELSIF param.type == "b" %]
+ <input type="radio" name="[% param.name FILTER html %]" id="[% param.name FILTER html %]-on"
+ value=1 [% "checked=\"checked\"" IF Param(param.name) %]>
+ <label for="[% param.name FILTER html %]-on">On</label>
+ <input type="radio" name="[% param.name FILTER html %]" id="[% param.name FILTER html %]-off"
+ value=0 [% "checked=\"checked\"" IF !Param(param.name) %]>
+ <label for="[% param.name FILTER html %]-off">Off</label>
+ [% ELSIF param.type == "m" %]
+ [% boxSize = 5 %]
+ [% SET boxSize = param.choices.size IF param.choices.size < 5 %]
+
+ <select multiple="multiple" size="[% boxSize FILTER html %]"
+ name="[% param.name FILTER html %]" id="[% param.name FILTER html %]">
+ [% FOREACH item = param.choices %]
+ <option value="[% item FILTER html %]"
+ [% " selected=\"selected\"" IF lsearch(Param(param.name), item) != -1 %]>
+ [% item FILTER html %]
+ </option>
+ [% END %]
+ </select>
+ [% ELSIF param.type == "o" %]
+ <input id="input_[% param.name FILTER html %]" size="80"
+ name="[% param.name FILTER html %]"
+ value="[% Param(param.name) FILTER html %]"><br>
+ [% boxSize = 7 %]
+ [% SET boxSize = 3 + param.choices.size IF param.choices.size < 7 %]
+ [% plist = Param(param.name).split(',') %]
+
+ <table id="table_[% param.name FILTER html %]" class="bz_default_hidden">
+ <tr>
+ <td rowspan="2">
+ <select id="select_[% param.name FILTER html %]"
+ name="select_[% param.name FILTER html %]"
+ size="[% boxSize FILTER html %]">
+ [% FOREACH item = plist %]
+ <option value="[% item FILTER html %]">[% item FILTER html %]</option>
+ [% END %]
+ <option class="sortlist_separator" disabled="disabled"
+ value="[% sortlist_separator %]">active&uarr;&nbsp;&darr;inactive</option>
+ [% FOREACH item = param.choices %]
+ [% IF lsearch(plist, item) == -1 %]
+ <option value="[% item FILTER html %]">[% item FILTER html %]</option>
+ [% END %]
+ [% END %]
+ </select>
+ </td>
+ <td class="bottom">
+ <button type="button"
+ onClick="sortedList_moveItem('[% param.name FILTER html %]', -1, '[% sortlist_separator %]');">&uarr;</button>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="top">
+ <button type="button"
+ onClick="sortedList_moveItem('[% param.name FILTER html %]', +1, '[% sortlist_separator %]');">&darr;</button>
+ </td>
+ </tr>
+ </table>
+
+ <script type="text/javascript">
+ bz_toggleClass("input_[% param.name FILTER html %]", "bz_default_hidden");
+ bz_toggleClass("table_[% param.name FILTER html %]", "bz_default_hidden");
+ </script>
+ [% ELSIF param.type == "s" %]
+ <select name="[% param.name FILTER html %]" id="[% param.name FILTER html %]">
+ [% FOREACH item = param.choices %]
+ <option value="[% item FILTER html %]"
+ [% " selected=\"selected\"" IF item == Param(param.name) %]>
+ [% IF param.name == "defaultseverity" %]
+ [% display_value("bug_severity", item) FILTER html %]
+ [% ELSIF param.name == "defaultplatform" %]
+ [% display_value("rep_platform", item) FILTER html %]
+ [% ELSIF param.name == "defaultopsys" %]
+ [% display_value("op_sys", item) FILTER html %]
+ [% ELSIF param.name == "duplicate_or_move_bug_status" %]
+ [% display_value("bug_status", item) FILTER html %]
+ [% ELSE %]
+ [% item FILTER html %]
+ [% END %]
+ </option>
+ [% END %]
+ </select>
+ [% ELSE %]
+ <span class="warning">
+ Unknown param type [% param.type FILTER html %]!!!
+ </span>
+ [% END %]
+ </p>
+ [% UNLESS param.no_reset %]
+ <p>
+ <input type="checkbox" name="reset-[% param.name FILTER html %]"
+ id="reset-[% param.name FILTER html %]">
+ <label for="reset-[% param.name FILTER html %]">Reset</label>
+ </p>
+ [% END %]
+ </div>
+</div>
+
+[% END %]
diff --git a/template/en/custom/admin/params/editparams.html.tmpl b/template/en/custom/admin/params/editparams.html.tmpl
new file mode 100644
index 000000000..4a60069df
--- /dev/null
+++ b/template/en/custom/admin/params/editparams.html.tmpl
@@ -0,0 +1,92 @@
+[%# 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.
+ #%]
+
+[% curpanel = -1 %]
+[% panels = panels.nsort('sortkey') %]
+
+[% FOREACH panel = panels %]
+ [% PROCESS "admin/params/${panel.name}.html.tmpl"
+ params = panel.param_list %]
+ [% panel.title = title %]
+ [% panel.desc = desc %]
+ [% panel.param_descs = param_descs %]
+ [% IF panel.current %][% curpanel = loop.index %][% END %]
+[% END %]
+
+[% current_panel = panels.$curpanel %]
+
+[%# We cannot call header.html.tmpl earlier as we have to know
+ which panel is active first, in order to get its title %]
+
+[% title = BLOCK %]
+ [% IF curpanel == -1 %]
+ Parameters: Index
+ [% ELSE %]
+ Configuration:
+ [%+ current_panel.title FILTER html %]
+ [% END %]
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ message = message
+ style_urls = ['skins/standard/admin.css']
+ javascript_urls = ['js/params.js', 'js/util.js']
+ doc_section = "administering/parameters.html"
+%]
+
+<div class="row">
+ <div class="col-sm-2">
+ [%# NAVIGATION BAR %]
+ <div class="list-group">
+ <a href="editparams.cgi?section=index" class="list-group-item list-group-item-info" title="Show all parameters">Index</a>
+
+ [% FOREACH panel = panels %]
+ [% IF panel.current %]
+ [% Hook.process("current_panel") %]
+ <a href="#" class="list-group-item active" title="[% panel.desc FILTER html %]">[% panel.title FILTER html %]</a>
+ [% ELSE %]
+ <a href="editparams.cgi?section=[% panel.name FILTER uri %]"
+ class="list-group-item" title="[% panel.desc FILTER html %]">[% panel.title FILTER html %]</a>
+ [% END %]
+ [% END %]
+ </div>
+ </div>
+
+ <div class="col-sm-10">
+ <div id="contribute" class="well">
+ <strong>Note:</strong>
+ Bugzilla is developed entirely by volunteers.
+ The best way to give back to the Bugzilla project is to
+ <a href="http://www.bugzilla.org/contribute/">contribute</a> yourself!
+ You don't have to be a programmer to contribute, there are lots of
+ things that we need.
+ </div>
+
+ [% IF curpanel == -1 %]
+ [% PROCESS admin/params/index.html.tmpl panels = panels %]
+ [% ELSE %]
+ <div class="well">
+ This lets you edit the basic operating parameters of Bugzilla.
+ Be careful!<br>
+ Any item you check "Reset" on will get reset to its default value.
+ </div>
+
+ [%# CONTENT PANEL %]
+ <form id="edit_params" method="post" action="editparams.cgi">
+ [% PROCESS admin/params/common.html.tmpl panel = current_panel %]
+ <input type="hidden" name="section" value="[% current_panel.name FILTER html %]">
+ <input type="hidden" name="action" value="save">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ <input type="submit" class="btn btn-primary" id="save-params" value="Save Changes">
+ </form>
+ [% END %]
+ </div>
+</div>
+
+[% INCLUDE global/footer.html.tmpl %]
diff --git a/template/en/custom/admin/products/confirm-delete.html.tmpl b/template/en/custom/admin/products/confirm-delete.html.tmpl
new file mode 100644
index 000000000..d3de087fd
--- /dev/null
+++ b/template/en/custom/admin/products/confirm-delete.html.tmpl
@@ -0,0 +1,241 @@
+[%# 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:
+ # product: Bugzilla::Product object; The product
+ #
+ # (classification fields available if Param('useclassification') is enabled:)
+ #
+ # classification: Bugzilla::Classification object; The classification
+ # the product is in
+ #
+ #%]
+
+[% title = BLOCK %]Delete Product '[% product.name FILTER html %]'
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ style_urls = ['skins/standard/admin.css']
+%]
+
+<table id="" class="table">
+ <tr class="active">
+ <th>Field</th>
+ <th>Value</th>
+ </tr>
+
+ [% IF Param('useclassification') %]
+ <tr>
+ <td>Classification</td>
+ <td>[% classification.name FILTER html %]</td>
+ </tr>
+ <tr>
+ <td>Classification Description</td>
+ <td>
+ [% IF classification.description %]
+ [% classification.description FILTER html_light %]
+ [% ELSE %]
+ <span class="warning">missing</span>
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+
+ <tr>
+ <td>Product</td>
+ <td>
+ <a href="editproducts.cgi?product=[% product.name FILTER uri %]">
+ [% product.name FILTER html %]
+ </a>
+ </td>
+ </tr>
+ <tr>
+ <td>Description</td>
+ <td>[% product.description FILTER html_light %]</td>
+ </tr>
+
+ [% IF Param('usetargetmilestone') %]
+ <tr>
+ <td>Milestone URL</td>
+ <td>
+ [% IF product.milestone_url %]
+ <a href="[% product.milestone_url FILTER html %]">
+ [%- product.milestone_url FILTER html %]
+ </a>
+ [% ELSE %]
+ none
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+
+ <tr>
+ <td>Closed for [% terms.bugs %]</td>
+ <td>
+ [% IF product.is_active %]
+ open
+ [% ELSE %]
+ closed
+ [% END %]
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ [% IF product.components.size > 0 %]
+ <a href="editcomponents.cgi?product=[% product.name FILTER uri %]"
+ title="Edit components for product '[% product.name FILTER html %]'">
+ Components
+ </a>
+ [% ELSE %]
+ Components
+ [% END %]
+ </td>
+ <td>
+ [% IF product.components.size > 0 %]
+ <table class="no-border">
+ [% FOREACH c = product.components %]
+ <tr>
+ <th>[% c.name FILTER html %]:</th>
+ <td>[% c.description FILTER html_light %]</td>
+ </tr>
+ [% END %]
+ </table>
+ [% ELSE %]
+ none
+ [% END %]
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ [% IF product.versions.size > 0 %]
+ <a href="editversions.cgi?product=[%- product.name FILTER uri %]">
+ Versions
+ </a>
+ [% ELSE %]
+ Versions
+ [% END %]
+ </td>
+ <td>
+ [% IF product.versions.size > 0 %]
+ <div class="multi-columns">
+ [% FOREACH v = product.versions %]
+ [% v.name FILTER html %]<br>
+ [% END %]
+ </div>
+ [% ELSE %]
+ none
+ [% END %]
+ </td>
+ </tr>
+
+
+ [% IF Param('usetargetmilestone') %]
+ <tr>
+ <td>
+ [% IF product.milestones.size > 0 %]
+ <a href="editmilestones.cgi?product=[%- product.name FILTER uri %]">
+ Milestones
+ </a>
+ [% ELSE %]
+ Milestones
+ [% END %]
+ </td>
+ <td>
+ [% IF product.milestones.size > 0 %]
+ <div class="multi-columns">
+ [% FOREACH m = product.milestones %]
+ [% m.name FILTER html %]<br>
+ [% END %]
+ </div>
+ [% ELSE %]
+ none
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+
+ <tr>
+ <td>[% terms.Bugs %]</td>
+ <td>
+ [% IF product.bug_count %]
+ <a href="buglist.cgi?product=[% product.name FILTER uri %]"
+ title="List of [% terms.bugs %] for product '[% product.name FILTER html %]'">
+ [% product.bug_count FILTER html %]
+ </a>
+ [% ELSE %]
+ none
+ [% END %]
+ </td>
+ </tr>
+</table>
+
+<h2>Confirmation</h2>
+
+[% IF product.bug_count %]
+
+ [% IF !Param("allowbugdeletion") %]
+
+ <div class="alert alert-danger">
+ Sorry, there
+ [% IF product.bug_count > 1 %]
+ are [% product.bug_count FILTER html %] [%+ terms.bugs %]
+ [% ELSE %]
+ is 1 [% terms.bug %]
+ [% END %]
+ outstanding for this product. You must reassign
+ [% IF product.bug_count > 1 %]
+ those [% terms.bugs %]
+ [% ELSE %]
+ that [% terms.bug %]
+ [% END %]
+ to another product before you can delete this one.
+ </div>
+
+ [% ELSE %]
+
+ <div class="alert alert-danger">
+ There
+ [% IF product.bug_count > 1 %]
+ are [% product.bug_count FILTER html %] [%+ terms.bugs %]
+ [% ELSE %]
+ is 1 [% terms.bug %]
+ [% END %]
+ entered for this product! When you delete this product, <b>ALL</b>
+ stored [% terms.bugs %] and their history will be deleted, too.
+ </div>
+
+ [% END %]
+
+[% END %]
+
+[% Hook.process("confirmation") %]
+
+[% IF product.bug_count == 0 || Param('allowbugdeletion') %]
+
+ <p>Do you really want to delete this product?</p>
+
+ <form method="post" action="editproducts.cgi">
+ <input type="checkbox" id="delete_series" name="delete_series" value=1>
+ <label for="delete_series">
+ Delete all related series (you can also delete them later, by visiting
+ the <a href="chart.cgi?category=[% product.name FILTER html %]">New Charts page</a>.)
+ </label><p>
+ <input type="submit" id="delete" value="Yes, delete">
+ <input type="hidden" name="action" value="delete">
+ <input type="hidden" name="product" value="[% product.name FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ </form>
+
+[% END %]
+
+[% PROCESS admin/products/footer.html.tmpl %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/custom/admin/products/create.html.tmpl b/template/en/custom/admin/products/create.html.tmpl
new file mode 100644
index 000000000..4104f2428
--- /dev/null
+++ b/template/en/custom/admin/products/create.html.tmpl
@@ -0,0 +1,75 @@
+[%# 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:
+ # classification: Bugzilla::Classification object; If classifications
+ # are enabled, then this is
+ # the currently selected classification
+ #
+ #%]
+
+[% title = BLOCK %]Add Product[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ generate_api_token = 1
+ style_urls = ['skins/standard/admin.css']
+ javascript_urls = ['js/util.js', 'js/field.js']
+ yui = [ 'autocomplete' ]
+%]
+
+[% DEFAULT
+ product.is_active = 1,
+ version = "unspecified",
+ product.defaultmilestone = constants.DEFAULT_MILESTONE
+ product.allows_unconfirmed = 1
+%]
+
+<form method="post" action="editproducts.cgi">
+ <table id="admin_table_edit">
+
+ [% PROCESS "admin/products/edit-common.html.tmpl" %]
+
+ <tr>
+ <th>Version:</th>
+ <td><input size="20" maxlength="64" name="version"
+ value="[% version FILTER html %]" required>
+ </td>
+ </tr>
+ <tr>
+ <th>Create chart datasets for this product:</th>
+ <td>
+ <input type="checkbox" name="createseries" value="1" checked="checked">
+ </td>
+ </tr>
+
+ <tr>
+ <td colspan="2">&nbsp;</td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ This product must have at least one component.
+ You will be able to create additional components later:
+ </td>
+ </tr>
+
+ [% PROCESS "admin/components/edit-common.html.tmpl" desc_name = "comp_desc" %]
+ </table>
+
+ <input type="submit" class="btn btn-primary" id="add-product" value="Add">
+ <input type="hidden" name="action" value="new">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ <input type="hidden" name="classification"
+ value="[% classification.name FILTER html %]">
+</form>
+
+[% PROCESS "admin/products/footer.html.tmpl"
+ no_add_product_link = 1
+ no_edit_product_link = 1 %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/custom/admin/products/edit.html.tmpl b/template/en/custom/admin/products/edit.html.tmpl
new file mode 100644
index 000000000..c83479596
--- /dev/null
+++ b/template/en/custom/admin/products/edit.html.tmpl
@@ -0,0 +1,141 @@
+[%# 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:
+ # product: Bugzilla::Product object; The product
+ #
+ # (classification fields available if Param('useclassification') is enabled:)
+ #
+ # classification: Bugzilla::Classification object; The classification
+ # the product is in
+ #%]
+
+[% title = BLOCK %]Edit Product '[% product.name FILTER html %]'[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ style_urls = ['skins/standard/admin.css']
+ javascript_urls = ['js/util.js']
+%]
+
+[% group_control = {${constants.CONTROLMAPNA} => 'NA',
+ ${constants.CONTROLMAPSHOWN} => 'Shown',
+ ${constants.CONTROLMAPDEFAULT} => 'Default',
+ ${constants.CONTROLMAPMANDATORY} => 'Mandatory'}
+ %]
+
+<form method="post" action="editproducts.cgi">
+ <table id="admin_table_edit">
+
+ [% PROCESS "admin/products/edit-common.html.tmpl" %]
+
+ <tr>
+ <th>
+ <a href="editcomponents.cgi?product=[% product.name FILTER uri %]">
+ Edit components:
+ </a>
+ </th>
+ <td>
+ [% IF product.components.size -%]
+ [% FOREACH comp = product.components %]
+ <a href="editcomponents.cgi?action=edit&product=
+ [%- product.name FILTER uri %]&component=
+ [%- comp.name FILTER uri %]">[% comp.name FILTER html %]</a>:
+ [% comp.description FILTER html_light %]
+ <br>
+ [% END %]
+ [% ELSE %]
+ <span class="warning">missing</span>
+ [% END %]
+ </td>
+ </tr>
+ <tr>
+ <th>
+ <a href="editversions.cgi?product=[% product.name FILTER uri %]">Edit versions:</a>
+ </th>
+ <td>
+ [%- IF product.versions.size -%]
+ <div class="multi-columns">
+ [% FOREACH v = product.versions %]
+ [% v.name FILTER html %]<br>
+ [% END %]
+ </div>
+ [% ELSE %]
+ <span class="warning">missing</span>
+ [% END %]
+ </td>
+ </tr>
+ [% IF Param('usetargetmilestone') %]
+ <tr>
+ <th>
+ <a href="editmilestones.cgi?product=[% product.name FILTER uri %]">
+ Edit milestones:</a>
+ </th>
+ <td>
+ [%- IF product.milestones.size -%]
+ <div class="multi-columns">
+ [%- FOREACH m = product.milestones -%]
+ [% m.name FILTER html %]<br>
+ [% END %]
+ </div>
+ [% ELSE %]
+ <span class="warning">missing</span>
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+ <tr>
+ <th>
+ <a href="editproducts.cgi?action=editgroupcontrols&product=
+ [%- product.name FILTER uri %]">
+ Edit Group Access Controls:
+ </a>
+ </th>
+ <td>
+ [% IF product.group_controls.size %]
+ [% FOREACH g = product.group_controls.values.sort("name") %]
+ <b>[% g.group.name FILTER html %]:</b>
+ [% IF g.group.isactive %]
+ [% group_control.${g.membercontrol} FILTER html %]/
+ [% group_control.${g.othercontrol} FILTER html %]
+ [% IF g.entry %], ENTRY[% END %]
+ [% IF g.canedit %], CANEDIT[% END %]
+ [% IF g.editcomponents %], editcomponents[% END %]
+ [% IF g.canconfirm %], canconfirm[% END %]
+ [% IF g.editbugs %], editbugs[% END %]
+ [% ELSE %]
+ DISABLED
+ [% END %]
+ <br>
+ [% END %]
+ [% ELSE %]
+ no groups
+ [% END %]
+ </td>
+ </tr>
+ <tr>
+ <th>[% terms.Bugs %]:</th>
+ <td>
+ <a href="buglist.cgi?product=[% product.name FILTER uri %]">
+ [% product.bug_count FILTER html %]</a>
+ </td>
+ </tr>
+ </table>
+
+ <input type="hidden" name="product_old_name"
+ value="[% product.name FILTER html %]">
+ <input type="hidden" name="action" value="update">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ <input type="submit" class="btn btn-primary" id="update-product" value="Save Changes">
+</form>
+
+[% PROCESS "admin/products/footer.html.tmpl"
+ no_add_product_link = 1
+ no_edit_product_link = 1 %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/custom/admin/settings/edit.html.tmpl b/template/en/custom/admin/settings/edit.html.tmpl
new file mode 100644
index 000000000..a7a9a65f6
--- /dev/null
+++ b/template/en/custom/admin/settings/edit.html.tmpl
@@ -0,0 +1,80 @@
+[%# 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:
+ # settings: a hash of hashes, keyed by setting name.
+ # Each hash contains:
+ # is_enabled - boolean
+ # default_value - string (global default for this setting)
+ # value - string (user-defined preference)
+ # is_default - boolean (true if user has no preference)
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Default Preferences"
+ style_urls = ['skins/standard/admin.css']
+%]
+
+[% PROCESS "global/setting-descs.none.tmpl" %]
+
+<p>
+ This lets you edit the default preferences values. The Default Value displayed
+ for each preference will apply to all users who do not choose their own value,
+ and to anyone who is not logged in.
+</p>
+
+<div>
+ The 'Enabled' checkbox controls whether or not this preference is available to users:
+ <ul>
+ <li>If it is checked, users will be allowed to choose their own value if they desire.</li>
+ <li>If it is not checked, the Default Value will automatically apply to everyone.</li>
+ </ul>
+</div>
+
+ <form id="settings" method="post" action="editsettings.cgi">
+ <div class="panel panel-default">
+ <table class="table">
+ <tr class="active">
+ <th style="text-align:left;">Preference Text</th>
+ <th style="text-align:left;">Default Value</th>
+ <th style="text-align:left;">Enabled</th>
+ </tr>
+
+ [% FOREACH name = settings.keys.sort %]
+ [% checkbox_name = name _ '-enabled' %]
+ <tr>
+ <td>
+ [% setting_descs.$name OR name FILTER html %]
+ </td>
+ <td>
+ <select name="[% name FILTER html %]" id="[% name FILTER html %]" class="form-control">
+ [% FOREACH x = settings.${name}.legal_values %]
+ <option value="[% x FILTER html %]"
+ [% " selected=\"selected\"" IF x == settings.${name}.default_value %]>
+ [% setting_descs.${x} OR x FILTER html %]
+ </option>
+ [% END %]
+ </select>
+ </td>
+ <td class="center">
+ <input type="checkbox"
+ name="[% checkbox_name FILTER html %]"
+ id="[% checkbox_name FILTER html %]"
+ [% " checked=\"checked\"" IF settings.${name}.is_enabled %]>
+ </td>
+ </tr>
+ [% END %]
+ </table>
+ </div>
+
+ <input type="hidden" name="action" value="update">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ <input type="submit" class="btn btn-primary" id="update" value="Submit Changes">
+ </form>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/custom/admin/table.html.tmpl b/template/en/custom/admin/table.html.tmpl
new file mode 100644
index 000000000..32bae7ede
--- /dev/null
+++ b/template/en/custom/admin/table.html.tmpl
@@ -0,0 +1,160 @@
+[%# 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:
+ #
+ # columns:
+ # array of hashes representing the columns in the table.
+ # Each hash contains data for a single column. Hash keys:
+ # name: Name of the field in the data param
+ # heading: The text to print at the header cell
+ # contentlink: URI to which the content of a data cell shall be linked to.
+ # Expressions of format %%xxx%% are replaced with value
+ # with the key xxx in data hash of the current row.
+ # content: If specified, the content of this variable is used
+ # instead of the data pulled from the current row.
+ # NOTE: This value is only partially HTML filtered!
+ # content_use_field: If defined and true, then each value in the
+ # column corresponds with a key in the
+ # field_descs field, and that value from the
+ # field_descs hash will be used instead of "content."
+ # See fieldvalues/select-field for an example of use.
+ # This content WILL be HTML-filtered in this case.
+ # allow_html_content: if defined, then this column allows some html content
+ # and so it will be only partially filtered.
+ # yesno_field: Turn the data from 0/!0 into Yes/No
+ #
+ # data:
+ # array of hashes representing the data for the table.
+ # Each hash contains data for a single row of data. The
+ # keys are column names from columns subhashes name field.
+ #
+ # overrides:
+ # Example:
+ # overrides { # first hash
+ # column_name_to_be_overwriten => { # second hash
+ # name_of_row_to_match_against => { # third hash
+ # value_to_match_against => { # fourth hash
+ # content => "some contents"
+ # override_content => 1
+ # }
+ # }
+ # }
+ # }
+ #
+ # Provides a method for overriding individual table cells. This is a hash
+ # (1), whose key is the column name, so the column must be named for
+ # one of it's cells to be overwritten. The hash value is another hash
+ # (2). The keys of that second hash are the name of the row to match
+ # against. The second hash then again points to another hash. Within this
+ # third hash (3), the keys represent values to match against. The item
+ # contains a fourth hash (4) specifying overridden values.
+ #
+ # Each column value mentioned in the 'columns' documentation above
+ # can be overwritten (apart from name and heading). To override a
+ # table-cell value 'xxx', specify a new 'xxx' value, and specify a
+ # 'override_xxx' value as well. See
+ # admin/milestones/list.html.tmpl for example
+ #
+ #%]
+
+[%################### TABLE HEADER ######################%]
+
+<table id="" class="table">
+ <tr class="active">
+ [% FOREACH c = columns %]
+ [%# Default to align left for headers %]
+ <th class="[% (c.class || 'left') FILTER css_class_quote %]">
+ [% c.heading FILTER html %]
+ </th>
+ [% END %]
+ </tr>
+
+
+[%################### TABLE CONTENT ######################%]
+
+[% FOREACH row = data %]
+
+ <tr>
+ [% FOREACH c = columns %]
+
+ [%# Copy to local variables, as we may update these %]
+ [% contentlink = c.contentlink
+ content = c.content
+ content_use_field = c.content_use_field
+ class = c.class
+ allow_html_content = c.allow_html_content
+ yesno_field = c.yesno_field
+ %]
+
+ [%# Get any specific "important" overrides for this c.name and row.name ? %]
+ [% SET important = overrides.${c.name}.name.${row.name} %]
+
+ [% IF important %]
+
+ [% FOREACH key IN important.keys %]
+ [% SET ${key} = important.${key} %]
+ [% END %]
+
+ [% ELSE %]
+
+ [%# Are there any specific overrides for this column? %]
+ [% FOREACH match_field = overrides.${c.name}.keys %]
+
+ [% override = overrides.${c.name}.${match_field}.${row.$match_field} %]
+ [% NEXT UNLESS override %]
+
+ [% FOREACH key IN override.keys %]
+ [% SET ${key} = override.${key} %]
+ [% END %]
+
+ [% LAST %]
+
+ [% END %]
+ [% END %]
+
+ <td [% IF class %] class="[% class FILTER html %]"[% END %]>
+
+ [% IF contentlink %]
+ [% FOREACH m = contentlink.match('%%(.+?)%%', 1) %]
+ [% replacement_value = FILTER uri; row.$m; END %]
+ [% contentlink = contentlink.replace("%%$m%%", replacement_value) %]
+ [% END %]
+ <a href="[% contentlink %]">
+ [% END %]
+
+ [% IF content_use_field %]
+ [% colname = row.${c.name} %]
+ [% field_descs.${colname} FILTER html %]
+ [% ELSIF content %]
+ [% content FILTER html_light %]
+ [% ELSIF yesno_field %]
+ [% row.${c.name} ? "Yes" : "No" %]
+ [% ELSIF allow_html_content %]
+ [% row.${c.name} FILTER html_light %]
+ [% ELSE %]
+ [% row.${c.name} FILTER html %]
+ [% END %]
+
+ [% IF contentlink %]
+ </a>
+ [% END %]
+
+ </td>
+ [% END %]
+ </tr>
+[% END %]
+
+[% IF data.size == 0 %]
+ <tr><td colspan="[% columns.size %]" class="center"><i>&lt;none&gt;</i></td></tr>
+[% END %]
+
+
+[%################### TABLE FOOTER ######################%]
+
+</table>
diff --git a/template/en/custom/admin/users/create.html.tmpl b/template/en/custom/admin/users/create.html.tmpl
new file mode 100644
index 000000000..46abe3733
--- /dev/null
+++ b/template/en/custom/admin/users/create.html.tmpl
@@ -0,0 +1,50 @@
+[%# 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:
+ #
+ # listselectionvalues: selection values to recreate the current user list.
+ # editusers: is viewing user member of editusers?
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Add user"
+ style_urls = ['skins/standard/admin.css']
+ doc_section = "administering/users.html#creating-new-users"
+%]
+
+[% PROCESS admin/users/listselectvars.html.tmpl
+ listselectionvalues = listselectionvalues
+%]
+
+<form method="post" action="editusers.cgi">
+ <table id="admin_table_edit">
+ [% PROCESS admin/users/userdata.html.tmpl
+ editform = 0
+ editusers = editusers
+ otheruser = []
+ %]
+ </table>
+ <p>
+ <input type="submit" class="btn btn-primary" id="add" value="Add">
+ <input type="hidden" name="action" value="new">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ [% INCLUDE listselectionhiddenfields %]
+ </p>
+</form>
+
+<p>
+ You can also <a href="editusers.cgi">find a user</a>
+ [% IF listselectionvalues %],
+ or
+ <a href="editusers.cgi?action=list[% INCLUDE listselectionurlparams %]">go
+ back to the user list</a>
+ [% END %].
+</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/custom/admin/users/edit.html.tmpl b/template/en/custom/admin/users/edit.html.tmpl
new file mode 100644
index 000000000..b4a4ce866
--- /dev/null
+++ b/template/en/custom/admin/users/edit.html.tmpl
@@ -0,0 +1,176 @@
+[%# 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:
+ #
+ # message: message tag specifying a global/messages.html.tmpl
+ # message
+ # listselectionvalues: selection values to recreate the current user list.
+ # editusers: is viewing user member of editusers?
+ # otheruser: Bugzilla::User object of viewed user.
+ # groups: array of group information (name, grant type,
+ # canbless) for viewed user.
+ #%]
+
+[% title = BLOCK %]Edit user [% otheruser.identity FILTER html %][% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ message = message
+ style_urls = ['skins/standard/admin.css']
+ doc_section = "administering/users.html#modifying-users"
+ javascript_urls = [ 'js/field.js' ]
+%]
+
+[% PROCESS admin/users/listselectvars.html.tmpl
+ listselectionvalues = listselectionvalues
+%]
+
+<form method="post" action="editusers.cgi">
+<table id="admin_table_edit">
+ [% PROCESS admin/users/userdata.html.tmpl
+ editform = 1
+ editusers = editusers
+ otheruser = otheruser
+ %]
+ [% IF groups.size %]
+ <tr>
+ <th>Group access:</th>
+ <td>
+ <table id="group_membership">
+ <tr>
+ [% IF editusers %]
+ <th colspan="3">
+ Can turn these bits on for other users
+ </th>
+ [% END %]
+ </tr>
+ <tr>
+ [% IF editusers %]
+ <th class="checkbox">|</th>
+ [% END %]
+ <th colspan="2">User is a member of these groups</th>
+ </tr>
+ [% FOREACH group = groups %]
+ [% perms = permissions.${group.id} %]
+ <tr class="[% 'in' IF perms.regexpmember || perms.derivedmember %]direct">
+ [% IF editusers %]
+ <td class="checkbox">
+ [% '[' IF perms.indirectbless %]
+ [% %]<input type="checkbox"
+ name="bless_[% group.id %]"
+ value="1"
+ [% ' checked="checked"' IF perms.directbless %]>
+ [% ']' IF perms.indirectbless %]</td>
+ [% END %]
+ <td class="checkbox">
+ [% '[' IF perms.derivedmember %]
+ [% '*' IF perms.regexpmember %]
+ [%%]<input type="checkbox"
+ id="group_[% group.id %]"
+ name="group_[% group.id %]"
+ value="1"
+ [% ' checked="checked"' IF perms.directmember %]>
+ [% '*' IF perms.regexpmember %]
+ [% ']' IF perms.derivedmember %]</td>
+ <td class="groupname">
+ <label for="group_[% group.id %]">
+ <strong>[% group.name FILTER html %]:</strong>
+ [%+ group.description FILTER html_light %]
+ </label>
+ </td>
+ </tr>
+ [% END %]
+ </table>
+ </td>
+ </tr>
+ [% END %]
+
+ <tr>
+ <th>Product responsibilities:</th>
+ <td>
+ [% IF otheruser.product_responsibilities.size %]
+ [% PROCESS admin/users/responsibilities.html.tmpl otheruser = otheruser %]
+ [% ELSE %]
+ <em>none</em>
+ [% END %]
+ </td>
+ </tr>
+
+ <tr>
+ <th>Last Login:</th>
+ <td>
+ [% IF otheruser.last_seen_date %]
+ [% otheruser.last_seen_date FILTER html %]
+ [% ELSE %]
+ <em>never</em>
+ [% END %]
+ </td>
+ </tr>
+</table>
+
+<p>
+ <input type="submit" class="btn btn-primary" id="update" value="Save Changes">
+ <input type="hidden" name="userid" value="[% otheruser.id %]">
+ <input type="hidden" name="action" value="update">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ [% INCLUDE listselectionhiddenfields %]
+
+ or <a href="editusers.cgi?action=activity&amp;userid=[% otheruser.id %]"
+ title="View Account History for '
+ [%- otheruser.login FILTER html %]'">View Account History</a> / <a
+ href="custom_userhistory.cgi?userid=[%- otheruser.id FILTER html %]"
+ title="Custom Account History for '[%- otheruser.login FILTER html
+ %]'">Custom Account History</a>
+</p>
+</form>
+<p>
+ User is a member of all groups shown with a check or grey bar.
+ A grey bar indicates indirect membership, either derived from other
+ groups (marked with square brackets) or via regular expression
+ (marked with '*').
+</p>
+[% IF editusers %]
+ <p>
+ Square brackets around the bless checkbox indicate the ability
+ to bless users (grant them membership in the group) as a result
+ of membership in another group.
+ </p>
+[% END %]
+
+[% IF Param('allowuserdeletion') && editusers %]
+ <form method="post" action="editusers.cgi">
+ <p>
+ <input type="submit" id="delete" value="Delete User">
+ <input type="hidden" name="action" value="del">
+ <input type="hidden" name="userid" value="[% otheruser.id %]">
+ [% INCLUDE listselectionhiddenfields %]
+ </p>
+ </form>
+[% END %]
+
+<p>
+ You can also
+ [% IF editusers %]
+ <a href="editusers.cgi?action=add[% INCLUDE listselectionurlparams %]">add
+ a new user</a>
+ [% IF listselectionvalues %],
+ [% END %]
+ [% END %]
+ [% IF listselectionvalues.matchtype != 'exact' %]
+ go
+ <a href="editusers.cgi?action=list[% INCLUDE listselectionurlparams %]">back
+ to the user list</a>,
+ [% END %]
+ [% IF editusers OR listselectionvalues %]
+ or
+ [% END %]
+ <a href="editusers.cgi">find other users</a>.
+</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/custom/admin/users/search.html.tmpl b/template/en/custom/admin/users/search.html.tmpl
new file mode 100644
index 000000000..39b8da0b7
--- /dev/null
+++ b/template/en/custom/admin/users/search.html.tmpl
@@ -0,0 +1,83 @@
+[%# 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:
+ #
+ # editusers: is viewing user member of editusers?
+ # restrictablegroups: list of groups visible to the user:
+ # id: group id
+ # name: group name
+ #%]
+
+
+[% PROCESS global/header.html.tmpl
+ title = "Search users"
+ style_urls = ['skins/standard/admin.css']
+ doc_section = "administering/users.html"
+%]
+
+[% PROCESS admin/users/listselectvars.html.tmpl
+ listselectionvalues = listselectionvalues
+%]
+
+<form name="f" method="get" action="editusers.cgi">
+<input type="hidden" name="action" value="list">
+<p><label for="matchvalue">List users with</label>
+<select id="matchvalue" name="matchvalue" class="form-control selectwidthauto">
+ <option value="login_name">login name</option>
+ <option value="realname">real name</option>
+ <option value="userid">user id</option>
+</select>
+<label for="matchstr">matching</label>
+<input size="32" name="matchstr" id="matchstr" autofocus>
+<select name="matchtype" class="form-control selectwidthauto">
+ <option value="substr" selected="selected">case-insensitive substring</option>
+ <option value="regexp">case-insensitive regexp</option>
+ <option value="notregexp">not (case-insensitive regexp)</option>
+ <option value="exact">exact (find this user)</option>
+</select>
+<input type="submit" class="btn btn-primary" id="search" value="Search">
+</p>
+
+[% IF restrictablegroups.size %]
+ <p><input type="checkbox" name="grouprestrict" value="1" id="grouprestrict">
+ <label for="grouprestrict">Restrict to users belonging to group</label>
+ <select name="groupid"
+ onchange="document.forms['f'].grouprestrict.checked=true" class="form-control selectwidthauto">
+ [% FOREACH group = restrictablegroups %]
+ <option value="[% group.id FILTER html %]">[% group.name FILTER html %]</option>
+ [% END %]
+ </select></p>
+[% END %]
+
+<p>
+ Restrict search to
+ <select name="is_enabled" class="form-control selectwidthauto">
+ <option value="2">All</option>
+ <option value="1" selected>Enabled</option>
+ <option value="0">Disabled</option>
+ </select>
+ users.
+</p>
+
+[% Hook.process('end') %]
+
+</form>
+
+[% IF editusers %]
+ <p>
+ You can also <a href="editusers.cgi?action=add">add a new user</a>
+ [%- IF listselectionvalues %],
+ or
+ <a href="editusers.cgi?action=list[% INCLUDE listselectionurlparams %]">show
+ the user list again</a>
+ [%- END %].
+ </p>
+[% END %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/custom/attachment/list.html.tmpl b/template/en/custom/attachment/list.html.tmpl
new file mode 100644
index 000000000..aff79ac57
--- /dev/null
+++ b/template/en/custom/attachment/list.html.tmpl
@@ -0,0 +1,167 @@
+[%# 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.
+ #%]
+
+[% RETURN UNLESS attachments.size || Param("maxattachmentsize") || Param("maxlocalattachment") %]
+
+<script type="text/javascript">
+<!--
+function toggle_display(link) {
+ var table = document.getElementById("attachment_table");
+ var view_all = document.getElementById("view_all");
+ var hide_obsolete_url_parameter = "&hide_obsolete=1";
+ // Store current height for scrolling later
+ var originalHeight = table.offsetHeight;
+ var rows = YAHOO.util.Dom.getElementsByClassName(
+ 'bz_tr_obsolete', 'tr', table);
+
+ for (var i = 0; i < rows.length; i++) {
+ bz_toggleClass(rows[i], 'bz_default_hidden');
+ }
+
+ if (YAHOO.util.Dom.hasClass(rows[0], 'bz_default_hidden')) {
+ link.innerHTML = "Show Obsolete";
+ view_all.href = view_all.href + hide_obsolete_url_parameter
+ }
+ else {
+ link.innerHTML = "Hide Obsolete";
+ view_all.href = view_all.href.replace(hide_obsolete_url_parameter,"");
+ }
+
+ var newHeight = table.offsetHeight;
+ // This scrolling makes the window appear to not move at all.
+ window.scrollBy(0, newHeight - originalHeight);
+
+ return false;
+}
+//-->
+</script>
+
+<div class="panel panel-default">
+ <div class="panel-heading" style="padding-left: 8px; padding-right: 8px; padding-top: 4px; padding-bottom: 4px;font-weight:bold;font-size:13px;">
+ <i class="fa fa-caret-right" aria-hidden="true" style="margin-right:5px;cursor: pointer"></i> Attachments ([%+ attachments.size %] files)
+ </div>
+
+
+ <ul class="list-group" style="display:none;">
+
+ [% count = 0 %]
+ [% obsolete_attachments = 0 %]
+ [% user_cache = template_cache.users %]
+ [% FOREACH attachment = attachments %]
+ [% count = count + 1 %]
+ [% IF !attachment.isprivate || user.is_insider || attachment.attacher.id == user.id %]
+ [% IF attachment.isobsolete %]
+ [% obsolete_attachments = obsolete_attachments + 1 %]
+ [% END %]
+ <!--
+ <tr id="a[% count %]" class="[% "bz_contenttype_" _ attachment.contenttype
+ FILTER css_class_quote %]
+ [% " bz_patch" IF attachment.ispatch %]
+ [% " bz_private" IF attachment.isprivate %]
+ [% " bz_tr_obsolete bz_default_hidden"
+ IF attachment.isobsolete %]">-->
+ <li class="list-group-item">
+ <div>
+ [% IF attachment.datasize %]
+ <a href="attachment.cgi?id=[% attachment.id %]"
+ title="View the content of the attachment">
+ [% END %]
+ <b>[% attachment.description FILTER html FILTER obsolete(attachment.isobsolete) %]</b>
+ [% "</a>" IF attachment.datasize %]
+
+ <span class="bz_attach_extra_info">
+ [% IF attachment.datasize %]
+ ([% attachment.filename FILTER html %],
+ [% attachment.datasize FILTER unitconvert %],
+ [% IF attachment.ispatch %]
+ patch)
+ [% ELSE %]
+ [%+ attachment.contenttype FILTER html %])
+ [% END %]
+ [% ELSE %]
+ (<em>deleted</em>)
+ [% END %]
+
+ <br>
+ <a href="#attach_[% attachment.id %]"
+ title="Go to the comment associated with the attachment">
+ [%- attachment.attached FILTER time("%Y-%m-%d %H:%M %Z") %]</a>,
+
+ [%# No need to recreate the exact same template if we already have it. %]
+ [% attacher_id = attachment.attacher.id %]
+ [% UNLESS user_cache.$attacher_id %]
+ [% user_cache.$attacher_id = BLOCK %]
+ [% INCLUDE global/user.html.tmpl who = attachment.attacher %]
+ [% END %]
+ [% END %]
+ [% user_cache.$attacher_id FILTER none %]
+ </span>
+ </div>
+
+ [% IF show_attachment_flags %]
+ <div class="bz_attach_flags">
+ [% IF attachment.flags.size == 0 %]
+ <i>no flags</i>
+ [% ELSE %]
+ [% FOREACH flag = attachment.flags %]
+ [% IF user.id %]
+ <span title="[% flag.setter.identity FILTER html %]">[% flag.setter.nick FILTER html %]</span>:
+ [% ELSIF flag.setter.name %]
+ <span title="[% flag.setter.name FILTER html %]">[% flag.setter.nick FILTER html %]</span>:
+ [% ELSE %]
+ [% flag.setter.nick FILTER html %]:
+ [% END %]
+ [%+ flag.type.name FILTER html %][% flag.status %]
+ [%+ IF flag.status == "?" && flag.requestee %]
+ [% IF user.id %]
+ (<span title="[% flag.requestee.identity FILTER html %]">[% flag.requestee.nick FILTER html %]</span>)
+ [% ELSIF flag.requestee.name %]
+ (<span title="[% flag.requestee.name FILTER html %]">[% flag.requestee.nick FILTER html %]</span>)
+ [% ELSE %]
+ ([% flag.requestee.nick FILTER html %])
+ [% END %]
+ [% END %]<br>
+ [% END %]
+ [% END %]
+ </div>
+ [% END %]
+
+ <div>
+ <a href="attachment.cgi?id=[% attachment.id %]&amp;action=edit">Details</a>
+ [% IF attachment.ispatch && feature_enabled('patch_viewer') %]
+ | <a href="attachment.cgi?id=[% attachment.id %]&amp;action=diff">Diff</a>
+ [% END %]
+ [% Hook.process("action") %]
+ </div>
+ </li>
+ [% END %]
+ [% END %]
+ </ul>
+ <div class="panel-footer" style="display:none;">
+ <div colspan="[% show_attachment_flags ? 3 : 2 %]">
+ [% IF attachments.size %]
+ <span class="bz_attach_view_hide">
+ [% IF obsolete_attachments %]
+ <a href="#a0" onclick="return toggle_display(this);">Show
+ Obsolete</a> ([% obsolete_attachments %])
+ [% END %]
+ [% IF Param("allow_attachment_display") %]
+ <a id="view_all" href="attachment.cgi?bugid=
+ [%- bugid %]&amp;action=viewall
+ [%- "&amp;hide_obsolete=1" IF obsolete_attachments %]">View All</a>
+ [% END %]
+ </span>
+ [% END %]
+ [% IF Param("maxattachmentsize") || Param("maxlocalattachment") %]
+ <a href="attachment.cgi?bugid=[% bugid %]&amp;action=enter">Add an attachment</a>
+ (proposed patch, testcase, etc.)
+ [% END %]
+ </div>
+ </div>
+</div>
+<br>
diff --git a/template/en/custom/bug/comment.html.tmpl b/template/en/custom/bug/comment.html.tmpl
new file mode 100644
index 000000000..035f6117c
--- /dev/null
+++ b/template/en/custom/bug/comment.html.tmpl
@@ -0,0 +1,38 @@
+[%# 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:
+ #
+ # This template supports the same parameters as global/textarea.html.tmpl
+ # with the exception of "name" and "id", which will always be "comment".
+ #%]
+
+[% IF feature_enabled('jsonrpc') %]
+ <div id="comment_tabs" role="tablist">
+ <div id="comment_tab" class="comment_tab active_comment_tab"
+ role="tab" aria-selected="true"
+ onclick="show_comment_edit()">Comment</div>
+ <div id="comment_preview_tab" class="comment_tab"
+ role="tab" aria-selected="false"
+ onclick="show_comment_preview([% bug.id FILTER none %])">Preview</div>
+ </div>
+[% END %]
+
+[% INCLUDE global/textarea.html.tmpl
+ name = "comment"
+ id = "comment"
+ classes = "comment-textarea"
+%]
+
+[% IF feature_enabled('jsonrpc') %]
+ <div id="comment_preview" class="bz_default_hidden bz_comment">
+ <div id="comment_preview_loading" class="bz_default_hidden">Generating Preview...</div>
+ <div id="comment_preview_error" class="bz_default_hidden"></div>
+ <pre id="comment_preview_text" class="bz_comment_text"></pre>
+ </div>
+[% END %]
diff --git a/template/en/custom/bug/comments.html.tmpl b/template/en/custom/bug/comments.html.tmpl
new file mode 100644
index 000000000..ede273a51
--- /dev/null
+++ b/template/en/custom/bug/comments.html.tmpl
@@ -0,0 +1,262 @@
+[%# 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 bug/time.html.tmpl %]
+
+<script src="[% 'js/comments.js' FILTER mtime %]" type="text/javascript">
+</script>
+
+<script type="text/javascript">
+<!--
+ /* Adds the reply text to the 'comment' textarea */
+ function replyToComment(id, real_id, name) {
+ var prefix = "(In reply to " + name + " from comment #" + id + ")\n";
+ var replytext = "";
+ [% IF user.settings.quote_replies.value == 'quoted_reply' %]
+ /* pre id="comment_name_N" */
+ var text_elem = document.getElementById('comment_text_'+id);
+ var text = getText(text_elem);
+ replytext = prefix + wrapReplyText(text);
+ [% ELSIF user.settings.quote_replies.value == 'simple_reply' %]
+ replytext = prefix;
+ [% END %]
+
+ [% IF user.is_insider %]
+ if (document.getElementById('isprivate_' + real_id).checked) {
+ document.getElementById('newcommentprivacy').checked = 'checked';
+ updateCommentTagControl(document.getElementById('newcommentprivacy'), 'comment');
+ }
+ [% END %]
+
+ /* <textarea id="comment"> */
+ var textarea = document.getElementById('comment');
+ if (textarea.value != replytext) {
+ textarea.value += replytext;
+ }
+
+ textarea.focus();
+ }
+//-->
+</script>
+
+[% DEFAULT mode = "show" %]
+[% user_cache = template_cache.users %]
+[% can_edit_comments = bug.check_can_change_field('longdesc', 0, 1) %]
+[% can_tag_comments = feature_enabled('jsonrpc') AND user.can_tag_comments %]
+
+<!-- This auto-sizes the comments and positions the collapse/expand links
+ to the right. -->
+<!--<table class="bz_comment_table">-->
+<!--<tr>-->
+<!--<td>-->
+
+<div class="row">
+
+[% PROCESS display_comments %]
+
+[% IF mode == "edit" && user.id
+ && user.settings.comment_box_position.value == "before_comments" %]
+ <div class="bz_add_comment">
+ <a href="#"
+ onclick="return goto_add_comments();">
+ Add Comment</a>
+ </div>
+[% END %]
+
+[%# Note: this template is used in multiple places; if you use this hook,
+ # make sure you are aware of this fact.
+ #%]
+[% Hook.process("aftercomments") %]
+
+</div>
+
+<!--</td>-->
+<!--<td>-->
+ <!--[% IF mode == "edit" %]-->
+ <!--<ul class="bz_collapse_expand_comments">-->
+ <!--<li><a href="#" onclick="toggle_all_comments('collapse');-->
+ <!--return false;">Collapse All Comments</a></li>-->
+ <!--<li><a href="#" onclick="toggle_all_comments('expand');-->
+ <!--return false;">Expand All Comments</a></li>-->
+ <!--[% IF Param('comment_taggers_group') %]-->
+ <!--<li><div id="comment_tags_collapse_expand_container"></div></li>-->
+ <!--[% END %]-->
+ <!--[% IF user.settings.comment_box_position.value == "after_comments" && user.id %]-->
+ <!--<li class="bz_add_comment"><a href="#" -->
+ <!--onclick="return goto_add_comments('bug_status_bottom');">-->
+ <!--Add Comment</a></li>-->
+ <!--[% END %]-->
+ <!--</ul>-->
+ <!--[% END %]-->
+<!--</td>-->
+<!--</tr></table>-->
+
+[%############################################################################%]
+[%# Block for individual comments #%]
+[%############################################################################%]
+
+[% BLOCK display_comments %]
+ [% FOREACH comment = comments %]
+ [% NEXT IF comment.is_private AND NOT (user.is_insider || user.id == comment.author.id) %]
+ [% comment_text = comment.body_full %]
+ [% NEXT IF comment_text == '' AND (comment.work_time - 0) != 0 AND !user.is_timetracker %]
+
+ <div id="c[% comment.count %]" class="panel panel-default bz_comment[% " bz_private" IF comment.is_private %]
+ [% " bz_default_collapsed" IF comment.collapsed %]
+ [% " bz_comment_hilite" IF marks.${comment.count} %]
+ [% " bz_first_comment" IF comment.count == 0 %]" style="padding:0px;">
+ [% IF comment.count == 0 %]
+ [% class_name = "bz_first_comment_head" %]
+ [% comment_label = "Description" %]
+ [% ELSE %]
+ [% class_name = "bz_comment_head" %]
+ [% comment_label = "Comment " _ comment.count %]
+ [% END %]
+
+ <div class="panel-heading [% class_name FILTER html %]">
+
+ <div class="row">
+ <div class="col-sm-8">
+
+
+ <div class="row">
+ <div class="col-sm-12">
+ <span class="bz_comment_user" style="color:#000!important;">
+ [%# No need to recreate the exact same template if we already have it. %]
+ [% commenter_id = comment.author.id %]
+ [% UNLESS user_cache.$commenter_id %]
+ [% user_cache.$commenter_id = BLOCK %]
+ [% INCLUDE global/user.html.tmpl who = comment.author %]
+ [% END %]
+ [% END %]
+ [% user_cache.$commenter_id FILTER none %]
+ </span>
+ <span class="bz_comment_user_images">
+ [% FOREACH group = comment.author.groups_with_icon %]
+ <img src="[% group.icon_url FILTER html %]"
+ alt="[% group.name FILTER html %]"
+ title="[% group.name FILTER html %] - [% group.description FILTER html %]">
+ [% END %]
+ </span>
+ </div>
+ <div class="col-sm-12">
+ <span style="margin-right:2px;">
+ <a style="color:#505050; font-weight: normal;" href="#c[% comment.count %]">
+ [%- comment_label FILTER html %]</a>
+ </span>
+ <span style="color:#505050;">•</span>
+ <span class="bz_comment_time" style="color:#505050; font-weight: normal;margin-left:2px;">
+ [%+ comment.creation_ts FILTER time %]
+ </span>
+
+ </div>
+ </div>
+
+ </div>
+
+ <div class="col-sm-4">
+
+ [% IF mode == "edit" %]
+ <span class="bz_comment_actions">
+ [% IF comment.collapsed %]
+ <span class="bz_collapsed_actions">
+ [% END %]
+ [% IF can_edit_comments %]
+ [% IF can_tag_comments %]
+ <a href="#" class="btn btn-default btn-xs" style="background:transparent;color:#505050;border:none;"
+ onclick="YAHOO.bugzilla.commentTagging.toggle([% comment.id %], [% comment.count %]);return false"><i class="fa fa-tag" aria-hidden="true"></i></a>
+ [% END %]
+ <a class="bz_reply_link btn btn-default btn-xs" href="#add_comment" style="background:transparent;color:#505050;border:none;"
+ [% IF user.settings.quote_replies.value != 'off' %]
+ onclick="replyToComment('[% comment.count %]', '[% comment.id %]', '[% comment.author.name || comment.author.nick FILTER html FILTER js %]'); return false;"
+ [% END %]
+ ><i class="fa fa-reply" aria-hidden="true"></i></a>
+ [% END %]
+ [% IF comment.collapsed %]
+ </span>
+ [% END %]
+ <script type="text/javascript">
+ addCollapseLink([% comment.count %], [% comment.collapsed FILTER js %], 'Toggle comment display');
+ </script>
+ </span>
+ [% ELSIF comment.collapsed %]
+ <span class="bz_comment_actions">
+ <script type="text/javascript">
+ addCollapseLink([% comment.count %], [% comment.collapsed FILTER js %], 'Toggle comment display');
+ </script>
+ </span>
+ [% END %]
+
+
+ </div>
+ </div>
+
+
+
+ [% IF mode == "edit" && can_edit_comments && user.is_insider %]
+ <div class="bz_private_checkbox">
+ <input type="hidden" value="1"
+ name="defined_isprivate_[% comment.id %]">
+ <input type="checkbox"
+ name="isprivate_[% comment.id %]" value="1"
+ id="isprivate_[% comment.id %]"
+ onClick="updateCommentPrivacy(this, [% comment.count %])"
+ [% " checked=\"checked\"" IF comment.is_private %]>
+ <label for="isprivate_[% comment.id %]">Private</label>
+ </div>
+ [% END %]
+
+
+ [% IF comment.collapsed %]
+ <span id="cr[% comment.count %]" class="bz_comment_collapse_reason"
+ title="[% comment.author.name || comment.author.login FILTER html %]
+ [%~ %] [[% comment.creation_ts FILTER time %]]">
+ Comment hidden ([% comment.tags.join(', ') FILTER html %])
+ </span>
+ [% END %]
+ </div>
+
+ [% IF user.is_timetracker &&
+ (comment.work_time > 0 || comment.work_time < 0) %]
+ <br>
+ Additional hours worked:
+ [% PROCESS formattimeunit time_unit=comment.work_time %]
+ [% END %]
+
+ [% IF user.id && Param('comment_taggers_group') %]
+ <div id="comment_tag_[% comment.count FILTER html %]"
+ class="bz_comment_tags">
+ <span id="ct_[% comment.count %]"
+ class="[% 'bz_default_hidden' UNLESS comment.tags.size %]">
+ [% IF comment.tags.size %]
+ <script>
+ YAHOO.bugzilla.commentTagging.showTags([% comment.id FILTER none %],
+ [% comment.count FILTER none %], [
+ [% FOREACH tag = comment.tags %]
+ [%~%]'[% tag FILTER js %]'[% "," UNLESS loop.last %]
+ [% END %]
+ [%~%]]);
+ </script>
+ [% END %]
+ </span>
+ </div>
+ [% END %]
+
+[%# Don't indent the <pre> block, since then the spaces are displayed in the
+ # generated HTML
+ #%]
+<div class="panel-body bz_comment_text[% " collapsed" IF comment.collapsed %]"
+ [% IF mode == "edit" || comment.collapsed %]
+ id="comment_text_[% comment.count FILTER none %]"
+ [% END %]>
+ [%- comment_text FILTER quoteUrls(bug, comment) -%]
+</div>
+ [% Hook.process('a_comment-end', 'bug/comments.html.tmpl') %]
+ </div>
+ [% END %]
+[% END %]
diff --git a/template/en/custom/bug/create/create-guided.html.tmpl b/template/en/custom/bug/create/create-guided.html.tmpl
new file mode 100644
index 000000000..7cd59b3ea
--- /dev/null
+++ b/template/en/custom/bug/create/create-guided.html.tmpl
@@ -0,0 +1,621 @@
+[%# 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:
+ # This template has the same interface as create.html.tmpl
+ #%]
+
+[% USE Bugzilla %]
+[% cgi = Bugzilla.cgi %]
+
+[% PROCESS global/header.html.tmpl
+ title = "Enter $terms.ABug"
+ onload = "PutDescription()"
+ style_urls = ['skins/standard/bug.css']
+ %]
+
+[%# This script displays the descriptions for selected components. %]
+<script type="text/javascript">
+var descriptions = [
+[% FOREACH c = product.components %]
+ [% NEXT IF NOT c.is_active %]
+ '[% c.description FILTER js %]',
+[% END %]
+];
+
+function PutDescription() {
+ var description = document.getElementById('description');
+ var componentIndex = document.getElementById('component').selectedIndex;
+ YAHOO.util.Dom.removeClass("description", "bz_default_hidden");
+ if (componentIndex != -1) {
+ description.innerHTML = descriptions[componentIndex];
+ }
+}
+</script>
+
+[% INCLUDE 'bug/create/user-message.html.tmpl' %]
+
+
+<div class="" style="background: transparent; border: none;">
+
+<div style="">
+ <div class="tab-content" id="myTabContent">
+ <div class="tab-pane fade active in" role="tabpanel" id="step1-tab" aria-labelledby="step1-heading" style="margin-bottom:100px;">
+
+ <!--
+ <p class="text-danger" style="margin-bottom:20px;">
+ Please don't skip this step - half of all [% terms.bugs %] filed are
+ reported already.
+ </p>
+ -->
+
+ <div class="jumbotron">
+ <h2 class="site-welcome stick-top" style="font-family: Bitter,'Open Sans',sans-serif; font-size: 2.5em;text-align: center;margin-bottom: 1em;">Please summarize your issue in one sentence:</h2>
+
+ <div>
+
+
+
+ <div class="row">
+ <div class="col-lg-12">
+ <div class="input-group">
+ <input id="quicksearch_main" name="quicksearch" class="form-control" title="Quick Search" placeholder="pop3 mail" autofocus="" required="">
+
+ <script>
+ document.getElementById("quicksearch_main").addEventListener("keyup", function(event) {
+ if (event.keyCode === 13) {
+ event.preventDefault();
+ updateDuplicateWindow();
+ }
+ });
+ </script>
+
+ <div class="input-group-btn">
+ <div class="btn-group">
+ <button id="find" onclick="updateDuplicateWindow();" class="btn btn-default" value="Quick Search">Find similar Issues</button>
+ </div>
+ </div>
+ </div><!-- /input-group -->
+ </div><!-- /.col-lg-6 -->
+ </div>
+
+
+
+ <ul class="additional_links" style="display: none;">
+ </ul>
+ </div><br>
+ <small class="text-muted">Please search [% terms.Bugzilla %] by entering
+ a few key words having to do with your [% terms.bug %] in this box.<br/>
+ For example: <code><b>pop3 mail</b></code> or <code><b>copy paste</b></code>.
+ The results will appear above.
+ <!-- <hr width="100%" /> --></small>
+
+ </div>
+
+<!--
+ [%# All bugs opened inside the past six months %]
+ <form action="buglist.cgi" method="get" target="somebugs">
+ <input type="hidden" name="format" value="simple">
+ <input type="hidden" name="order" value="relevance desc">
+ <input type="hidden" name="bug_status" value="__all__">
+ <input type="hidden" name="product" value="[% product.name FILTER html %]">
+ <input type="hidden" name="chfieldfrom" value="-6m">
+ <input type="hidden" name="chfieldto" value="Now">
+ <input type="hidden" name="chfield" value="[Bug creation]">
+ <div class="row">
+ <div class="col-lg-4 col-lg-offset-4">
+ <div class="input-group" style="max-width:450px;margin-bottom:20px;">
+ <input type="text" class="form-control" name="content" size="40">
+ <div class="input-group-btn">
+ <button onclick="$('#duplicate_search_panel').show();" class="btn btn-default" type="submit" id="search" value="Search">Search</button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </form>
+-->
+
+ <div id="duplicate_search_panel" style="display:none;">
+ <div class="panel panel-default">
+ <div class="panel-heading">
+ <h3 class="panel-title">
+ Search for duplicate bugs
+ </h3>
+ </div>
+ <div class="panel-body">
+ <div class="row">
+ <div class="col-sm-12">
+
+ <div id="otherpage" class="align-h-center"><div class="row" style="margin: 20px;"><div class="col-sm-12"><div class="text-center"><i class="fa fa-spinner fa-spin" style="font-size:32px"></i></div></div></div></div>
+ </div>
+ </div>
+ <script>
+
+ function updateDuplicateWindow() {
+ $('#duplicate_search_panel').show();
+
+ $('#otherpage').load(encodeURI('buglist.cgi?serverpush=0&format=simple&order=relevance desc&bug_status=__all__&product=[% product.name FILTER html %]&chfieldfrom=-6m&chfieldto=Now&chfield=[Bug creation]&content=' + $("#quicksearch_main").val()), function() {
+ console.log('Load was performed.');
+ });
+ }
+ </script>
+ <!--
+ <iframe name="somebugs" id="somebugs" frameBorder="0"
+ src="duplicates.cgi?product=[% product.name FILTER uri %]&amp;format=simple">
+ </iframe>
+ -->
+ </div>
+ <div class="panel-footer">
+
+ <p>
+ Check the two lists of frequently-reported [% terms.bugs %]:
+ <a href="duplicates.cgi?product=[% product.name FILTER uri %]&amp;format=simple"
+ target="somebugs">All-time Top 100</a> (loaded initially) |
+ <a href="duplicates.cgi?product=[% product.name FILTER uri %]&amp;format=simple&amp;sortby=delta&amp;reverse=1&amp;maxrows=100&amp;changedsince=14"
+ target="somebugs">Hot in the last two weeks</a>
+ </p>
+
+ <p>
+ Look through the search results. If you get the
+ <code><b>[% terms.zeroSearchResults %]</b></code> message, [% terms.Bugzilla %]
+ found no [% terms.bugs %] that
+ match. Check for typing mistakes, or try fewer or different keywords.
+ If you find [% terms.abug %] that looks the same as yours, please add
+ any useful extra information you have to it, rather than opening a new one.
+ </p>
+
+ </div>
+ </div>
+
+
+
+
+ <hr/>
+
+ <a href="#step2-tab" class="btn btn-primary pull-right" role="tab" data-toggle="tab" aria-controls="tab" aria-expanded="true">
+ Next Step
+ </a>
+ </div>
+
+ </div>
+
+
+
+ <!-- ==================================================================================================== STEP 2 -->
+
+ <div class="tab-pane fade in create-guided" role="tabpanel" id="step2-tab" aria-labelledby="step2-heading" style="margin-bottom:100px;">
+ <div class="panel panel-default">
+ <div class="panel-body">
+
+ <h2 style="margin-top:0px;">Give information<br/>
+ <small>If you've tried a few searches and your [% terms.bug %] really isn't in
+ there, tell us all about it.</small>
+ </h2><br/>
+
+ <form id="guided_form" method="post" action="post_bug.cgi">
+ <input type="hidden" name="format" value="guided">
+ <input type="hidden" name="assigned_to" value="">
+ <input type="hidden" name="priority"
+ value="[% default.priority FILTER html %]">
+ <input type="hidden" name="version"
+ value="[% default.version FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+
+
+ <div class="row equal">
+ <div class="col-sm-2 align-v-center align-h-right" style="padding-right: 0px;">
+ <b style="text-transform: uppercase;">Product</b>
+ </div>
+ <div class="col-sm-10">
+ <input type="hidden" name="product" value="[% product.name FILTER html %]"/>
+ [% product.name FILTER html %]
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>Component</b><br/>
+ <small>
+ The area where the problem occurs.
+ To pick the right component, you could use the same one as
+ similar [% terms.bugs %] you found in your search, or read the full list of
+ <a href="describecomponents.cgi?product=[% product.name FILTER uri %]"
+ target="_blank" >component descriptions</a> (opens in new window) if
+ you need more help.
+ </small>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-4">
+
+ <select class="" name="component" id="component" size="5" onchange="PutDescription()">
+ [% IF NOT default.component_ %]
+ [% default.component_ = "General" %]
+ [% END %]
+ [% FOREACH c = product.components %]
+ [% NEXT IF NOT c.is_active %]
+ <option value="[% c.name FILTER html %]"
+ [%+ 'selected="selected"' IF c.name == default.component_ %]>
+ [% c.name FILTER html %]
+ </option>
+ [% END %]
+ </select>
+ </div>
+
+ <div class="col-sm-8">
+ <div id="description" style="margin-left:0px;">
+ Select a component to see its description here.
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="row equal">
+ <div class="col-sm-2 align-v-center align-h-right" style="padding-right: 0px;">
+ <b style="text-transform:uppercase;">[% field_descs.rep_platform FILTER html %]</b>
+ </div>
+ <div class="col-sm-10">
+ [% PROCESS select sel = 'rep_platform' %]
+ </div>
+ </div>
+
+ <div class="row equal">
+ <div class="col-sm-2 align-v-center align-h-right" style="padding-right: 0px;">
+ <b>Operating System</b>
+ </div>
+ <div class="col-sm-10">
+ [% PROCESS select sel = 'op_sys' %]
+ </div>
+ </div>
+
+
+ <div class="row">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>URL</b><br/>
+ <small>
+ URL that demonstrates the problem you are seeing (optional).
+ </small>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+
+ <input type="text" size="80" name="bug_file_loc" value="http://">
+ </div>
+
+ <div class="col-sm-12">
+ <span class="text-danger"> You should never use URL to point to pastebins
+ for error messages, logs, emerge --info output, screenshots or similar
+ information.<br>Instead, these should always be attached to the
+ bug.</span>
+ </div>
+ </div>
+ </div>
+ </div>
+
+
+ <div class="row">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b style="text-transform:uppercase;">Summary</b><br/>
+ <small>
+ A sentence which summarises the problem.
+ Please be descriptive and use lots of keywords.
+ Include the <b>full</b> package atom with the version!
+ </small>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+
+ <input type="text" size="80" name="short_desc" id="short_desc" placeholder="Summary"
+ maxlength="255" spellcheck="true">
+ </div>
+
+ <div class="col-sm-12">
+ <p>
+ <code>
+ <span class="bad">Bad example</span>: mail crashed
+ </code>
+ <br>
+ <code>
+ <span class="good">Good example</span>:
+ mail-client/evolution-2.8.3-r2: crash if I close the mail window while checking for new POP mail
+ </code>
+ </p>
+
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>Description</b><br/>
+ <small>
+ Expand on the Summary. Please be
+ as specific as possible about what is wrong.
+ </small>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ [% INCLUDE global/textarea.html.tmpl
+ name = 'comment'
+ minrows = 6
+ cols = constants.COMMENT_COLS
+ mandatory = 1
+ classes = 'form-control'
+ %]
+ </div>
+
+ <div class="col-sm-12">
+ <p>
+ <code>
+ <span class="bad">Bad example</span>: Mozilla crashed.
+ You suck!
+ </code>
+ <br>
+ <code>
+ <span class="good">Good example</span>: After a crash which
+ happened when I was sorting in the Bookmark Manager,<br> all of my
+ top-level bookmark folders beginning with the letters Q to Z are
+ no longer present.
+ </code>
+ </p>
+ </div>
+ </div>
+ </div>
+ </div>
+
+
+ <div class="row equal">
+ <div class="col-sm-2 align-v-center align-h-right" style="padding-right: 0px;">
+ <b style="text-transform:uppercase;">Reproducibility</b>
+ </div>
+ <div class="col-sm-10">
+ <select class="form-control" name="reproducible">
+ <option name="AlwaysReproducible" value="Always">
+ Happens every time.
+ </option>
+ <option name="Sometimes" value="Sometimes">
+ Happens sometimes, but not always.
+ </option>
+ <option name="DidntTry" value="Didn't try">
+ Haven't tried to reproduce it.
+ </option>
+ <option name="NotReproducible" value="Couldn't Reproduce">
+ Tried, but couldn't reproduce it.
+ </option>
+ </select>
+ </div>
+ </div>
+
+
+ <div class="row">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>Steps to Reproduce</b><br/>
+ <small>
+ Describe how to reproduce the problem, step by
+ step. Include any special setup steps.
+ </small>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ [% INCLUDE global/textarea.html.tmpl
+ name = 'reproduce_steps'
+ minrows = 4
+ cols = constants.COMMENT_COLS
+ defaultcontent = "1.\n2.\n3."
+ classes = 'form-control'
+ %]
+ </div>
+ </div>
+ </div>
+ </div>
+
+
+ <div class="row">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b style="text-transform:uppercase;">Actual Results</b><br/>
+ <small>
+ What happened after you performed the steps above?
+ </small>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ [% INCLUDE global/textarea.html.tmpl
+ name = 'actual_results'
+ minrows = 4
+ cols = constants.COMMENT_COLS
+ classes = 'form-control'
+ %]
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>Expected Results</b><br/>
+ <small>
+ What should the software have done instead?
+ </small>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ [% INCLUDE global/textarea.html.tmpl
+ name = 'expected_results'
+ minrows = 4
+ cols = constants.COMMENT_COLS
+ classes = 'form-control'
+ %]
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b style="text-transform:uppercase;">Additional Information</b><br/>
+ <small>
+ Add any additional information you feel may be relevant to this
+ [% terms.bug %], such as what other <b>programs you had running</b>,
+ and/or
+ information about <b>your computer's configuration</b>. Any information
+ longer
+ than a few lines, such as a <b>stack trace</b>, should be added using the
+ "Create a new Attachment" link on the bug, after it is filed.<br />
+ <b>Please paste all information from 'emerge --info' in this section!</b>
+ </small>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ [% INCLUDE global/textarea.html.tmpl
+ name = 'additional_info'
+ minrows = 8
+ cols = constants.COMMENT_COLS
+ classes = 'form-control'
+ %]
+ </div>
+ </div>
+ </div>
+ </div>
+
+
+
+ <div class="row">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>[% field_descs.bug_severity FILTER html %]</b><br/>
+ <small>
+ Say how serious the problem is, or if your [% terms.bug %] is a
+ request for a new feature.
+ </small>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ <select class="form-control" name="bug_severity">
+ <option name="blocker" value="blocker">
+ Blocker: Blocks development and/or testing work of Gentoo as a whole
+ </option>
+ <option name="critical" value="critical">
+ Critical: The software crashes, hangs, or causes you to
+ lose data.
+ </option>
+ <option name="major" value="major">
+ Major: A major feature is broken.
+ </option>
+ <option name="normal" value="normal" selected="selected">
+ Normal: It's [% terms.abug %] that should be fixed.
+ </option>
+ <option name="minor" value="minor">
+ Minor: Minor loss of function, and there's an easy workaround.
+ </option>
+ <option name="trivial" value="trivial">
+ Trivial: A cosmetic problem, such as a misspelled word or
+ misaligned text.
+ </option>
+ <option name="enhancement" value="enhancement">
+ Enhancement: Request for new feature or enhancement, including ebuild
+ submissions.
+ </option>
+ </select>
+ </div>
+ </div>
+ </div>
+ </div>
+
+
+ [% Hook.process('form') %]
+
+
+ </form>
+
+ <hr/>
+
+ <p>
+ <a href="#step3-tab" class="btn btn-primary pull-right" role="tab" data-toggle="tab" aria-controls="tab" aria-expanded="true">
+ Next Step
+ </a>
+ <a href="#step1-tab" class="btn btn-default pull-right" style="margin-right:10px;" role="tab" data-toggle="tab" aria-controls="tab" aria-expanded="true">
+ Back
+ </a>
+ </p>
+
+
+ </div>
+ </div>
+ </div>
+
+ <!-- ==================================================================================================== STEP 3 -->
+
+ <div class="tab-pane fade in" role="tabpanel" id="step3-tab" aria-labelledby="step3-heading">
+ <div class="panel panel-default">
+ <div class="panel-body">
+ <h2 style="margin-top:0px;">That's it! You are ready to submit the [%+ terms.bug %] report now.<br/>
+ <small>
+ Thanks very much. You'll be notified by email about any
+ progress that is made on fixing your [% terms.bug %].
+ </small>
+ </h2>
+ <br/>
+
+ <div class="alert alert-warning" role="alert">
+ Please be warned
+ that we get a lot of [% terms.bug %] reports filed - it may take quite a
+ while to get around to yours. You can help the process by making sure your
+ [%+ terms.bug %] is
+ complete and easy to understand, and by quickly replying to any questions
+ which may arrive by email.
+ </div>
+
+ <hr/>
+
+ <p class="pull-right">
+ <input class="btn btn-primary" type="button" onclick="document.getElementById('guided_form').submit(); " id="report" value="Submit [% terms.Bug %] Report">
+ </p>
+ <a href="#step2-tab" class="btn btn-default pull-right" style="margin-right:10px;" role="tab" data-toggle="tab" aria-controls="tab" aria-expanded="true">
+ Back
+ </a>
+ </div>
+ </div>
+ </div>
+
+
+ </div>
+</div>
+</div>
+
+
+
+[% PROCESS global/footer.html.tmpl %]
+
+[%############################################################################%]
+[%# Block for SELECT fields #%]
+[%############################################################################%]
+
+[% BLOCK select %]
+ <select name="[% sel %]" class="form-control selectwidthauto">
+ [%- IF default.$sel %]
+ <option value="[% default.$sel FILTER html %]" selected="selected">
+ [% default.$sel FILTER html -%]
+ </option>
+ [% END %]
+ [%- FOREACH x = $sel %]
+ [% NEXT IF x == default.$sel %]
+ <option value="[% x FILTER html %]">
+ [% x FILTER html -%]
+ </option>
+ [%- END %]
+ </select>
+[% END %]
diff --git a/template/en/custom/bug/create/create.html.tmpl b/template/en/custom/bug/create/create.html.tmpl
new file mode 100644
index 000000000..e8050a1d3
--- /dev/null
+++ b/template/en/custom/bug/create/create.html.tmpl
@@ -0,0 +1,831 @@
+[%# 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.
+ #%]
+
+[% title = BLOCK %]Enter [% terms.Bug %]: [% product.name FILTER html %][% END %]
+[% use_qa_contact = Param("useqacontact") %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ generate_api_token = 1
+ yui = [ 'autocomplete', 'calendar', 'datatable', 'button' ]
+ style_urls = ['skins/standard/bug.css']
+ javascript_urls = [ "js/attachment.js", "js/util.js",
+ "js/field.js", "js/TUI.js", "js/bug.js" ]
+ onload = "set_assign_to($use_qa_contact); hideElementById('attachment_true');
+ showElementById('attachment_false'); showElementById('btn_no_attachment');"
+%]
+
+<script type="text/javascript">
+<!--
+
+var initialowners = new Array([% product.components.size %]);
+var last_initialowner;
+var initialccs = new Array([% product.components.size %]);
+var components = new Array([% product.components.size %]);
+var comp_desc = new Array([% product.components.size %]);
+var flags = new Array([% product.components.size %]);
+[% IF Param("useqacontact") %]
+ var initialqacontacts = new Array([% product.components.size %]);
+ var last_initialqacontact;
+[% END %]
+[% count = 0 %]
+[%- FOREACH c = product.components %]
+ [% NEXT IF NOT c.is_active %]
+ components[[% count %]] = "[% c.name FILTER js %]";
+ comp_desc[[% count %]] = "[% c.description FILTER html_light FILTER js %]";
+ initialowners[[% count %]] = "[% c.default_assignee.login FILTER js %]";
+ [% flag_list = [] %]
+ [% FOREACH f = c.flag_types.bug %]
+ [% NEXT UNLESS f.is_active %]
+ [% flag_list.push(f.id) %]
+ [% END %]
+ [% FOREACH f = c.flag_types.attachment %]
+ [% NEXT UNLESS f.is_active %]
+ [% flag_list.push(f.id) %]
+ [% END %]
+ flags[[% count %]] = [[% flag_list.join(",") FILTER js %]];
+ [% IF Param("useqacontact") %]
+ initialqacontacts[[% count %]] = "[% c.default_qa_contact.login FILTER js %]";
+ [% END %]
+
+ [% SET initial_cc_list = [] %]
+ [% FOREACH cc_user = c.initial_cc %]
+ [% initial_cc_list.push(cc_user.login) %]
+ [% END %]
+ initialccs[[% count %]] = "[% initial_cc_list.join(', ') FILTER js %]";
+
+ [% count = count + 1 %]
+[%- END %]
+
+var status_comment_required = new Array();
+[% FOREACH status = bug_status %]
+ status_comment_required['[% status.name FILTER js %]'] =
+ [% status.comment_required_on_change_from() ? 'true' : 'false' %]
+[% END %]
+
+TUI_alternates['expert_fields'] = 'Show Advanced Fields';
+// Hide the Advanced Fields by default, unless the user has a cookie
+// that specifies otherwise.
+TUI_hide_default('expert_fields');
+// Also hide the "Paste text as attachment" textarea by default.
+TUI_hide_default('attachment_text_field');
+-->
+</script>
+
+[%# Migration note: The following file corresponds to the old Param
+# 'entryheaderhtml'
+#%]
+[% PROCESS 'bug/create/user-message.html.tmpl' %]
+
+<div class="panel panel-default">
+<div class="panel-body">
+
+ <h2 style="margin-top:0px;">Enter A Bug</h2>
+ <div class="row" style="margin-bottom:10px;">
+ <div class="col-sm-12">
+ <a id="expert_fields_controller" class="controller bz_default_hidden pull-right"
+ href="javascript:TUI_toggle_class('expert_fields')">Hide
+ Advanced Fields</a>
+ [%# Show the link if the browser supports JS %]
+ <script type="text/javascript">
+ YAHOO.util.Dom.removeClass('expert_fields_controller',
+ 'bz_default_hidden');
+ </script>
+ </div>
+ </div>
+
+<form name="Create" id="Create" method="post" action="post_bug.cgi"
+ class="enter_bug_form" enctype="multipart/form-data"
+ onsubmit="return validateEnterBug(this)">
+<input type="hidden" name="product" value="[% product.name FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ <input type="hidden" name="version"
+ value="[% default.version FILTER html %]">
+
+
+ <div class="row">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>Product</b>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ [% product.name %]
+ </div>
+ </div>
+ </div>
+ </div>
+
+
+ <div class="row">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>Reporter</b>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ [% user.login %]
+ </div>
+ </div>
+ </div>
+ </div>
+
+
+ <div class="row">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>Component</b>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-4">
+ <select name="component" id="component" onchange="set_assign_to([% Param("useqacontact") %]);"
+ size="7" aria-required="true" class="">
+ [%# Build the lists of assignees and QA contacts if "usemenuforusers" is enabled. %]
+ [% IF Param("usemenuforusers") %]
+ [% assignees_list = user.get_userlist.clone %]
+ [% qa_contacts_list = user.get_userlist.clone %]
+ [% END %]
+
+ [%- FOREACH c = product.components %]
+ [% NEXT IF NOT c.is_active %]
+ <option value="[% c.name FILTER html %]"
+ id="v[% c.id FILTER html %]_component"
+ [% IF c.name.lower == default.component_.lower %]
+ [%# This is for bug/field.html.tmpl, for visibility-related
+ # controls. %]
+ [% default.component_id = c.id %]
+ selected="selected"
+ [% END %]>
+ [% c.name FILTER html -%]
+ </option>
+ [% IF Param("usemenuforusers") %]
+ [% INCLUDE build_userlist default_user = c.default_assignee,
+ userlist = assignees_list %]
+ [% INCLUDE build_userlist default_user = c.default_qa_contact,
+ userlist = qa_contacts_list %]
+ [% END %]
+ [%- END %]
+ </select>
+ </div>
+
+ <div class="col-sm-8">
+ <div id="comp_desc" class="comment">Select a component to read its description.</div>
+ <script type="text/javascript">
+ <!--
+ [%+ INCLUDE "bug/field-events.js.tmpl"
+ field = bug_fields.component, product = product %]
+ //-->
+ </script>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>Severity</b>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ [% INCLUDE bug/field.html.tmpl
+ bug = default, field = bug_fields.bug_severity, editable = 1, no_tds = 1,
+ value = default.bug_severity %]
+ </div>
+ </div>
+ </div>
+ </div>
+
+[% IF Param('letsubmitterchoosepriority') %]
+ <div class="row expert_fields">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>Priority</b>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ [% INCLUDE bug/field.html.tmpl
+ bug = default, field = bug_fields.priority, editable = 1, no_tds = 1,
+ value = default.priority %]
+ </div>
+ </div>
+ </div>
+ </div>
+[% END %]
+
+
+<div class="row">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>Hardware</b>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ [% INCLUDE bug/field.html.tmpl
+ bug = default, field = bug_fields.rep_platform, editable = 1, no_tds = 1,
+ value = default.rep_platform %]
+ </div>
+ </div>
+ </div>
+</div>
+
+
+ [% IF user.in_group('editbugs', product.id) %]
+ <div class="row expert_fields">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>Depends on</b>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ <input name="dependson" accesskey="d" value="[% dependson FILTER html %]">
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="row expert_fields">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>Blocks</b>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ <input name="blocked" accesskey="b" value="[% blocked FILTER html %]">
+ </div>
+ </div>
+ </div>
+ </div>
+ [% END %]
+
+
+
+
+ <div class="row">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>OS</b>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-2">
+ [% INCLUDE bug/field.html.tmpl
+ bug = default, field = bug_fields.op_sys, editable = 1, no_tds = 1,
+ value = default.op_sys %]
+ [% IF (!Param('defaultplatform') || !Param('defaultopsys')) && !cloned_bug_id %]
+ </div>
+ <div class="col-sm-10">
+ <div class="text-success">We've made a guess at your
+ [% IF Param('defaultplatform') %]
+ operating system. Please check it
+ [% ELSIF Param('defaultopsys') %]
+ platform. Please check it
+ [% ELSE %]
+ operating system and platform. Please check them
+ [% END %]
+ and make any corrections if necessary.</div>
+ [% END %]
+ </div>
+ </div>
+ </div>
+ </div>
+
+
+
+ <div class="row expert_fields">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>Status</b>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ [% INCLUDE bug/field.html.tmpl
+ bug = default, field = bug_fields.bug_status, no_tds = 1,
+ editable = (bug_status.size > 1), value = default.bug_status
+ override_legal_values = bug_status %]
+
+ <!-- TODO:
+ [%# Calculate the number of rows we can use for flags %]
+ [% num_rows = 6 + (Param("useqacontact") ? 1 : 0) +
+ (user.is_timetracker ? 3 : 0)
+ %]
+
+ <td rowspan="[% num_rows FILTER html %]">
+ [% IF product.flag_types.bug.size > 0 %]
+ [% display_flag_headers = 0 %]
+ [% any_flags_requesteeble = 0 %]
+
+ [% FOREACH flag_type = product.flag_types.bug %]
+ [% NEXT UNLESS flag_type.is_active %]
+ [% display_flag_headers = 1 %]
+ [% SET any_flags_requesteeble = 1 IF flag_type.is_requestable && flag_type.is_requesteeble %]
+ [% END %]
+
+ [% IF display_flag_headers %]
+ [% PROCESS "flag/list.html.tmpl" flag_types = product.flag_types.bug
+ any_flags_requesteeble = any_flags_requesteeble
+ flag_table_id = "bug_flags"
+ %]
+ [% END %]
+ [% END %]
+ </td>
+ -->
+ </div>
+ </div>
+ </div>
+</div>
+
+
+<div class="row expert_fields">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>Assignee</b>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ <!--
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.assigned_to editable = 1
+ %]
+
+ <!-- TODO: show suggestions -->
+ [% INCLUDE global/userselect.html.tmpl
+ id => "assigned_to"
+ name => "assigned_to"
+ value => assigned_to
+ disabled => assigned_to_disabled
+ size => 30
+ emptyok => 1
+ custom_userlist => assignees_list
+ %]
+ </div>
+ </div>
+ </div>
+ </div>
+
+
+<div class="row expert_fields">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>CC</b>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ <!--
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.cc editable = 1
+ %]
+
+ -->
+
+ [% INCLUDE global/userselect.html.tmpl
+ id => "cc"
+ name => "cc"
+ value => cc
+ disabled => cc_disabled
+ size => 30
+ multiple => 5
+ %]
+ </div>
+ </div>
+ </div>
+</div>
+
+<div class="row expert_fields">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>Default CC</b>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ <div id="initial_cc">
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+
+<div class="row expert_fields">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>Alias</b>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ <input name="alias" size="20" value="[% alias FILTER html %]">
+ </div>
+ </div>
+ </div>
+</div>
+
+<div class="row expert_fields">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>URL</b>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ <input name="bug_file_loc" id="bug_file_loc" class="text_input"
+ size="40" value="[% bug_file_loc FILTER html %]">
+ </div>
+ </div>
+ </div>
+</div>
+
+
+[% IF user.is_timetracker %]
+ <div class="row expert_fields">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>Orig. Est.</b>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ <input name="estimated_time" size="6" maxlength="6" value="[% estimated_time FILTER html %]">
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="row expert_fields">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>Deadline</b>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ [% INCLUDE bug/field.html.tmpl
+ bug = default, field = bug_fields.deadline, value = deadline, no_tds = 1,
+ editable = 1, value_span = 2 %]
+ </div>
+ </div>
+ </div>
+ </div>
+[% END %]
+
+<div class="row expert_fields">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>Arches</b>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ [% Hook.process("after_cc_field") %]
+ </div>
+ </div>
+ </div>
+</div>
+
+ <div class="row">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>Summary</b>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ <input name="short_desc" size="70" value="[% short_desc FILTER html %]"
+ maxlength="255" spellcheck="true" aria-required="true"
+ class="text_input form-control selectwidthauto" id="short_desc">
+ </div>
+ </div>
+ </div>
+ </div>
+
+[% IF feature_enabled('jsonrpc') AND !cloned_bug_id AND user.settings.possible_duplicates.value == 'on' %]
+ <div class="row">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>Possible Duplicates</b>
+ </div>
+ <div class="col-sm-10">
+
+ <div id="possible_duplicates"></div>
+ <script type="text/javascript">
+ var dt_columns = [
+ { key: "id", label: "[% field_descs.bug_id FILTER js %]",
+ formatter: YAHOO.bugzilla.dupTable.formatBugLink },
+ { key: "summary",
+ label: "[% field_descs.short_desc FILTER js %]",
+ formatter: "text" },
+ { key: "status",
+ label: "[% field_descs.bug_status FILTER js %]",
+ formatter: YAHOO.bugzilla.dupTable.formatStatus },
+ { key: "update_token", label: '',
+ formatter: YAHOO.bugzilla.dupTable.formatCcButton }
+ ];
+ YAHOO.bugzilla.dupTable.addCcMessage = "Add Me to the CC List";
+ YAHOO.bugzilla.dupTable.init({
+ container: 'possible_duplicates',
+ columns: dt_columns,
+ product_name: '[% product.name FILTER js %]',
+ summary_field: 'short_desc',
+ options: {
+ MSG_LOADING: 'Searching for possible duplicates...',
+ MSG_EMPTY: 'No possible duplicates found.',
+ SUMMARY: 'Possible Duplicates'
+ }
+ });
+ </script>
+
+ </div>
+ </div>
+[% END %]
+
+
+ <div class="row">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>Description</b>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ [% defaultcontent = BLOCK %]
+ [%-# We are within a BLOCK. The comment will be correctly HTML-escaped
+ # by global/textarea.html.tmpl. So we must not escape the comment here. %]
+ [% comment FILTER none %]
+ [%- END %]
+ [% INCLUDE bug/comment.html.tmpl
+ minrows = 10
+ maxrows = 25
+ cols = constants.COMMENT_COLS
+ defaultcontent = defaultcontent
+ %]
+ </div>
+ </div>
+ </div>
+ </div>
+
+
+ [% IF Param('use_see_also') %]
+ <div class="row expert_fields">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>See also</b>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ [% INCLUDE bug/field.html.tmpl
+ bug = default
+ field = bug_fields.see_also
+ editable = 1
+ value = see_also
+ %]
+ </div>
+ </div>
+ </div>
+ </div>
+ [% END %]
+
+
+
+ [% IF Param("maxattachmentsize") || Param("maxlocalattachment") %]
+ <div class="row">
+ <div class="col-sm-2 align-h-right" style="padding-right: 0px;text-align:right;">
+ <b>Attachment</b>
+ </div>
+ <div class="col-sm-10">
+ <div class="row">
+ <div class="col-sm-12">
+ <div id="attachment_false" class="bz_default_hidden">
+ <input class="btn btn-default" type="button" value="Add an attachment" onClick="handleWantsAttachment(true)">
+ </div>
+
+ <div id="attachment_true">
+ <input type="button" id="btn_no_attachment" value="Don't add an attachment"
+ class="bz_default_hidden" onClick="handleWantsAttachment(false)">
+ <fieldset>
+ <legend>Add an attachment</legend>
+ <table class="attachment_entry">
+ [% PROCESS attachment/createformcontents.html.tmpl
+ flag_types = product.flag_types.attachment
+ any_flags_requesteeble = 1
+ flag_table_id ="attachment_flags" %]
+ </table>
+ </fieldset>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+[% END %]
+
+
+
+<!-- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
+<!-- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
+<!-- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
+<!-- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
+<!-- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
+
+
+
+
+
+
+
+[% IF Param("useqacontact") %]
+<div class="panel panel-default expert_fields">
+<div class="panel-heading">
+ <h3 class="panel-title">QA Contract</h3>
+</div>
+<div class="panel-body" >
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.qa_contact editable = 1
+ %]
+
+ <!--
+ <td colspan="2">
+ [% INCLUDE global/userselect.html.tmpl
+ id => "qa_contact"
+ name => "qa_contact"
+ value => qa_contact
+ disabled => qa_contact_disabled
+ size => 30
+ emptyok => 1
+ custom_userlist => qa_contacts_list
+ %]
+ <noscript>(Leave blank to assign to default qa contact)</noscript>
+ -->
+
+</div>
+</div>
+[% END %]
+
+
+
+
+
+
+
+
+
+[% USE Bugzilla %]
+
+[% FOREACH field = Bugzilla.active_custom_fields %]
+[% NEXT UNLESS field.enter_bug %]
+[% SET value = ${field.name}.defined ? ${field.name} : "" %]
+<tr [% 'class="expert_fields"' IF !field.is_mandatory %]>
+[% INCLUDE bug/field.html.tmpl
+bug = default, field = field, value = value, editable = 1,
+value_span = 3 %]
+</tr>
+[% END %]
+
+
+
+
+
+[% IF user.is_insider %]
+<tr class="expert_fields">
+<th>&nbsp;</th>
+<td colspan="3">
+ &nbsp;&nbsp;
+ <input type="checkbox" id="comment_is_private" name="comment_is_private"
+ [% ' checked="checked"' IF comment_is_private %]
+ onClick="updateCommentTagControl(this, 'comment')">
+ <label for="comment_is_private">
+ Make description and any new attachment private (visible only to members
+ of the <strong>[% Param('insidergroup') FILTER html %]</strong> group)
+ </label>
+</td>
+</tr>
+<script>
+updateCommentTagControl(document.getElementById('comment_is_private'), 'comment');
+</script>
+[% END %]
+
+[% IF use_keywords %]
+<div class="panel panel-default">
+<div class="panel-heading">
+ <h3 class="panel-title">Keywords</h3>
+</div>
+<div class="panel-body" >
+ [% INCLUDE bug/field.html.tmpl
+ bug = default, field = bug_fields.keywords, editable = 1,
+ value = keywords, possible_values = all_keywords,
+ desc_url = "describekeywords.cgi", value_span = 3
+ %]
+</div>
+</div>
+[% END %]
+
+
+
+
+<table>
+
+<tbody class="expert_fields">
+ <tr>
+ [% IF Param('usetargetmilestone') && Param('letsubmitterchoosemilestone') %]
+ [% INCLUDE select field = bug_fields.target_milestone %]
+ [% ELSE %]
+ <td colspan="2">&nbsp;</td>
+ [% END %]
+
+ <td colspan="2">&nbsp;</td>
+ </tr>
+</tbody>
+
+
+
+<tbody class="expert_fields">
+ [% IF product.groups_available.size %]
+ <tr>
+ <th>&nbsp;</th>
+ <td colspan="3">
+ <br>
+ <strong>
+ Only users in [%+ IF Param('or_groups') %]at least one[% ELSE %]all[% END %] of the selected groups can view this
+ [%+ terms.bug %]:
+ </strong>
+ <br>
+ <span class="bz_info">
+ (Leave all boxes unchecked to make this a public [% terms.bug %].)
+ </span>
+ <br>
+ <br>
+
+ <!-- Checkboxes -->
+ <input type="hidden" name="defined_groups" value="1">
+ [% FOREACH group = product.groups_available %]
+ <input type="checkbox" id="group_[% group.id FILTER html %]"
+ name="groups" value="[% group.name FILTER html %]"
+ [% ' checked="checked"' IF default.groups.contains(group.name)
+ OR group.is_default %]>
+ <label for="group_[% group.id FILTER html %]">
+ [%- group.description FILTER html_light %]</label><br>
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+</tbody>
+</table>
+
+
+[%# Form controls for entering additional data about the bug being created. %]
+[% Hook.process("form") %]
+
+<hr/>
+<input class="btn btn-primary pull-right" type="submit" id="commit" value="Submit [% terms.Bug %]">
+&nbsp;&nbsp;&nbsp;&nbsp;
+<input class="btn btn-default pull-right expert_fields" type="submit" name="maketemplate" id="maketemplate"
+ value="Remember values as bookmarkable template"
+ onclick="bz_no_validate_enter_bug=true" style="margin-right:10px;">
+<input type="hidden" name="form_name" value="enter_bug">
+
+
+</form>
+</div>
+</div>
+
+<br/>
+<br/>
+
+[%# Links or content with more information about the bug being created. %]
+[% Hook.process("end") %]
+
+[% PROCESS global/footer.html.tmpl %]
+
+[%############################################################################%]
+[%# Block for SELECT fields #%]
+[%############################################################################%]
+
+[% BLOCK select %]
+
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = field editable = 1
+ %]
+ <td>
+ <select name="[% field.name FILTER html %]"
+ id="[% field.name FILTER html %]">
+ [%- FOREACH x = ${field.name} %]
+ [% NEXT IF NOT x.is_active %]
+ <option value="[% x.name FILTER html %]"
+ [% " selected=\"selected\"" IF x.name == default.${field.name} %]>
+ [% display_value(field.name, x.name) FILTER html %]
+ </option>
+ [% END %]
+ </select>
+ </td>
+[% END %]
+
+[% BLOCK build_userlist %]
+ [% user_found = 0 %]
+ [% default_login = default_user.login %]
+ [% RETURN UNLESS default_login %]
+
+ [% FOREACH user = userlist %]
+ [% IF user.login == default_login %]
+ [% user_found = 1 %]
+ [% LAST %]
+ [% END %]
+ [% END %]
+
+ [% userlist.push({login => default_login,
+ identity => default_user.identity,
+ visible => 1})
+ UNLESS user_found %]
+[% END %]
diff --git a/template/en/custom/bug/create/user-message.html.tmpl b/template/en/custom/bug/create/user-message.html.tmpl
new file mode 100644
index 000000000..1aa0052f5
--- /dev/null
+++ b/template/en/custom/bug/create/user-message.html.tmpl
@@ -0,0 +1,24 @@
+[%# 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.
+ #%]
+
+[%# Migration note: this file corresponds to the old Param
+ # 'entryheaderhtml'
+ #%]
+
+[%# You can make the output of this template product-specific by using
+ # Template Toolkit IF statements. The current product name is stored in
+ # the 'product' variable.
+ #%]
+
+<div class="well" role="alert" style="margin-bottom:40px;">
+Before reporting [% terms.abug %], please read the
+<a href="https://www.gentoo.org/doc/en/bugzilla-howto.xml">
+[% terms.bug %] writing guidelines</a>, please look at the list of
+<a href="duplicates.cgi">most frequently reported [% terms.bugs %]</a>, and please
+<a href="query.cgi?format=specific">search</a> (<a href="query.cgi">advanced</a>) for the [% terms.bug %].
+</div> \ No newline at end of file
diff --git a/template/en/custom/bug/edit.html.tmpl b/template/en/custom/bug/edit.html.tmpl
new file mode 100644
index 000000000..680fa7187
--- /dev/null
+++ b/template/en/custom/bug/edit.html.tmpl
@@ -0,0 +1,1612 @@
+[%# 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 bug/time.html.tmpl %]
+
+[% IF Param('comment_taggers_group') %]
+ [% IF user.can_tag_comments %]
+ <div id="bz_ctag_div" class="bz_default_hidden">
+ <a href="javascript:void(0)" onclick="YAHOO.bugzilla.commentTagging.hideInput()">x</a>
+ <div>
+ <input id="bz_ctag_add" size="10" placeholder="add tag"
+ maxlength="[% constants.MAX_COMMENT_TAG_LENGTH FILTER html %]">
+ <span id="bz_ctag_autocomp"></span>
+ </div>
+ &nbsp;
+ </div>
+ <div id="bz_ctag_error" class="bz_default_hidden">
+ <a href="javascript:void(0)" onclick="YAHOO.bugzilla.commentTagging.hideError()">x</a>
+ <span id="bz_ctag_error_msg"></span>
+ </div>
+ [% END %]
+ [% IF user.id %]
+ <script type="text/javascript">
+ YAHOO.bugzilla.commentTagging.init([% user.can_tag_comments ? 'true' : 'false' %]);
+ YAHOO.bugzilla.commentTagging.min_len = [% constants.MIN_COMMENT_TAG_LENGTH FILTER js %];
+ YAHOO.bugzilla.commentTagging.max_len = [% constants.MAX_COMMENT_TAG_LENGTH FILTER js %];
+ YAHOO.bugzilla.commentTagging.label = 'Comment Tags:';
+ YAHOO.bugzilla.commentTagging.min_len_error =
+ 'Comment tags must be at least
+ [%~ " " _ constants.MIN_COMMENT_TAG_LENGTH FILTER js %] characters.';
+ YAHOO.bugzilla.commentTagging.max_len_error =
+ 'Comment tags cannot be longer than
+ [%~ " " _ constants.MAX_COMMENT_TAG_LENGTH FILTER js %] characters.';
+ </script>
+ [% END %]
+[% END %]
+
+<script type="text/javascript">
+<!--
+[% IF user.is_timetracker %]
+ var bz_remaining_time = [% bug.remaining_time %];
+[% END %]
+
+[% IF user.id %]
+ /* Index all classifications so we can keep track of the classification
+ * for the selected product, which could control field visibility.
+ */
+ var all_classifications = new Array([% bug.choices.product.size %]);
+ [%- FOREACH product = bug.choices.product %]
+ all_classifications['[% product.name FILTER js %]'] = '
+ [%- product.classification.name FILTER js %]';
+ [%- END %]
+[% END %]
+//-->
+</script>
+
+
+<div class="panel panel-default">
+ <div class="panel-body">
+ <div class="row">
+ <div class="col-sm-12">
+ <span class="label label-[% bug.isopened ? 'success' : 'danger' %]">[% bug.isopened ? 'Open' : 'Closed' %]</span>
+ &nbsp;<a style="color:#000000;" href="show_bug.cgi?id=[% bug.bug_id %]">[% terms.Bug %]&nbsp;[% bug.bug_id FILTER html %]</a>
+
+ <span id="summary_container" class="bz_default_hidden">
+ [% IF bug.alias.size > 0 %]
+ (<span id="alias_nonedit_display">[% bug.alias.join(', ') FILTER html %]</span>)
+ [% END %]
+
+ <small style="margin-left:5px;color:#505152;">Created: [% bug.creation_ts FILTER time("%Y-%m-%d %H:%M %Z") %]</small>
+ <small style="margin-left:5px;color:#505152;">Updated: [% bug.delta_ts FILTER time("%Y-%m-%d %H:%M %Z") %]</small>
+
+ </span>
+
+ </div>
+
+ <div class="col-sm-12">
+ <h1 style="font-size: 20px;margin-top:10px;margin-bottom:4px;"><span id="short_desc_nonedit_display">[% bug.short_desc FILTER quoteUrls(bug) %]</span></h1>
+ </div>
+ </div>
+ </div>
+</div>
+
+<!--
+[% can_edit_short_desc = bug.check_can_change_field('short_desc', 0, 1) %]
+[% IF can_edit_short_desc %]
+ <small>(<a href="#" id="summary_edit_action">edit</a>)</small>
+ [% END %]
+-->
+
+<div class="panel panel-default">
+<div class="panel-heading" style="padding-left: 8px; padding-right: 8px; padding-top: 4px; padding-bottom: 4px;font-weight:bold;font-size:13px;">
+ <i class="fa fa-caret-down" aria-hidden="true" style="margin-right:5px;cursor: pointer"></i> Categories
+</div>
+<div class="panel-body">
+ <div class="row">
+ <div class="col-sm-6">
+ <div class="row" style="margin-bottom:2px;">
+ <div class="col-sm-2 align-h-right" style="padding-right:0px;color:#505050;">
+ <small>Product:</small>
+ </div>
+ <div class="col-sm-10" style="color:#292929;padding-left:10px;">
+ <small>[%+ bug.product %]</small>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-sm-2 align-h-right" style="padding-right:0px;color:#505050;">
+ <small>Component:</small>
+ </div>
+ <div class="col-sm-10" style="color:#292929;padding-left:10px;">
+ <small>[%+ bug.component %]</small>
+ </div>
+ </div>
+ </div>
+
+ <div class="col-sm-6">
+ <div class="row equal">
+ <div class="col-sm-2 align-h-right" style="padding-right:0px;color:#505050;">
+ <small>Severity:</small>
+ </div>
+ <div class="col-sm-10" style="color:#292929;padding-left:10px;">
+ <small>[%+ bug.bug_severity %]</small>
+ </div>
+ </div>
+
+ <div class="row equal">
+ <div class="col-sm-2 align-h-right" style="padding-right:0px;color:#505050;">
+ <small>Priority:</small>
+ </div>
+ <div class="col-sm-10" style="color:#292929;padding-left:10px;">
+ <small>[%+ bug.priority %]</small>
+ </div>
+ </div>
+ </div>
+
+ </div>
+</div>
+</div>
+
+
+<div class="panel panel-default">
+<div class="panel-heading" style="padding-left: 8px; padding-right: 8px; padding-top: 4px; padding-bottom: 4px;font-weight:bold;font-size:13px;">
+ <i class="fa fa-caret-down" aria-hidden="true" style="margin-right:5px;cursor: pointer"></i> Tracking
+</div>
+<div class="panel-body">
+ <div class="row">
+ <div class="col-sm-6">
+ <div class="row" style="margin-bottom:2px;">
+ <div class="col-sm-2 align-h-right" style="padding-right:0px;color:#505050;">
+ <small>Status:</small>
+ </div>
+ <div class="col-sm-10" style="color:#292929;padding-left:10px;">
+ <small>[%+ display_value("bug_status", bug.bug_status) FILTER html %]</small>
+ </div>
+ </div>
+ </div>
+
+ </div>
+</div>
+</div>
+
+
+<div class="panel panel-default">
+<div class="panel-heading" style="padding-left: 8px; padding-right: 8px; padding-top: 4px; padding-bottom: 4px;font-weight:bold;font-size:13px;">
+ <i class="fa fa-caret-down" aria-hidden="true" style="margin-right:5px;cursor: pointer"></i> People
+</div>
+<div class="panel-body">
+ <div class="row">
+ <div class="col-sm-6">
+ <div class="row" style="margin-bottom:2px;">
+ <div class="col-sm-2 align-h-right" style="padding-right:0px;color:#505050;">
+ <small>Assignee:</small>
+ </div>
+ <div class="col-sm-10" style="color:#292929;padding-left:10px;">
+ <small>[%+ bug.assigned_to.name %]</small>
+ </div>
+ </div>
+ </div>
+
+ <div class="col-sm-6">
+ <div class="row equal">
+ <div class="col-sm-2 align-h-right" style="padding-right:0px;color:#505050;">
+ <small>Reporter:</small>
+ </div>
+ <div class="col-sm-10" style="color:#292929;padding-left:10px;">
+ <small>[% INCLUDE global/user.html.tmpl who = bug.reporter %]</small>
+ </div>
+ </div>
+
+ <div class="row equal">
+ <div class="col-sm-2 align-h-right" style="padding-right:0px;color:#505050;">
+ <small>CC:</small>
+ </div>
+ <div class="col-sm-10" style="color:#292929;padding-left:10px;">
+ <small><i class="fa fa-caret-right" aria-hidden="true" style="margin-right:5px;cursor: pointer;"></i> [% bug.cc.size FILTER html %]
+ [% IF bug.cc.size == 1 %]
+ user
+ [% ELSE %]
+ users
+ [% END %]
+ [% IF user.id %]
+ [% IF bug.cc.contains( user.email ) %]
+ including you
+ [% END %]
+ [% END %]</small><button class="btn btn-default btn-xs" style="margin-left:5px;">Add</button>
+ </div>
+ </div>
+ </div>
+
+ </div>
+</div>
+</div>
+
+<div class="panel panel-default">
+<div class="panel-heading" style="padding-left: 8px; padding-right: 8px; padding-top: 4px; padding-bottom: 4px;font-weight:bold;font-size:13px;">
+ <i class="fa fa-caret-down" aria-hidden="true" style="margin-right:5px;cursor: pointer"></i> Details
+</div>
+<div class="panel-body">
+ <div class="row">
+ <div class="col-sm-6">
+ <div class="row" style="margin-bottom:2px;">
+ <div class="col-sm-2 align-h-right" style="padding-right:0px;color:#505050;">
+ <small>Hardware:</small>
+ </div>
+ <div class="col-sm-10" style="color:#292929;padding-left:10px;">
+ <small>[% INCLUDE bug/field.html.tmpl
+ bug = bug, field = bug_fields.rep_platform,
+ no_tds = 1, value = bug.rep_platform
+ editable = can_edit_rep_platform %]
+ [%+ INCLUDE bug/field.html.tmpl
+ bug = bug, field = bug_fields.op_sys,
+ no_tds = 1, value = bug.op_sys
+ editable = 0 %]</small>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-sm-2 align-h-right" style="padding-right:0px;color:#505050;">
+ <small>Tags:</small>
+ </div>
+ <div class="col-sm-10" style="color:#292929;padding-left:10px;">
+ <small>[% IF user.id %]
+ [% INCLUDE bug/field.html.tmpl
+ bug = bug, field = bug_fields.tag, value = bug.tags.join(", "),
+ editable = 0, no_tds=1, possible_values = user.tags.keys
+ %]
+ [% END %]</small>
+ </div>
+ </div>
+ </div>
+
+ <div class="col-sm-6">
+ <div class="row equal">
+ <div class="col-sm-2 align-h-right" style="padding-right:0px;color:#505050;">
+ <small>Flags:</small>
+ </div>
+ <div class="col-sm-10" style="color:#292929;padding-left:10px;">
+ <small><i class="fa fa-caret-right" aria-hidden="true" style="margin-right:5px;cursor: pointer;"></i> [%+ bug.flag_types.size %] Flags</small>
+ </div>
+ </div>
+
+ <div class="row equal">
+ <div class="col-sm-2 align-h-right" style="padding-right:0px;color:#505050;">
+ <small>URL:</small>
+ </div>
+ <div class="col-sm-10" style="color:#292929;padding-left:10px;">
+ <small>[% bug.bug_file_loc FILTER html %]</small>
+ </div>
+ </div>
+ </div>
+
+ </div>
+</div>
+</div>
+
+
+<div class="panel panel-default">
+<div class="panel-heading" style="padding-left: 8px; padding-right: 8px; padding-top: 4px; padding-bottom: 4px;font-weight:bold;font-size:13px;">
+ <i class="fa fa-caret-right" aria-hidden="true" style="margin-right:5px;cursor: pointer"></i> Dependencies
+</div>
+<div class="panel-body" style="display:none;">
+ <div class="row">
+ <div class="col-sm-6">
+ <div class="row" style="margin-bottom:2px;">
+ <div class="col-sm-2 align-h-right" style="padding-right:0px;color:#505050;">
+ <small>Depends on:</small>
+ </div>
+ <div class="col-sm-10" style="color:#292929;padding-left:10px;">
+ <small>[%+ bug.assigned_to.name %]</small>
+ </div>
+ </div>
+ </div>
+
+ <div class="col-sm-6">
+ <div class="row equal">
+ <div class="col-sm-2 align-h-right" style="padding-right:0px;color:#505050;">
+ <small>Blocks:</small>
+ </div>
+ <div class="col-sm-10" style="color:#292929;padding-left:10px;">
+ <small>[% INCLUDE global/user.html.tmpl who = bug.reporter %]</small>
+ </div>
+ </div>
+ </div>
+
+ </div>
+</div>
+</div>
+
+
+<div class="panel panel-default">
+<div class="panel-heading" style="padding-left: 8px; padding-right: 8px; padding-top: 4px; padding-bottom: 4px;font-weight:bold;font-size:13px;">
+ <i class="fa fa-caret-right" aria-hidden="true" style="margin-right:5px;cursor: pointer"></i> Time Tracking Data
+</div>
+<div class="panel-body" style="display:none;">
+ <div class="row">
+ <div class="col-sm-6">
+ <div class="row" style="margin-bottom:2px;">
+ <div class="col-sm-2 align-h-right" style="padding-right:0px;color:#505050;">
+ <small>Depends on:</small>
+ </div>
+ <div class="col-sm-10" style="color:#292929;padding-left:10px;">
+ <small>[%+ bug.assigned_to.name %]</small>
+ </div>
+ </div>
+ </div>
+
+ <div class="col-sm-6">
+ <div class="row equal">
+ <div class="col-sm-2 align-h-right" style="padding-right:0px;color:#505050;">
+ <small>Blocks:</small>
+ </div>
+ <div class="col-sm-10" style="color:#292929;padding-left:10px;">
+ <small>[% INCLUDE global/user.html.tmpl who = bug.reporter %]</small>
+ </div>
+ </div>
+ </div>
+
+ </div>
+</div>
+</div>
+
+
+[%# *** Attachments *** %]
+
+[% PROCESS attachment/list.html.tmpl
+attachments = bug.attachments
+bugid = bug.bug_id
+num_attachment_flag_types = bug.num_attachment_flag_types
+show_attachment_flags = bug.show_attachment_flags
+%]
+
+
+<div class="panel panel-default" style="display:none;">
+<div class="panel-body">
+<form name="changeform" id="changeform" method="post" action="process_bug.cgi">
+
+ <input type="hidden" name="delta_ts" value="[% bug.delta_ts %]">
+ <input type="hidden" name="id" value="[% bug.bug_id %]">
+ <input type="hidden" name="token" value="[% issue_hash_token([bug.id, bug.delta_ts]) FILTER html %]">
+
+ [% PROCESS section_title %]
+ <table class="edit_form">
+ <tr>
+ [%# 1st Column %]
+ <td id="bz_show_bug_column_1" class="bz_show_bug_column">
+ <table>
+ [%# *** ID, product, component, status, resolution, Hardware, and OS *** %]
+ [% PROCESS section_status %]
+
+ [% PROCESS section_spacer %]
+
+ [% PROCESS section_aliases %]
+
+ [% PROCESS section_spacer %]
+
+ [% PROCESS section_details1 %]
+
+ [% PROCESS section_spacer %]
+
+ [%# *** severity, priority, version, milestone, and deadline *** %]
+ [% PROCESS section_details2 %]
+
+ [%# *** assigned to and qa contact *** %]
+ [% PROCESS section_people %]
+
+ [% PROCESS section_spacer %]
+
+ [% PROCESS section_url_keyword_whiteboard %]
+
+ [% PROCESS section_spacer %]
+
+ [%# *** Dependencies and duplicates *** %]
+ [% PROCESS section_duplicates %]
+
+ [% PROCESS section_dependson_blocks %]
+
+ </table>
+ </td>
+ <td>
+ <div class="bz_column_spacer">&nbsp;</div>
+ </td>
+ [%# 2nd Column %]
+ <td id="bz_show_bug_column_2" class="bz_show_bug_column">
+ <table>
+ [%# *** Reported and modified dates *** %]
+ [% PROCESS section_dates %]
+
+ [% PROCESS section_cclist %]
+
+ [% PROCESS section_bug_ignored %]
+
+ [% PROCESS section_spacer %]
+
+ [% PROCESS section_see_also %]
+
+ [% PROCESS section_customfields %]
+
+ [% PROCESS section_spacer %]
+
+ [% Hook.process("after_custom_fields") %]
+
+ [% PROCESS section_flags %]
+
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="3">
+ [% PROCESS commit_button id="_top"%]
+ </td>
+ </tr>
+
+ <tr>
+ <td colspan="3">
+ <hr id="bz_top_half_spacer">
+ </td>
+ </tr>
+ </table>
+</div>
+</div>
+
+ <table id="bz_big_form_parts" style="display:none;">
+ <tr>
+ <td>
+ [% IF user.is_timetracker %]
+ [% PROCESS section_timetracking %]
+ [% END %]
+
+ [%# *** Attachments *** %]
+
+ [% PROCESS attachment/list.html.tmpl
+ attachments = bug.attachments
+ bugid = bug.bug_id
+ num_attachment_flag_types = bug.num_attachment_flag_types
+ show_attachment_flags = bug.show_attachment_flags
+ %]
+
+ </td>
+ <td>
+ [% PROCESS section_restrict_visibility %]
+ </td>
+ </tr></table>
+
+ [% IF user.settings.comment_box_position.value == 'before_comments' %]
+ [% PROCESS comment_box %]
+ [% END %]
+
+ [%# *** Additional Comments *** %]
+ <div id="comments">
+ [% PROCESS bug/comments.html.tmpl
+ comments = bug.comments
+ mode = user.id ? "edit" : "show"
+ %]
+ </div>
+
+ [% IF user.settings.comment_box_position.value == 'after_comments' %]
+ <hr>
+ [% PROCESS comment_box %]
+ [% END %]
+
+</form>
+
+[%############################################################################%]
+[%# Block for the Title (alias and short desc) #%]
+[%############################################################################%]
+
+[% BLOCK section_title %]
+ [%# That's the main table, which contains all editable fields. %]
+
+<!--
+ <div class="bz_short_desc_container edit_form">
+ [% PROCESS commit_button id="_top"%]
+ <a href="show_bug.cgi?id=[% bug.bug_id %]">
+ [%-# %]<b>[% terms.Bug %]&nbsp;[% bug.bug_id FILTER html %]</b>
+ [%-# %]</a> <span id="summary_container" class="bz_default_hidden">
+ [% IF bug.alias.size > 0 %]
+ (<span id="alias_nonedit_display">[% bug.alias.join(', ') FILTER html %]</span>)
+ [% END %]
+ - <span id="short_desc_nonedit_display">[% bug.short_desc FILTER quoteUrls(bug) %]</span>
+ [% can_edit_short_desc = bug.check_can_change_field('short_desc', 0, 1) %]
+ [% IF can_edit_short_desc %]
+ <small>(<a href="#" id="summary_edit_action">edit</a>)</small>
+ [% END %]
+ </span>
+
+ <div id="summary_input">
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.short_desc
+ editable = can_edit_short_desc
+ accesskey = "s"
+ tag_name = 'span'
+ %]
+ [% PROCESS input inputname => "short_desc" size => "80"
+ maxlength => 255 spellcheck => "true" no_td => 1 %]
+ </div>
+ </div>
+-->
+
+
+ <script type="text/javascript">
+ hideEditableField('summary_container',
+ 'summary_input',
+ 'summary_edit_action',
+ 'short_desc',
+ '[% bug.short_desc FILTER js %]' );
+ </script>
+[% END %]
+
+[%############################################################################%]
+[%# Block for the first table in the "Details" section #%]
+[%############################################################################%]
+
+[% BLOCK section_details1 %]
+
+ [%#############%]
+ [%# PRODUCT #%]
+ [%#############%]
+ <tr>
+ [% INCLUDE bug/field.html.tmpl
+ bug = bug, field = bug_fields.product, value = bug.product
+ override_legal_values = bug.choices.product
+ desc_url = "describecomponents.cgi"
+ editable = bug.check_can_change_field('product', 0, 1)
+ %]
+ </tr>
+
+ [%# Classification is here so that it can be used in value controllers
+ # and visibility controllers. It comes after product because
+ # it uses some javascript that depends on the existence of the
+ # product field.
+ #%]
+ <tr class="bz_default_hidden">
+ [% INCLUDE bug/field.html.tmpl
+ bug = bug field = bug_fields.classification
+ override_legal_values = bug.choices.classification
+ value = bug.classification
+ editable = bug.check_can_change_field('product', 0, 1) %]
+ </tr>
+ [%###############%]
+ [%# Component #%]
+ [%###############%]
+ <tr>
+ [% INCLUDE bug/field.html.tmpl
+ bug = bug, field = bug_fields.component, value = bug.component
+ override_legal_values = bug.choices.component
+ desc_url = "describecomponents.cgi?product=$bug.product"
+ editable = bug.check_can_change_field('component', 0, 1)
+ %]
+ </tr>
+ [%############%]
+ [%# PLATFORM #%]
+ [%############%]
+ <tr>
+ [% can_edit_rep_platform = bug.check_can_change_field('rep_platform', 0, 1) %]
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.rep_platform,
+ editable = can_edit_rep_platform,
+ accesskey = "h" %]
+ <td class="field_value">
+ [% INCLUDE bug/field.html.tmpl
+ bug = bug, field = bug_fields.rep_platform,
+ no_tds = 1, value = bug.rep_platform
+ editable = can_edit_rep_platform %]
+ [%+ INCLUDE bug/field.html.tmpl
+ bug = bug, field = bug_fields.op_sys,
+ no_tds = 1, value = bug.op_sys
+ editable = bug.check_can_change_field('op_sys', 0, 1) %]
+ </td>
+ </tr>
+
+
+
+[% END %]
+
+[%############################################################################%]
+[%# Block for the status section #%]
+[%############################################################################%]
+
+[% BLOCK section_status %]
+ <tr>
+ <th class="field_label">
+ <a href="page.cgi?id=fields.html#bug_status">Status</a>:
+ </th>
+ <td id="bz_field_status">
+ <span id="static_bug_status">
+ [% display_value("bug_status", bug.bug_status) FILTER html %]
+ [% IF bug.resolution %]
+ [%+ display_value("resolution", bug.resolution) FILTER html %]
+ [% IF bug.dup_id %]
+ of [% "${terms.bug} ${bug.dup_id}" FILTER bug_link(bug.dup_id) FILTER none %]
+ [% END %]
+ [% END %]
+ [% IF bug.user.canedit || bug.user.isreporter %]
+ (<a href="#add_comment"
+ onclick="window.setTimeout(function() { document.getElementById('bug_status').focus(); }, 10)">edit</a>)
+ [% END %]
+ </span>
+ </td>
+ </tr>
+[% END %]
+
+[%############################################################################%]
+[%# Block for the second table in the "Details" section #%]
+[%############################################################################%]
+
+[% BLOCK section_details2 %]
+
+ [%###############################################################%]
+ [%# Importance (priority and severity) #%]
+ [%###############################################################%]
+ <tr>
+ <th class="field_label">
+ [% can_edit_priority = bug.check_can_change_field('priority', 0, 1) %]
+ <label [% IF can_edit_priority %]for="priority"[% END %] accesskey="i">
+ <a href="page.cgi?id=fields.html#importance"><u>I</u>mportance</a></label>:
+ </th>
+ <td>
+ [% INCLUDE bug/field.html.tmpl
+ bug = bug, field = bug_fields.priority,
+ no_tds = 1, value = bug.priority
+ editable = can_edit_priority %]
+ [%+ INCLUDE bug/field.html.tmpl
+ bug = bug, field = bug_fields.bug_severity,
+ no_tds = 1, value = bug.bug_severity
+ editable = bug.check_can_change_field('bug_severity', 0, 1) %]
+ [% Hook.process('after_importance', 'bug/edit.html.tmpl') %]
+ </td>
+ </tr>
+
+ [% IF Param("usetargetmilestone") && bug.target_milestone %]
+ <tr>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.target_milestone
+ editable = bug.check_can_change_field('target_milestone', 0, 1)
+ %]
+ [% PROCESS select selname = "target_milestone" %]
+ </tr>
+ [% END %]
+
+ [% IF Param("timetrackinggroup") && bug.deadline %]
+ <tr>
+ <th class="field_label">
+ <a href="page.cgi?id=fields.html#deadline">Deadline</a>:
+ </th>
+ <td>[% bug.deadline FILTER html %]</td>
+ </tr>
+ [% END %]
+[% END %]
+
+[%############################################################################%]
+[%# Block for the table in the "People" section #%]
+[%############################################################################%]
+
+[% BLOCK section_people %]
+
+ <tr>
+ [% can_edit_assigned_to = bug.check_can_change_field("assigned_to", 0, 1) %]
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.assigned_to
+ editable = can_edit_assigned_to
+ %]
+ <td>
+ [% IF can_edit_assigned_to %]
+ <div id="bz_assignee_edit_container" class="bz_default_hidden">
+ <span>
+ [% INCLUDE global/user.html.tmpl who = bug.assigned_to %]
+ (<a href="#" id="bz_assignee_edit_action">edit</a>)
+ [% IF bug.assigned_to.id != user.id %]
+ (<a title="Reassign to yourself"
+ href="#" id="bz_assignee_take_action">take</a>)
+ [% END %]
+ </span>
+ </div>
+ <div id="bz_assignee_input">
+ [% INCLUDE global/userselect.html.tmpl
+ id => "assigned_to"
+ name => "assigned_to"
+ value => bug.assigned_to.login
+ classes => ["bz_userfield"]
+ size => 30
+ %]
+ <br>
+ <input type="checkbox" id="set_default_assignee" name="set_default_assignee" value="1">
+ <label id="set_default_assignee_label" for="set_default_assignee">Reset Assignee to default</label>
+ </div>
+ <script type="text/javascript">
+ hideEditableField('bz_assignee_edit_container',
+ 'bz_assignee_input',
+ 'bz_assignee_edit_action',
+ 'assigned_to',
+ '[% bug.assigned_to.login FILTER js %]' );
+ hideEditableField('bz_assignee_edit_container',
+ 'bz_assignee_input',
+ 'bz_assignee_take_action',
+ 'assigned_to',
+ '[% bug.assigned_to.login FILTER js %]',
+ '[% user.login FILTER js %]' );
+ initDefaultCheckbox('assignee');
+ </script>
+ [% ELSE %]
+ [% INCLUDE global/user.html.tmpl who = bug.assigned_to %]
+ [% END %]
+ </td>
+ </tr>
+
+ [% IF Param('useqacontact') %]
+ <tr>
+ [% can_edit_qa_contact = bug.check_can_change_field("qa_contact", 0, 1) %]
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.qa_contact
+ editable = can_edit_qa_contact
+ accesskey = "q"
+ %]
+ <td>
+ [% IF can_edit_qa_contact %]
+ <div id="bz_qa_contact_edit_container" class="bz_default_hidden">
+ <span>
+ [% INCLUDE global/user.html.tmpl who = bug.qa_contact %]
+ (<a href="#" id="bz_qa_contact_edit_action">edit</a>)
+ [% IF bug.qa_contact.id != user.id %]
+ (<a title="Change QA contact to yourself"
+ href="#" id="bz_qa_contact_take_action">take</a>)
+ [% END %]
+ </span>
+ </div>
+ <div id="bz_qa_contact_input">
+ [% INCLUDE global/userselect.html.tmpl
+ id => "qa_contact"
+ name => "qa_contact"
+ value => bug.qa_contact.login
+ size => 30
+ classes => ["bz_userfield"]
+ emptyok => 1
+ %]
+ <br>
+ <input type="checkbox" id="set_default_qa_contact" name="set_default_qa_contact" value="1">
+ <label for="set_default_qa_contact" id="set_default_qa_contact_label">Reset QA Contact to default</label>
+ </div>
+ <script type="text/javascript">
+ hideEditableField('bz_qa_contact_edit_container',
+ 'bz_qa_contact_input',
+ 'bz_qa_contact_edit_action',
+ 'qa_contact',
+ '[% bug.qa_contact.login FILTER js %]');
+ hideEditableField('bz_qa_contact_edit_container',
+ 'bz_qa_contact_input',
+ 'bz_qa_contact_take_action',
+ 'qa_contact',
+ '[% bug.qa_contact.login FILTER js %]',
+ '[% user.login FILTER js %]');
+ initDefaultCheckbox('qa_contact');
+ </script>
+ [% ELSE %]
+ [% INCLUDE global/user.html.tmpl who = bug.qa_contact %]
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+ <script type="text/javascript">
+ assignToDefaultOnChange(['product', 'component'],
+ '[% bug.component_obj.default_assignee.login FILTER js %]',
+ '[% bug.component_obj.default_qa_contact.login FILTER js %]');
+ </script>
+[% END %]
+
+[%############################################################################%]
+[%# Block for URL Keyword and Whiteboard #%]
+[%############################################################################%]
+[% BLOCK section_url_keyword_whiteboard %]
+ <tr>
+ [% can_edit_bug_file_loc = bug.check_can_change_field("bug_file_loc", 0, 1) %]
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.bug_file_loc
+ editable = can_edit_bug_file_loc
+ accesskey = "u"
+ %]
+ <td>
+ [% IF can_edit_bug_file_loc %]
+ <span id="bz_url_edit_container" class="bz_default_hidden">
+ [% IF is_safe_url(bug.bug_file_loc) %]
+ <a href="[% bug.bug_file_loc FILTER html %]" target="_blank"
+ rel="noreferrer" title="[% bug.bug_file_loc FILTER html %]">
+ [% bug.bug_file_loc FILTER truncate(40) FILTER html %]</a>
+ [% ELSE %]
+ [% bug.bug_file_loc FILTER html %]
+ [% END %]
+ (<a href="#" id="bz_url_edit_action">edit</a>)</span>
+ [% END %]
+ <span id="bz_url_input_area">
+ [% url_output = INCLUDE input no_td = 1 inputname = "bug_file_loc" size = 40 %]
+ [% IF NOT bug.check_can_change_field("bug_file_loc", 0, 1)
+ AND is_safe_url(bug.bug_file_loc) %]
+ <a href="[% bug.bug_file_loc FILTER html %]"
+ rel="noreferrer">[% url_output FILTER none %]</a>
+ [% ELSE %]
+ [% url_output FILTER none %]
+ [% END %]
+ </span>
+ [% IF bug.check_can_change_field("bug_file_loc", 0, 1) %]
+ <script type="text/javascript">
+ hideEditableField('bz_url_edit_container',
+ 'bz_url_input_area',
+ 'bz_url_edit_action',
+ 'bug_file_loc',
+ "[% bug.bug_file_loc FILTER js %]");
+ </script>
+ [% END %]
+ </td>
+ </tr>
+
+ [% IF Param('usestatuswhiteboard') %]
+ <tr>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.status_whiteboard
+ editable = bug.check_can_change_field("status_whiteboard", 0, 1)
+ accesskey = "w"
+ %]
+ [% INCLUDE input inputname = "status_whiteboard" size = 40 %]
+ </tr>
+ [% END %]
+
+ [% IF use_keywords %]
+ <tr>
+ [% INCLUDE bug/field.html.tmpl
+ bug = bug, field = bug_fields.keywords, value = bug.keywords
+ editable = bug.check_can_change_field("keywords", 0, 1),
+ desc_url = "describekeywords.cgi", possible_values = all_keywords
+ %]
+ </tr>
+ [% END %]
+
+ [% IF user.id %]
+ <tr>
+ [% INCLUDE bug/field.html.tmpl
+ bug = bug, field = bug_fields.tag, value = bug.tags.join(", "),
+ editable = 1, possible_values = user.tags.keys
+ %]
+ </tr>
+ [% END %]
+[% END %]
+
+[%############################################################################%]
+[%# Block for Duplicates #%]
+[%############################################################################%]
+
+[% BLOCK section_duplicates %]
+ [% RETURN UNLESS bug.duplicates.size %]
+ <tr>
+ <th class="field_label">
+ <label>Duplicates ([% bug.duplicates.size %])</label>:
+ </th>
+ <td class="field_value">
+ <span id="duplicates">
+ [% FOREACH dupe = bug.duplicates %]
+ [% INCLUDE bug/link.html.tmpl bug = dupe, link_text = dupe.id, use_alias = 1 %][% " " %]
+ [% END %]
+ </span>
+ (<a href="buglist.cgi?bug_id=[% bug.duplicate_ids.join(",") FILTER html %]">
+ [%-%]view as [% terms.bug %] list</a>)
+ </td>
+ </tr>
+[% END %]
+
+[%############################################################################%]
+[%# Block for Depends On / Blocks #%]
+[%############################################################################%]
+
+[% BLOCK section_dependson_blocks %]
+ <tr>
+ [% INCLUDE dependencies
+ field = bug_fields.dependson deps = bug.depends_on_obj %]
+ </tr>
+
+ <tr>
+ [% INCLUDE dependencies
+ field = bug_fields.blocked deps = bug.blocks_obj %]
+ </tr>
+
+ [% IF bug.dependson.size || bug.blocked.size %]
+ <tr>
+ <th>&nbsp;</th>
+
+ <td id="show_dependency_tree_or_graph">
+ Show dependency <a href="showdependencytree.cgi?id=[% bug.bug_id %]&amp;hide_resolved=1">tree</a>
+
+ [% IF Param('webdotbase') %]
+ /&nbsp;<a href="showdependencygraph.cgi?id=[% bug.bug_id %]">graph</a>
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+[% END %]
+
+
+[%############################################################################%]
+[%# Block for Restricting Visibility #%]
+[%############################################################################%]
+
+[% BLOCK section_restrict_visibility %]
+ [% RETURN UNLESS bug.groups.size %]
+
+ <div class="bz_group_visibility_section">
+ [% inallgroups = 1 %]
+ [% inagroup = 0 %]
+ [% emitted_description = 0 %]
+
+ [% FOREACH group = bug.groups %]
+ [% SET inallgroups = 0 IF NOT group.ingroup %]
+ [% SET inagroup = 1 IF group.ison %]
+
+ [% NEXT IF group.mandatory %]
+
+ [% IF NOT emitted_description %]
+ [% emitted_description = 1 %]
+ <div id="bz_restrict_group_visibility_help">
+ <b>Only users in
+ [%+ IF Param('or_groups') %]at least one[% ELSE %]all[% END %]
+ of the selected groups can view this [% terms.bug %]:</b>
+ <p class="instructions">
+ Unchecking all boxes makes this a more public [% terms.bug %].
+ </p>
+ </div>
+ [% END %]
+
+ [% IF group.ingroup %]
+ <input type="hidden" name="defined_groups"
+ value="[% group.name FILTER html %]">
+ [% END %]
+
+ <input type="checkbox" value="[% group.name FILTER html %]"
+ name="groups" id="group_[% group.bit %]"
+ [% ' checked="checked"' IF group.ison %]
+ [% ' disabled="disabled"' IF NOT group.ingroup %]>
+ <label for="group_[% group.bit %]">
+ [%- group.description FILTER html_light %]</label>
+ <br>
+ [% END %]
+
+ [% IF emitted_description %]
+ [% IF NOT inallgroups %]
+ <p class="instructions">Only members of a group can change the
+ visibility of [% terms.abug %] for that group.</p>
+ [% END %]
+ [% END %]
+
+ [% IF inagroup %]
+ <div id="bz_enable_role_visibility_help">
+ <b>Users in the roles selected below can always view
+ this [% terms.bug %]:</b>
+ </div>
+ <div id="bz_enable_role_visibility">
+ <div>
+ [% user_can_edit_accessible =
+ bug.check_can_change_field("reporter_accessible", 0, 1)
+ %]
+ [% IF user_can_edit_accessible %]
+ <input type="hidden" name="defined_reporter_accessible" value="1">
+ [% END %]
+ <input type="checkbox" value="1"
+ name="reporter_accessible" id="reporter_accessible"
+ [% " checked" IF bug.reporter_accessible %]
+ [% " disabled=\"disabled\"" UNLESS user_can_edit_accessible %]>
+ <label for="reporter_accessible">Reporter</label>
+ </div>
+ <div>
+ [% user_can_edit_accessible =
+ bug.check_can_change_field("cclist_accessible", 0, 1)
+ %]
+ [% IF user_can_edit_accessible %]
+ <input type="hidden" name="defined_cclist_accessible" value="1">
+ [% END %]
+ <input type="checkbox" value="1"
+ name="cclist_accessible" id="cclist_accessible"
+ [% " checked" IF bug.cclist_accessible %]
+ [% " disabled=\"disabled\"" UNLESS user_can_edit_accessible %]>
+ <label for="cclist_accessible">CC List</label>
+ </div>
+ <p class="instructions">
+ The assignee
+ [% IF (Param('useqacontact')) %]
+ and QA contact
+ [% END %]
+ can always see [% terms.abug %], and this section does not
+ take effect unless the [% terms.bug %] is restricted to at
+ least one group.
+ </p>
+ </div>
+ [% END %]
+ </div> [%# bz_group_visibility_section %]
+[% END %]
+
+[%############################################################################%]
+[%# Block for Dates #%]
+[%############################################################################%]
+
+[% BLOCK section_dates %]
+ <tr>
+ <th class="field_label">
+ Reported:
+ </th>
+ <td>
+ [% bug.creation_ts FILTER time("%Y-%m-%d %H:%M %Z") %] by [% INCLUDE global/user.html.tmpl who = bug.reporter %]
+ </td>
+ </tr>
+
+ <tr>
+ <th class="field_label">
+ Modified:
+ </th>
+ <td>
+ [% bug.delta_ts FILTER time("%Y-%m-%d %H:%M %Z") %]
+ (<a href="show_activity.cgi?id=[% bug.bug_id %]">[%# terms.Bug %]History</a>)
+ </td>
+
+ </tr>
+[% END %]
+
+[%############################################################################%]
+[%# Block for CC LIST #%]
+[%############################################################################%]
+[% BLOCK section_cclist %]
+ <tr>
+ <th class="field_label">
+ <label [% IF user.id %]for="newcc"[% END %] accesskey="a">
+ CC List:
+ </label>
+ </th>
+ <td>
+ [% IF user.id %]
+ [% IF NOT bug.cc.contains(user.login) %]
+ <input type="checkbox" id="addselfcc" name="addselfcc"
+ [% " checked=\"checked\""
+ IF user.settings.state_addselfcc.value == 'always'
+ || (!bug.user.has_any_role
+ && user.settings.state_addselfcc.value == 'cc_unless_role') %]>
+ <label for="addselfcc">Add me to CC list</label>
+ <br>
+ [% END %]
+ [% END %]
+ [% bug.cc.size FILTER html %]
+ [% IF bug.cc.size == 1 %]
+ user
+ [% ELSE %]
+ users
+ [% END %]
+ [% IF user.id %]
+ [% IF bug.cc.contains( user.email ) %]
+ including you
+ [% END %]
+ [% END %]
+ [% IF user.id || bug.cc.size %]
+ <span id="cc_edit_area_showhide_container" class="bz_default_hidden">
+ (<a href="#" id="cc_edit_area_showhide">[% IF user.id %]edit[% ELSE %]show[% END %]</a>)
+ </span>
+ [% END %]
+ <div id="cc_edit_area">
+ <br>
+ [% IF user.id %]
+ <div>
+ <div><label for="cc"><b>Add</b></label></div>
+ [% INCLUDE global/userselect.html.tmpl
+ id => "newcc"
+ name => "newcc"
+ value => ""
+ size => 30
+ classes => ["bz_userfield"]
+ multiple => 5
+ %]
+ </div>
+ [% Hook.process("after_cc_field", 'bug/edit.html.tmpl') %]
+ [% END %]
+ [% IF bug.cc.size %]
+ <select id="cc" multiple="multiple" size="5" [% 'name="cc"' IF bug.user.canedit %]>
+ [% FOREACH c = bug.cc %]
+ <option value="[% c FILTER email FILTER html %]">
+ [% c FILTER email FILTER html %]</option>
+ [% END %]
+ </select>
+ [% IF user.id && !bug.user.canedit %]
+ <input type="hidden" name="cc" value="[% user.login FILTER email FILTER html %]">
+ [% END %]
+ [% IF user.id AND (bug.user.canedit OR bug.cc.contains(user.login)) %]
+ <br>
+ <input type="checkbox" id="removecc" name="removecc">
+ <label for="removecc">
+ [% IF bug.user.canedit %]
+ Remove selected CCs
+ [% ELSE %]
+ Remove me from the CC list
+ [% END %]
+ </label>
+ <br>
+ [% END %]
+ [% END %]
+ </div>
+ [% IF !user.id && bug.cc.size %]
+ <script type="text/javascript">
+ hideEditableField( 'cc_edit_area_showhide_container',
+ 'cc_edit_area',
+ 'cc_edit_area_showhide',
+ '',
+ '');
+ </script>
+ [% END %]
+ </td>
+ </tr>
+[% END %]
+
+[%############################################################################%]
+[%# Block for Bug Ignored #%]
+[%############################################################################%]
+[% BLOCK section_bug_ignored %]
+ [% IF user.id %]
+ <tr>
+ <th class="field_label">
+ <label for="bug_ignored" title="Ignore all email for this [% terms.bug %]">
+ Ignore [% terms.Bug %] Mail:
+ </label>
+ </th>
+ <td>
+ <input type="hidden" name="defined_bug_ignored" value="1">
+ <span title="You will still receive emails for flag requests directed at you.">
+ <input type="checkbox" name="bug_ignored" id="bug_ignored" value="1"
+ [% ' checked="checked"' IF user.is_bug_ignored(bug.id) %]>
+ (never email me about this [% terms.bug %])
+ </span>
+ </td>
+ </tr>
+ [% END %]
+[% END %]
+
+[%############################################################################%]
+[%# Block for See Also #%]
+[%############################################################################%]
+[% BLOCK section_see_also %]
+ [% IF Param('use_see_also') || bug.see_also.size %]
+ <tr>
+ [% INCLUDE bug/field.html.tmpl
+ field = bug_fields.see_also
+ value = bug.see_also
+ editable = bug.check_can_change_field('see_also', 0, 1)
+ %]
+ </tr>
+ [% END %]
+[% END %]
+
+[% BLOCK section_aliases %]
+ <tr>
+ [% INCLUDE "bug/field-label.html.tmpl" field = bug_fields.alias %]
+ <td>
+ [% IF bug.alias.size %]
+ [% bug.alias.join(', ') FILTER html %]
+ [% ELSE %]
+ None
+ [% END %]
+ [% IF bug.check_can_change_field('alias', 0, 1) %]
+ <span id="alias_edit_area_showhide_container" class="bz_default_hidden">
+ (<a href="#" id="alias_edit_area_showhide">edit</a>)
+ </span>
+ <br>
+ <div id="alias_edit_area">
+ <div>
+ <label for="newalias" class="field_label">Add</label>
+ <br>
+ <input name="newalias" id="newalias" size="20">
+ </div>
+ [% IF bug.alias.size %]
+ <select id="alias" name="alias" multiple="multiple" size="5">
+ [% FOREACH a = bug.alias %]
+ <option value="[% a FILTER html %]">[% a FILTER html %]</option>
+ [% END %]
+ </select>
+ <br>
+
+ <input type="checkbox" id="removealias" name="removealias">
+ <label for="removealias">Remove selected aliases</label>
+ [% END %]
+ </div>
+ <script type="text/javascript">
+ hideEditableField( 'alias_edit_area_showhide_container',
+ 'alias_edit_area',
+ 'alias_edit_area_showhide',
+ '',
+ '');
+ </script>
+ [% END %]
+ </td>
+ </tr>
+[% END %]
+
+[%############################################################################%]
+[%# Block for FLAGS #%]
+[%############################################################################%]
+
+[% BLOCK section_flags %]
+ [%# *** Flags *** %]
+ [% show_bug_flags = 0 %]
+ [% bug_flags_set = 0 %]
+ [% show_more_flags = 0 %]
+ [% FOREACH type = bug.flag_types %]
+ [% IF type.flags.size || (user.id && type.is_active && user.can_request_flag(type)) %]
+ [% show_bug_flags = 1 %]
+ [% END %]
+ [% IF user.id && type.is_active && (!type.flags.size || type.is_multiplicable) %]
+ [% show_more_flags = 1 %]
+ [% END %]
+ [% IF type.flags.size %]
+ [% bug_flags_set = 1 %]
+ [% END %]
+ [% LAST IF show_bug_flags && show_more_flags && bug_flags_set %]
+ [% END %]
+ [% IF show_bug_flags %]
+ <tr>
+ <th class="field_label">
+ <label>Flags:</label>
+ </th>
+ <td>
+ [% IF bug.flag_types.size %]
+ [% PROCESS "flag/list.html.tmpl" flag_no_header = 1
+ flag_types = bug.flag_types
+ any_flags_requesteeble = bug.any_flags_requesteeble %]
+ [% END %]
+ [% IF show_more_flags %]
+ <span id="bz_flags_more_container" class="bz_default_hidden">
+ [% IF !bug_flags_set %]<em>None yet set</em>[% END %]
+ (<a href="#" id="bz_flags_more_action">[% IF !bug_flags_set %]set[% ELSE %]more[% END %] flags</a>)
+ </span>
+ <script type="text/javascript">
+ YAHOO.util.Dom.removeClass('bz_flags_more_container', 'bz_default_hidden');
+ var table = YAHOO.util.Dom.get("flags");
+ var rows = YAHOO.util.Dom.getElementsByClassName('bz_flag_type', 'tbody', table);
+ for (var i = 0; i < rows.length; i++) {
+ YAHOO.util.Dom.addClass(rows[i], 'bz_default_hidden');
+ }
+ YAHOO.util.Event.addListener('bz_flags_more_action', 'click', function (e) {
+ YAHOO.util.Dom.addClass('bz_flags_more_container', 'bz_default_hidden');
+ for (var i = 0; i < rows.length; i++) {
+ YAHOO.util.Dom.removeClass(rows[i], 'bz_default_hidden');
+ }
+ YAHOO.util.Event.preventDefault(e);
+ });
+ </script>
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+[% END %]
+
+[%############################################################################%]
+[%# Block for Custom Fields #%]
+[%############################################################################%]
+
+[% BLOCK section_customfields %]
+[%# *** Custom Fields *** %]
+ [% USE Bugzilla %]
+ [% FOREACH field = Bugzilla.active_custom_fields %]
+ <tr>
+ [%# Use PROCESS instead of INCLUDE, because extra_field_item is defined
+ # in the template and must be returned back. INCLUDE cannot do that. %]
+ [% PROCESS bug/field.html.tmpl value = bug.${field.name}
+ editable = bug.check_can_change_field(field.name, 0, 1) %]
+ </tr>
+ [% IF extra_field_item %]
+ <tr>
+ <th class="field_label">[% extra_field_item.header FILTER none %]</th>
+ <td>[% extra_field_item.data FILTER none %]</td>
+ </tr>
+ [% END %]
+ [% END %]
+[% END %]
+
+[%############################################################################%]
+[%# Block for Section Spacer #%]
+[%############################################################################%]
+
+[% BLOCK section_spacer %]
+ <tr>
+ <td colspan="2" class="bz_section_spacer"></td>
+ </tr>
+[% END %]
+
+
+
+
+[%############################################################################%]
+[%# Block for dependencies #%]
+[%############################################################################%]
+
+[% BLOCK dependencies %]
+
+ [% INCLUDE "bug/field-label.html.tmpl" %]
+
+ <td>
+ <span id="[% field.name FILTER html %]_input_area">
+ [% IF bug.check_can_change_field(field.name, 0, 1) %]
+ <input name="[% field.name FILTER html %]"
+ id="[% field.name FILTER html %]" class="text_input"
+ value="[% bug.${field.name}.join(', ') FILTER html %]">
+ [% END %]
+ </span>
+
+ [% FOREACH dep_bug = deps %]
+ [% INCLUDE bug/link.html.tmpl bug = dep_bug, link_text = dep_bug.id, use_alias = 1 %][% " " %]
+ [% END %]
+ [% IF bug.check_can_change_field(field.name, 0, 1) %]
+ <span id="[% field.name FILTER html %]_edit_container"
+ class="edit_me bz_default_hidden">
+ (<a href="#" id="[% field.name FILTER html %]_edit_action">edit</a>)
+ </span>
+ <script type="text/javascript">
+ hideEditableField('[% field.name FILTER js %]_edit_container',
+ '[% field.name FILTER js %]_input_area',
+ '[% field.name FILTER js %]_edit_action',
+ '[% field.name FILTER js %]',
+ '[% bug.${field.name}.join(', ') FILTER js %]');
+ </script>
+ [% END %]
+ </td>
+
+[% END %]
+
+[%############################################################################%]
+[%# Block for Time Tracking Group #%]
+[%############################################################################%]
+
+[% BLOCK section_timetracking %]
+ <div id="bz_time_tracking_showhide_container" class="bz_default_hidden">
+ (<a href="#" id="bz_time_tracking_showhide">show time tracking data</a>)
+ </div>
+ <table class="bz_time_tracking_table" id="bz_time_tracking_table">
+ <tr>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.estimated_time, editable = 1
+ %]
+ <th>
+ Current Est.:
+ </th>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.work_time, editable = 1
+ %]
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.remaining_time, editable = 1
+ %]
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.percentage_complete
+ %]
+ <th>
+ Gain:
+ </th>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.deadline, editable = 1
+ %]
+ </tr>
+ <tr>
+ <td>
+ <input name="estimated_time" id="estimated_time"
+ value="[% PROCESS formattimeunit
+ time_unit=bug.estimated_time %]"
+ size="6" maxlength="6">
+ </td>
+ <td>
+ [% PROCESS formattimeunit
+ time_unit=(bug.actual_time + bug.remaining_time) %]
+ </td>
+ <td>
+ [% PROCESS formattimeunit time_unit=bug.actual_time %] +
+ <input name="work_time" id="work_time"
+ value="0" size="3" maxlength="6"
+ onchange="adjustRemainingTime();">
+ </td>
+ <td>
+ <input name="remaining_time" id="remaining_time"
+ value="[% PROCESS formattimeunit
+ time_unit=bug.remaining_time %]"
+ size="6" maxlength="6" onchange="updateRemainingTime();">
+ </td>
+ <td>
+ [% PROCESS calculatepercentage act=bug.actual_time
+ rem=bug.remaining_time %]
+ </td>
+ <td>
+ [% PROCESS formattimeunit time_unit=bug.estimated_time - (bug.actual_time + bug.remaining_time) %]
+ </td>
+ <td>
+ [% INCLUDE bug/field.html.tmpl
+ field = bug_fields.deadline, value = bug.deadline, no_tds = 1
+ editable = bug.check_can_change_field('deadline', 0, 1) %]
+ </td>
+ </tr>
+ <tr>
+ <td colspan="7" class="bz_summarize_time">
+ <a href="summarize_time.cgi?id=[% bug.bug_id %]&amp;do_depends=1">
+ Summarize time (including time for [% terms.bugs %]
+ blocking this [% terms.bug %])</a>
+ </td>
+ </tr>
+ </table>
+ <script type="text/javascript">
+ hideEditableField( 'bz_time_tracking_showhide_container',
+ 'bz_time_tracking_table',
+ 'bz_time_tracking_showhide_container',
+ '',
+ '');
+ </script>
+[% END %]
+
+[%############################################################################%]
+[%# Block for the Additional Comments box #%]
+[%############################################################################%]
+
+[% BLOCK comment_box %]
+ <div id="add_comment" class="bz_section_additional_comments">
+ [% IF user.id %]
+ <label for="comment" accesskey="c"><b>Additional
+ <u>C</u>omments</b></label>: <em>(this is where you put emerge --info)</em>
+
+ [% IF user.is_insider && bug.check_can_change_field('longdesc', 0, 1) %]
+ <input type="checkbox" name="comment_is_private" value="1"
+ id="newcommentprivacy"
+ onClick="updateCommentTagControl(this, 'comment')">
+ <label for="newcommentprivacy">
+ Make comment private (visible only to members of the
+ <strong>[% Param('insidergroup') FILTER html %]</strong> group)
+ </label>
+ [% END %]
+
+ <!-- This table keeps the submit button aligned with the box. -->
+ <div class="row">
+ <div class="col-sm-12">
+ <!-- <table><tr><td> -->
+ [% IF bug.check_can_change_field('longdesc', 0, 1) %]
+ [% INCLUDE bug/comment.html.tmpl
+ minrows = 10
+ maxrows = 25
+ cols = constants.COMMENT_COLS
+ %]
+ [% IF user.is_insider %]
+ <script>
+ updateCommentTagControl(document.getElementById('newcommentprivacy'), 'comment');
+ </script>
+ [% END %]
+ [% Hook.process("after_comment_textarea", 'bug/edit.html.tmpl') %]
+ [% ELSE %]
+ You are not allowed to make an additional comment on this [% terms.bug %].
+ [% END %]
+ <br>
+ [% PROCESS commit_button id=""%]
+
+ [% Hook.process("after_comment_commit_button", 'bug/edit.html.tmpl') %]
+
+ <table id="bug_status_bottom" class="status">
+ <tr>
+ <th class="field_label">
+ <a href="page.cgi?id=fields.html#bug_status">Status</a>:
+ </th>
+ <td>
+ [% PROCESS bug/knob.html.tmpl %]
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+ <!-- </td></tr></table> -->
+
+ [% IF feature_enabled('jsonrpc') AND bug.assigned_to.login == 'bug-wranglers@gentoo.org' %]
+ [%# This seciton mostly left unindented to make updates from create.html.tmpl easier. %]
+ <table>
+ <tr id="possible_duplicates_container">
+ <th>Possible<br>Duplicates:</th>
+ <td colspan="3">
+ <div id="possible_duplicates"></div>
+ <script type="text/javascript">
+ var dt_columns = [
+ { key: "id", label: "[% field_descs.bug_id FILTER js %]",
+ formatter: YAHOO.bugzilla.dupTable.formatBugLink },
+ { key: "summary",
+ label: "[% field_descs.short_desc FILTER js %]",
+ formatter: "text" },
+ { key: "status",
+ label: "[% field_descs.bug_status FILTER js %]",
+ formatter: YAHOO.bugzilla.dupTable.formatStatus },
+ { key: "update_token", label: '',
+ formatter: YAHOO.bugzilla.dupTable.formatCcButton }
+ ];
+ YAHOO.bugzilla.dupTable.addCcMessage = "Add Me to the CC List";
+ YAHOO.bugzilla.dupTable.init({
+ container: 'possible_duplicates',
+ columns: dt_columns,
+ product_name: '[% product.name FILTER js %]',
+ summary_field: 'short_desc',
+ options: {
+ MSG_LOADING: 'Searching for possible duplicates...',
+ MSG_EMPTY: 'No possible duplicates found.',
+ SUMMARY: 'Possible Duplicates'
+ }
+ });
+ </script>
+ </td>
+ </tr>
+ </table><br>
+ [% END %]
+
+ [%# For logged-out users %]
+ [% ELSE %]
+ <table>
+ <tr>
+ <td>
+ <fieldset>
+ <legend>Note</legend>
+ You need to
+ <a href="show_bug.cgi?id=
+ [%- bug.bug_id %]&amp;GoAheadAndLogIn=1">log in</a>
+ before you can comment on or make changes to this [% terms.bug %].
+ </fieldset>
+ </td>
+ </tr>
+ </table>
+ [% END %]
+ </div>
+[% END %]
+
+[%############################################################################%]
+[%# Block for SELECT fields #%]
+[%############################################################################%]
+
+[% BLOCK select %]
+ <td>
+ [% IF bug.check_can_change_field(selname, 0, 1)
+ AND bug.choices.${selname}.size > 1 %]
+ <input type="hidden" id="[% selname %]_dirty">
+ <select id="[% selname %]" name="[% selname %]">
+ [% FOREACH x = bug.choices.${selname} %]
+ <option value="[% x.name FILTER html %]"
+ [% " selected" IF x.name == bug.${selname} %]>
+ [%- x.name FILTER html %]
+ </option>
+ [% END %]
+ </select>
+ [% ELSE %]
+ [% bug.${selname} FILTER html %]
+ [% END %]
+ </td>
+[% END %]
+
+[%############################################################################%]
+[%# Block for INPUT fields #%]
+[%############################################################################%]
+
+[% BLOCK input %]
+ [% IF no_td != 1 %]
+ <td[% " colspan=\"$colspan\"" IF colspan %]>
+ [% END %]
+ [% val = value ? value : bug.$inputname %]
+ [% IF bug.check_can_change_field(inputname, 0, 1) %]
+ <input id="[% inputname %]" name="[% inputname %]" class="text_input"
+ value="[% val FILTER html %]"[% " size=\"$size\"" IF size %]
+ [% " maxlength=\"$maxlength\"" IF maxlength %]
+ [% " spellcheck=\"$spellcheck\"" IF spellcheck %]>
+ [% ELSE %]
+ [% IF size && val.length > size %]
+ <span title="[% val FILTER html %]">
+ [% val FILTER truncate(size) FILTER html %]
+ </span>
+ [% ELSE %]
+ [% val FILTER html %]
+ [% END %]
+ [% END %]
+ [% IF no_td != 1 %]
+ </td>
+ [% END %]
+ [% no_td = 0 %]
+ [% maxlength = 0 %]
+ [% colspan = 0 %]
+ [% size = 0 %]
+ [% value = undef %]
+ [% spellcheck = undef %]
+[% END %]
+
+[% BLOCK commit_button %]
+ [% IF user.id %]
+ <div class="knob-buttons">
+ <input class="btn btn-primary btn-sm" type="submit" value="Save Changes"
+ id="commit[% id FILTER css_class_quote %]">
+ </div>
+ [% END %]
+[% END %]
diff --git a/template/en/custom/bug/field.html.tmpl b/template/en/custom/bug/field.html.tmpl
new file mode 100644
index 000000000..e34465041
--- /dev/null
+++ b/template/en/custom/bug/field.html.tmpl
@@ -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.
+ #%]
+
+[%# INTERFACE:
+ # field: a Bugzilla::Field object
+ # value: The value of the field for this bug.
+ # field_hidden (optional): boolean; if true, the field is hidden by default.
+ # override_legal_values (optional): The list of legal values, for select fields.
+ # editable: Whether the field should be displayed as an editable
+ # <input> or as just the plain text of its value.
+ # allow_dont_change: display the --do_not_change-- option for select fields.
+ # value_span: A colspan for the table cell containing
+ # the field value.
+ # no_tds: boolean; if true, don't display the label <th> or the
+ # wrapping <td> for the field.
+ # bug (optional): The current Bugzilla::Bug being displayed, or a hash
+ # with default field values being displayed on a page.
+ #%]
+
+[% IF NOT no_tds %]
+ [% field_hidden = 0 %]
+ [% IF bug AND !field.is_visible_on_bug(bug) %]
+ [% field_hidden = 1 %]
+ [% END %]
+
+ [% INCLUDE "bug/field-label.html.tmpl" hidden = field_hidden %]
+ <td class="field_value [% ' bz_hidden_field' IF field_hidden %]"
+ id="field_container_[% field.name FILTER html %]"
+ [% " colspan=\"$value_span\"" FILTER none IF value_span %]>
+[% END %]
+[% Hook.process('start_field_column') %]
+[% IF editable %]
+ [% SWITCH field.type %]
+ [% CASE [ constants.FIELD_TYPE_FREETEXT
+ constants.FIELD_TYPE_INTEGER ] %]
+ <input id="[% field.name FILTER html %]" class="text_input"
+ name="[% field.name FILTER html %]"
+ value="[% value FILTER html %]" size="40"
+ maxlength="[% constants.MAX_FREETEXT_LENGTH FILTER none %]"
+ [% IF field.type == constants.FIELD_TYPE_INTEGER %]
+ pattern="-?\d+[% IF dontchange %]|[% dontchange FILTER html %][% END %]"
+ title="The value must be a valid positive or negative integer"
+ [% END %]
+ [% IF field.is_mandatory %]
+ data-required="true" [% 'aria-required="true" required' UNLESS field_hidden %]
+ [% END %]>
+ [% CASE [constants.FIELD_TYPE_DATETIME, constants.FIELD_TYPE_DATE] %]
+ [% size = (field.type == constants.FIELD_TYPE_DATE) ? 10 : 20 %]
+ <input name="[% field.name FILTER html %]" size="[% size FILTER none %]"
+ id="[% field.name FILTER html %]"
+ value="[% value FILTER html %]"
+ [% IF field.is_mandatory %]
+ data-required="true" [% 'aria-required="true" required' UNLESS field_hidden %]
+ [% END %]
+ onchange="updateCalendarFromField(this)">
+ <button type="button" class="calendar_button"
+ id="button_calendar_[% field.name FILTER html %]"
+ onclick="showCalendar('[% field.name FILTER js %]')">
+ <span>Calendar</span>
+ </button>
+
+ <div id="con_calendar_[% field.name FILTER html %]"></div>
+
+ <script type="text/javascript">
+ <!--
+ [%+ PROCESS "global/calendar.js.tmpl" id = field.name %]
+ //--></script>
+ [% CASE constants.FIELD_TYPE_BUG_ID %]
+ <span id="[% field.name FILTER html %]_input_area">
+ <input name="[% field.name FILTER html %]" id="[% field.name FILTER html %]"
+ value="[% value FILTER html %]" size="7"
+ [% IF field.is_mandatory %]
+ data-required="true" [% 'aria-required="true" required' UNLESS field_hidden %]
+ [% END %]>
+ </span>
+
+ [% IF value %]
+ [% value FILTER bug_link(value, use_alias => 1) FILTER none %]
+ [% END %]
+ <span id="[% field.name FILTER html %]_edit_container" class="edit_me bz_default_hidden">
+ (<a href="#" id="[% field.name FILTER html %]_edit_action">edit</a>)
+ </span>
+ <script type="text/javascript">
+ hideEditableField('[% field.name FILTER js %]_edit_container',
+ '[% field.name FILTER js %]_input_area',
+ '[% field.name FILTER js %]_edit_action',
+ '[% field.name FILTER js %]',
+ "[% value FILTER js %]");
+ </script>
+ [% CASE [ constants.FIELD_TYPE_SINGLE_SELECT
+ constants.FIELD_TYPE_MULTI_SELECT ] %]
+ [%# The 'product' field needs its own template if classifications are enabled. %]
+ [% IF field.name == "product" AND Param('useclassification') %]
+ [% INCLUDE "global/product-select.html.tmpl"
+ id = "product", name = "product", value = value
+ products = override_legal_values %]
+ [% ELSE %]
+ <input type="hidden" id="[% field.name FILTER html %]_dirty">
+ <select id="[% field.name FILTER html %]"
+ name="[% field.name FILTER html %]"
+ class="form-control selectwidthauto"
+ [% IF field.type == constants.FIELD_TYPE_MULTI_SELECT %]
+ [% SET field_size = 5 %]
+ [% IF field.legal_values.size < 5 %]
+ [% SET field_size = field.legal_values.size %]
+ [% END %]
+ size="[% field_size FILTER html %]" multiple="multiple"
+ [% IF field.is_mandatory %]
+ data-required="true" [% 'aria-required="true" required' UNLESS field_hidden %]
+ [% END %]
+ [% END %]>
+ [% IF allow_dont_change %]
+ <option value="[% dontchange FILTER html %]"
+ [% ' selected="selected"' IF value == dontchange %]>
+ [% dontchange FILTER html %]
+ </option>
+ [% END %]
+ [% IF override_legal_values %]
+ [% legal_values = override_legal_values %]
+ [% ELSE %]
+ [% legal_values = field.legal_values %]
+ [% END %]
+ [% FOREACH legal_value = legal_values %]
+ [% NEXT IF NOT legal_value.is_active AND NOT value.contains(legal_value.name).size %]
+ <option value="[% legal_value.name FILTER html %]"
+ id="v[% legal_value.id FILTER html %]_
+ [%- field.name FILTER html %]"
+ [%# We always show selected values, even if they should be
+ # hidden %]
+ [% IF value.contains(legal_value.name).size %]
+ selected="selected"
+ [% ELSIF bug AND !legal_value.is_visible_on_bug(bug) %]
+ class="bz_hidden_option" disabled="disabled"
+ [% END %]>
+ [%- display_value(field.name, legal_value.name) FILTER html ~%]
+ </option>
+ [% END %]
+ </select>
+ [%# When you pass an empty multi-select in the web interface,
+ # it doesn't appear at all in the CGI object. Instead of
+ # forcing all users of process_bug to always specify every
+ # multi-select, we have this field defined if the multi-select
+ # field is defined, and then if this is passed but the multi-select
+ # isn't, we know that the multi-select was emptied.
+ %]
+ [% IF field.type == constants.FIELD_TYPE_MULTI_SELECT %]
+ <input type="hidden" name="defined_[% field.name FILTER html %]">
+ [% END %]
+ [% END %]
+
+ <script type="text/javascript">
+ <!--
+ initHidingOptionsForIE('[% field.name FILTER js %]');
+ [%+ INCLUDE "bug/field-events.js.tmpl"
+ field = field, product = bug.product_obj %]
+ //-->
+ </script>
+
+ [% CASE constants.FIELD_TYPE_TEXTAREA %]
+ <div id="[% field.name FILTER html %]_edit_container" class="bz_default_hidden">
+ <div>
+ (<a href="#" id="[% field.name FILTER html %]_edit_action">edit</a>)
+ </div>
+ [% IF value %]
+ <pre id="[% field.name FILTER html %]_readonly"
+ class="field_textarea_readonly">[% value FILTER html %]</pre>
+ [% END %]
+ </div>
+ <div id="[% field.name FILTER html %]_input">
+ [% INCLUDE global/textarea.html.tmpl
+ id = field.name name = field.name minrows = 4 maxrows = 8
+ cols = 60 defaultcontent = value mandatory = field.is_mandatory %]
+ </div>
+ <script type="text/javascript">
+ hideEditableField('[% field.name FILTER js %]_edit_container',
+ '[% field.name FILTER js %]_input',
+ '[% field.name FILTER js %]_edit_action',
+ '[% field.name FILTER js %]',
+ '[% value FILTER js %]',
+ '',
+ true);
+ </script>
+ [% CASE constants.FIELD_TYPE_BUG_URLS %]
+ [% IF bug.id && value.size %]
+ <ul class="bug_urls">
+ [% FOREACH bug_url = value %]
+ <li>
+ [% PROCESS bug_url_link bug_url = bug_url %]
+ <label><input type="checkbox" value="[% bug_url.name FILTER html %]"
+ name="remove_[% field.name FILTER html %]">
+ Remove</label>
+ </li>
+ [% END %]
+ </ul>
+ [% END %]
+ [% IF Param('use_see_also') %]
+ <span id="container_showhide_[% field.name FILTER html %]"
+ class="bz_default_hidden">
+ (<a href="#" id="showhide_[% field.name FILTER html %]">add</a>)
+ </span>
+ <div id="container_[% field.name FILTER html %]">
+ <input type="text" id="[% field.name FILTER html %]" size="40"
+ class="text_input" name="[% field.name FILTER html %]"
+ [% IF !bug.id %]value="[% value FILTER html %]"[% END %]>
+ </div>
+ [% IF bug.id %]
+ <script type="text/javascript">
+ setupEditLink('[% field.name FILTER js %]');
+ </script>
+ [% END %]
+ [% END %]
+ [% CASE constants.FIELD_TYPE_KEYWORDS %]
+ <div id="[% field.name FILTER html %]_container">
+ <input type="text" id="[% field.name FILTER html %]" size="40"
+ class="text_input" name="[% field.name FILTER html %]"
+ value="[% value FILTER html %]">
+ <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>
+ [% END %]
+[% ELSE %]
+ [% SWITCH field.type %]
+ [% CASE constants.FIELD_TYPE_TEXTAREA %]
+ <div class="uneditable_textarea">[% value FILTER html %]</div>
+ [% CASE constants.FIELD_TYPE_BUG_ID %]
+ [% IF value %]
+ [% value FILTER bug_link(value, use_alias => 1) FILTER none %]
+ [% END %]
+ [% CASE [ constants.FIELD_TYPE_SINGLE_SELECT
+ constants.FIELD_TYPE_MULTI_SELECT ] %]
+ [% FOREACH val = value %]
+ [% display_value(field.name, val) FILTER html %]
+ [% ', ' UNLESS loop.last() %]
+ [% END %]
+ [% CASE constants.FIELD_TYPE_BUG_URLS %]
+ [% '<ul class="bug_urls">' IF value.size %]
+ [% FOREACH bug_url = value %]
+ <li>
+ [% PROCESS bug_url_link bug_url = bug_url %]
+ </li>
+ [% END %]
+ [% '</ul>' IF value.size %]
+ [% CASE %]
+ [% value.join(', ') FILTER html %]
+ [% END %]
+[% END %]
+
+[% IF bug && field.name == 'component' %]
+ (<a href="buglist.cgi?component=[% bug.component FILTER uri %]&amp;product=[% bug.product FILTER uri %]&amp;bug_status=__open__"
+ target="_blank">show other [% terms.bugs %]</a>)
+[% END %]
+
+[% Hook.process('end_field_column') %]
+[% '</td>' IF NOT no_tds %]
+
+[%# for reverse relationships, we show this pseudo-field after the main field %]
+[% IF bug.id && field.is_relationship %]
+ [% extra_field_item = {} %]
+ [% extra_field_item.header = field.reverse_desc _ ":" FILTER html %]
+ [% extra_field_item.data = BLOCK %]
+ [% FOREACH depbug = bug.related_bugs(field) %]
+ [% depbug.id FILTER bug_link(depbug, use_alias => 1) FILTER none %][% " " %]
+ [% END %]
+ [% END %]
+[% ELSE %]
+ [% extra_field_item = '' %]
+[% END %]
+
+[% BLOCK bug_url_link %]
+ [% IF bug_url.isa('Bugzilla::BugUrl::Bugzilla::Local') %]
+ [% bug_url.target_bug_id FILTER bug_link(bug_url.target_bug_id, use_alias => 1) FILTER none %]
+ [% ELSE %]
+ <a href="[% bug_url.name FILTER html %]">
+ [% bug_url.name FILTER html %]</a>
+ [% END %]
+[% END %]
diff --git a/template/en/custom/bug/navigate.html.tmpl b/template/en/custom/bug/navigate.html.tmpl
new file mode 100644
index 000000000..d7912dce6
--- /dev/null
+++ b/template/en/custom/bug/navigate.html.tmpl
@@ -0,0 +1,84 @@
+[%# 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.
+ #%]
+
+[% RETURN IF !bug %]
+
+[% IF bottom_navigator == 1 %]
+ <ul class="related_actions">
+ <li><a href="show_bug.cgi?format=multiple&amp;id=
+ [% bug.bug_id FILTER uri %]">Format For Printing</a></li>
+ <li>&nbsp;-&nbsp;<a href="show_bug.cgi?ctype=xml&amp;id=
+ [% bug.bug_id FILTER uri %]">XML</a></li>
+ <li>&nbsp;-&nbsp;<a href="enter_bug.cgi?cloned_bug_id=
+ [% bug.bug_id FILTER uri %]">Clone This
+ [% terms.Bug %]</a></li>
+ [%# Links to more things users can do with this bug. %]
+ [% Hook.process("links") %]
+ <li>&nbsp;-&nbsp;<a href="#">Top of page </a></li>
+ </ul>
+[% END %]
+
+[% SET my_search = user.recent_search_for(bug) %]
+[% IF my_search %]
+<div class="container-fluid">
+ <small>
+ <div class="navigation">
+ [% SET last_bug_list = my_search.bug_list %]
+ [% SET this_bug_idx = lsearch(last_bug_list, bug.id) %]
+ <a href="buglist.cgi?regetlastlist=
+ [%- my_search.id FILTER uri %]"><b>[% terms.Bug %] List:</b></a>
+
+ ([% this_bug_idx + 1 %] of [% last_bug_list.size %])
+ &nbsp;&nbsp;
+ [% IF this_bug_idx > 0 %]
+ <a href="show_bug.cgi?id=
+ [%- last_bug_list.first FILTER uri %]&amp;list_id=
+ [%- my_search.id FILTER uri %]"><i class="fa fa-angle-double-left" aria-hidden="true"></i> First</a>
+ [% ELSE %]
+ <span class="navigation_link"><i class="fa fa-angle-double-left" aria-hidden="true"></i> First</span>
+ [% END %]
+
+ [% IF this_bug_idx > 0 %]
+ [% prev_bug = this_bug_idx - 1 %]
+ <a href="show_bug.cgi?id=
+ [%- last_bug_list.$prev_bug FILTER uri %]&amp;list_id=
+ [%- my_search.id FILTER uri %]"><i class="fa fa-angle-left" aria-hidden="true"></i> Prev</a>
+ [% ELSE %]
+ <span class="navigation_link"><i class="fa fa-angle-left" aria-hidden="true"></i> Prev</span>
+ [% END %]
+ &nbsp;
+ [% IF this_bug_idx + 1 < last_bug_list.size %]
+ [% next_bug = this_bug_idx + 1 %]
+ <a href="show_bug.cgi?id=
+ [%- last_bug_list.$next_bug FILTER uri %]&amp;list_id=
+ [%- my_search.id FILTER uri %]">Next <i class="fa fa-angle-right" aria-hidden="true"></i></a>
+ [% ELSE %]
+ <span class="navigation_link" style="font-style: normal;">Next <i class="fa fa-angle-right" aria-hidden="true"></i></span>
+ [% END %]
+
+ [% IF this_bug_idx + 1 < last_bug_list.size %]
+ <a href="show_bug.cgi?id=
+ [%- last_bug_list.last FILTER uri %]&amp;list_id=
+ [%- my_search.id FILTER uri %]">Last <i class="fa fa-angle-double-right" aria-hidden="true"></i></a>
+ [% ELSE %]
+ <span class="navigation_link" style="font-style: normal;">Last <i class="fa fa-angle-double-right" aria-hidden="true"></i></span>
+ [% END %]
+
+
+ <button class="pull-right btn btn-primary btn-sm">Edit Bug</button>
+
+ <button onclick="window.scrollTo(0,document.body.scrollHeight);" class="pull-right btn btn-default btn-sm" style="background: transparent;margin-right:5px;">Bottom <i class="fa fa-long-arrow-down" aria-hidden="true"></i>
+ </button>
+
+ <button class="pull-right btn btn-default btn-sm" style="background: transparent;margin-right:5px;">Copy Summary</button>
+
+
+ </div>
+ </small>
+</div>
+[% END %]
diff --git a/template/en/custom/bug/show.html.tmpl b/template/en/custom/bug/show.html.tmpl
new file mode 100644
index 000000000..9ca61027d
--- /dev/null
+++ b/template/en/custom/bug/show.html.tmpl
@@ -0,0 +1,43 @@
+[%# 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.
+ #%]
+
+[%# This script/template only handles one bug #%]
+[% bug = bugs.0 %]
+
+[% IF !header_done %]
+ [% PROCESS "bug/show-header.html.tmpl" %]
+ [% PROCESS global/header.html.tmpl %]
+[% END %]
+
+[% IF nextbug %]
+ <hr>
+ <p>
+ The next [% terms.bug %] in your list is [% terms.bug %]
+ <a href="show_bug.cgi?id=[% bug.bug_id %]">[% bug.bug_id %]</a>:
+ </p>
+ <hr>
+[% END %]
+
+<div class="row">
+ <div class="col-sm-12" style="margin-bottom:10px;">
+ [% PROCESS bug/navigate.html.tmpl %]
+ </div>
+
+ <div class="col-sm-12">
+ [% PROCESS bug/edit.html.tmpl %]
+ </div>
+
+</div>
+
+<!-- <hr> -->
+
+[%# PROCESS bug/navigate.html.tmpl bottom_navigator => 1 #%]
+
+<br>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/custom/global/choose-product.html.tmpl b/template/en/custom/global/choose-product.html.tmpl
new file mode 100644
index 000000000..59c2d86e9
--- /dev/null
+++ b/template/en/custom/global/choose-product.html.tmpl
@@ -0,0 +1,246 @@
+[%# 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:
+ # classifications: array of hashes, with an 'object' key representing a
+ # classification object and 'products' the list of
+ # product objects the user can enter bugs into.
+ # target: the script that displays this template.
+ #%]
+
+[% IF target == "enter_bug.cgi" %]
+ [% title = "Enter $terms.Bug" %]
+ [% subheader = "Select Product" %]
+ [% h2 = BLOCK %]
+ [% IF Param('useclassification') %]Next[% ELSE %]First[% END %],
+ you must pick a product on which to enter [% terms.abug %]:
+ [% END %]
+[% ELSIF target == "describecomponents.cgi" %]
+ [% title = "Browse" %]
+ [% h2 = "Select a product category to browse" %]
+[% END %]
+
+[% DEFAULT title = "Choose a Product" %]
+[% PROCESS global/header.html.tmpl %]
+
+[% USE Bugzilla %]
+[% previous_params = Bugzilla.cgi.canonicalise_query('classification', 'product') %]
+
+<h2>[% h2 FILTER html %]</h2>
+[% IF target == "enter_bug.cgi" %]
+<small>
+Please consult the <a href="https://www.gentoo.org/doc/en/bugzilla-howto.xml#doc_chap6">Bug Reporting Guide</a>
+on how to choose the proper product for your issue.
+</small>
+[% END %]
+
+<hr/>
+
+[% IF target == "enter_bug.cgi" %]
+<span>If you are <strong>unsure</strong>, please file your bug in this product:</span><br/><br/>
+
+<div class="row">
+<div class="col-sm-10">
+<div class="panel panel-default" style="cursor:pointer;" onclick="document.location='enter_bug.cgi?product=Gentoo%20Linux[%- IF previous_params %]&amp;[% previous_params FILTER none %][% END -%]'">
+<div class="panel-body">
+ <div class="row">
+ <div class="col-sm-2">
+ <img src="https://www.gentoo.org/assets/img/logo/gentoo-signet.svg" style="width:100%;" />
+ </div>
+ <div class="col-sm-10">
+ <table id="choose_product">
+ <tr class="hilight">
+
+ <td valign="top"><b>The Gentoo Linux Distribution &ndash; Ebuilds and System related issues</b></td>
+ </tr>
+ <tr>
+ <td>
+ <strong>Always attach the output of <tt>emerge --info</tt> to your bug report!</strong>
+ <br /><br />
+ Before reporting a bug, please make sure the issue you are about to file
+ is not the result of a misconfiguration on your part.<br />
+ Our other support venues (for instance the
+ <a href="https://forums.gentoo.org/">Forums</a> or
+ <a href="https://www.gentoo.org/main/en/irc.xml">IRC channels</a>)
+ can help you find out whether the issue warrants a bug report.
+ <br /><br />
+ Examples for bugs in this product:
+ <ul>
+ <li>New package and version bump requests</li>
+ <li>Compile errors (please follow the instructions contained in the error message!)</li>
+ <li>Application crashes (be sure to have a <a href="https://www.gentoo.org/proj/en/qa/backtraces.xml">backtrace</a> available)</li>
+ <li>General issues regarding your Gentoo system</li>
+ </ul>
+
+ Examples for bugs that should <span style="color: #a40000;">NOT</span> be filed here:
+ <ul>
+ <li>Security updates (use <em>Gentoo Security</em> below)</li>
+ <li>Documentation updates (use <em>Documentation</em> below)</li>
+ <li>Issues regarding our website and infrastructure (use <em>Gentoo Infrastructure</em> or <em>Website www.gentoo.org</em> below)</li>
+ <li>Issues about <em>OpenRC</em>, <em>genkernel</em>, or <em>catalyst</em> (use <em>Hosted projects</em> below)</li>
+ </ul>
+ </td></tr>
+ <tr>
+ </table>
+ </div>
+ </div>
+</div>
+</div>
+</div>
+</div>
+
+<br/>
+<span>Or, use one of the following products <strong>if you know that your choice is correct:</strong></span>
+
+[% END %]
+
+
+<!-- TODO implement switch view -->
+
+<div class="row" style="margin-bottom:10px;">
+<div class="col-sm-12">
+
+ <ul class="nav nav-pills pull-right" role="tablist">
+ <li role="presentation" class=" active">
+ <a class="btn btn-default btn-xs bgo_tab" style="border-right:0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px;" href="#detailed" aria-controls="detailed" role="tab" data-toggle="tab"><i class="fa fa-th-large" aria-hidden="true"></i></a>
+ </li>
+ <li role="presentation" class="" style="margin-left:0px;">
+ <a class="btn btn-default btn-xs bgo_tab" style="border-right:0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px;border-top-left-radius: 0px; border-bottom-left-radius: 0px;" href="#condensed" aria-controls="condensed" role="tab" data-toggle="tab"><i class="fa fa-th" aria-hidden="true"></i></a>
+ </li>
+ <li role="presentation" class="" style="margin-left:0px;">
+ <a class="btn btn-default btn-xs bgo_tab" style="border-top-left-radius: 0px; border-bottom-left-radius: 0px;" href="#list" aria-controls="list" role="tab" data-toggle="tab"><i class="fa fa-list-ul" aria-hidden="true"></i></a>
+ </li>
+ </ul>
+</div>
+</div>
+
+
+<div class="tab-content">
+<div role="tabpanel" class="tab-pane" id="list">
+
+
+<table id="choose_product">
+[% FOREACH c = classifications %]
+ [% IF c.object %]
+ <tr>
+ <th colspan="2" class="left">[% c.object.name FILTER html %]:
+ [%+ c.object.description FILTER html_light %]</th>
+ </tr>
+ [% END %]
+
+ [% FOREACH p = c.products %]
+ <tr>
+ <th class="right nowrap">
+ <a href="[% target %]?product=[% p.name FILTER uri -%]
+ [%- IF previous_params %]&amp;[% previous_params FILTER none %][% END -%]">
+ [% p.name FILTER html %]</a>:
+ </th>
+
+ <td>[% p.description FILTER html_light %]</td>
+ </tr>
+ [% END %]
+
+ <tr>
+ <th colspan="2">&nbsp;</th>
+ </tr>
+[% END %]
+
+</table>
+</div>
+
+
+<div role="tabpanel" class="tab-pane" id="condensed">
+ [% FOREACH c = classifications %]
+
+ [% IF c.object %]
+ <h4>[% c.object.name FILTER html %]: [%+ c.object.description FILTER html_light %]</h4>
+ <hr/>
+ [% END %]
+
+ <div class="row" style="width:100%; display: -webkit-flex;display: flex;flex-wrap:wrap;margin-bottom:40px;">
+
+ [% FOREACH p = c.products %]
+
+ <div class="col-sm-3" style="margin-top:20px;">
+ <div class="panel panel-default" style="cursor:pointer;height:60px;" onclick="document.location='[% target %]?product=[% p.name FILTER uri -%][%- IF previous_params %]&amp;[% previous_params FILTER none %][% END -%]'">
+ <div class="panel-body" style="height:60px;overflow:hidden;padding-top:5px;padding-bottom:5px;">
+ <div class="row equal">
+ <div class="col-sm-3 align-v-center" style="height:50px;">
+ [% IF p.name == "Gentoo Linux" %]
+ <img src="https://www.gentoo.org/assets/img/logo/gentoo-signet.svg" style="height:40px;" />
+ [% ELSIF p.name == "GURU" %]
+ <img src="https://wiki.gentoo.org/images/4/47/GURU.svg" style="height:50px;" />
+ [% ELSE %]
+ <img src="https://www.gentoo.org/assets/img/logo/gentoo-signet.svg" style="height:40px;" />
+ [% END %]
+ </div>
+ <div class="col-sm-9 align-v-center" style="padding: 0px;height:50px;">
+ <h4 class="" style="margin:0px;">
+ <a style="color:#555;" href="[% target %]?product=[% p.name FILTER uri -%]
+ [%- IF previous_params %]&amp;[% previous_params FILTER none %][% END -%]">[% p.name FILTER html %]</a>
+ </h4>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ [% END %]
+ </div>
+ [% END %]
+</div>
+
+
+
+<div role="tabpanel" class="tab-pane active" id="detailed">
+[% FOREACH c = classifications %]
+
+[% IF c.object %]
+<h4>[% c.object.name FILTER html %]: [%+ c.object.description FILTER html_light %]</h4>
+<hr/>
+[% END %]
+
+<div class="row" style="width:100%; display: -webkit-flex;display: flex;flex-wrap:wrap;margin-bottom:40px;">
+
+[% FOREACH p = c.products %]
+
+<div class="col-sm-4" style="margin-top:20px;">
+ <div class="panel panel-default" style="cursor:pointer;height:100%;" onclick="document.location='[% target %]?product=[% p.name FILTER uri -%][%- IF previous_params %]&amp;[% previous_params FILTER none %][% END -%]'">
+ <div class="panel-body" style="padding-bottom: 0px;">
+ <div class="row">
+ <div class="col-sm-4">
+ [% IF p.name == "Gentoo Linux" %]
+ <img src="https://www.gentoo.org/assets/img/logo/gentoo-signet.svg" style="width:100%;" />
+ [% ELSIF p.name == "GURU" %]
+ <img src="https://wiki.gentoo.org/images/4/47/GURU.svg" style="width:100%;" />
+ [% ELSE %]
+ <img src="https://www.gentoo.org/assets/img/logo/gentoo-signet.svg" style="width:100%;" />
+ [% END %]
+
+
+ </div>
+ <div class="col-sm-8">
+ <b><a style="color:#555;" href="[% target %]?product=[% p.name FILTER uri -%]
+ [%- IF previous_params %]&amp;[% previous_params FILTER none %][% END -%]">[% p.name FILTER html %]</a>
+ </b><p style="color:#777;padding-bottom: 0px;">
+ [% p.description FILTER html_light %]
+ </p>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+[% END %]
+</div>
+[% END %]
+</div>
+
+</div>
+
+
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/custom/global/common-links.html.tmpl b/template/en/custom/global/common-links.html.tmpl
new file mode 100644
index 000000000..3f09d0496
--- /dev/null
+++ b/template/en/custom/global/common-links.html.tmpl
@@ -0,0 +1,153 @@
+[%# 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.
+ #%]
+
+[% DEFAULT qs_suffix = "" %]
+[% USE Bugzilla %]
+
+<nav class="tyrian-navbar" role="navigation">
+<div class="container">
+ <div class="row">
+ <div class="navbar-header">
+ <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-main-collapse">
+ <span class="sr-only">Toggle navigation</span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ </button>
+ </div>
+ <div class="collapse navbar-collapse navbar-main-collapse">
+ <ul class="nav navbar-nav">
+
+ <!-- TODO Can we use the Gentoo logo instead? -->
+ <li><a href="./">Home</a></li>
+
+
+
+ <li><a href="enter_bug.cgi?format=guided">New</a></li>
+ <li><a href="enter_bug.cgi">[Ex]</a></li>
+ <li><a href="describecomponents.cgi">Browse</a></li>
+ <li><a href="query.cgi">Search</a></li>
+
+ [% IF user.login %]
+ <li><a href="page.cgi?id=mydashboard.html">Dashboard</a></li>
+ [% END %]
+
+
+
+
+ <li class="dropdown">
+ <a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><i class="fa fa-angle-double-right" aria-hidden="true"></i></a>
+ <ul class="dropdown-menu" role="menu">
+ <li><a href="report.cgi" style="color:#262626">Reports</a></li>
+ <li><a href="https://wiki.gentoo.org/wiki/Foundation:Privacy_Policy" style="color:#262626">Privacy Policy</a></li>
+ [% PROCESS link_to_documentation %]
+ </ul>
+ </li>
+
+ </ul>
+
+ <ul class="nav navbar-nav navbar-right hidden-xs">
+
+
+ [% IF Param('shutdownhtml') || Bugzilla.has_flags %]
+ [% IF user.id %]
+ <li><a href="request.cgi?requester=[% user.login FILTER uri %]&amp;requestee=
+ [% user.login FILTER uri %]&amp;do_union=1&amp;group=type&amp;action=queue"><i class="fa fa-bell" aria-hidden="true"></i></a></li>
+
+
+
+ [%-# Work around FF bug: keep this on one line %]</li>
+ [% ELSE %]
+ <li><a href="request.cgi"><i class="fa fa-bell" aria-hidden="true"></i></a>[%-# Work around FF bug: keep this on one line %]</li>
+ [% END %]
+ [% END %]
+
+
+ [% Hook.process('action-links') %]
+
+
+ <li class="dropdown">
+ <a href="/wiki/Gentoo_Wiki:Menu-Documentation" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"> <span class="fa fa-user" aria-label="Personal tools"></span> [% IF sudoer %] [%+ sudoer.login FILTER html %] (<b>impersonating [%+ user.login FILTER html %]</b> <a href="relogin.cgi?action=end-sudo">end session</a>) [% ELSE %] [%+ user.login FILTER html %] [% END %] <span class="caret"></span></a>
+ <ul class="dropdown-menu" role="menu">
+
+ [% IF user.login %]
+ <li><a href="userprefs.cgi" style="color:#262626">Preferences</a></li>
+
+ [% IF user.can_administer %]
+ <li><a href="admin.cgi" style="color:#262626">Administration</a></li>
+ [% END %]
+
+ <li>
+ [% IF user.authorizer.can_logout %]
+ <a href="index.cgi?logout=1" style="color:#262626">Log&nbsp;out</a>
+ [% ELSE %]
+ Logged&nbsp;in&nbsp;as
+ [% END %]
+ [%-# Work around FF bug: keep this on one line %]</li>
+ [% ELSE %]
+
+ [% IF Param('createemailregexp')
+ && user.authorizer.user_can_create_account %]
+ <li id="new_account_container[% qs_suffix FILTER html %]">
+ <a href="createaccount.cgi" style="color:#262626">New&nbsp;Account</a>
+ </li>
+ [% END %]
+
+ [%# Only display one login form when we're on a LOGIN_REQUIRED page. That
+ # way, we're guaranteed that the user will use the form that has
+ # hidden_fields in it (the center form) instead of this one. Also, it's
+ # less confusing to have one form (as opposed to three) when you're
+ # required to log in.
+ #%]
+ [% IF user.authorizer.can_login && !Bugzilla.page_requires_login %]
+ [% PROCESS "account/auth/login-small.html.tmpl" %]
+ [% END %]
+ [% END %]
+ </ul>
+ </li>
+ </ul>
+
+ <form action="buglist.cgi" class="navbar-form navbar-right" method="get"
+ onsubmit="if (this.quicksearch.value == '')
+ { alert('Please enter one or more search terms first.');
+ return false; } return true;">
+
+ <input type="hidden" id="no_redirect[% qs_suffix FILTER html %]" name="no_redirect" value="0">
+ <script type="text/javascript">
+ if (history && history.replaceState) {
+ var no_redirect = document.getElementById("no_redirect[% qs_suffix FILTER js %]");
+ no_redirect.value = 1;
+ }
+ </script>
+ <div class="input-group" style="margin-top:2px;">
+ <span class="input-group-addon" style="background:#61597b;color:#FFF;border:0px;" id="basic-addon1"><i class="fa fa-search" aria-hidden="true"></i></span>
+ <input class="form-control" style="height:30px;border:0px;background:#61597b;color:#FFF;padding-left:0px;box-shadow: none;" type="text" id="quicksearch[% qs_suffix FILTER html %]" name="quicksearch"
+ title="Quick Search" placeholder="Search Bugs" value="[% quicksearch FILTER html %]">
+ </div>
+ <button class="btn btn-default hidden" type="submit" value="Search"
+ id="find[% qs_suffix FILTER html %]">Search</button>
+
+ [%-# Work around FF bug: keep this on one line %]</form>
+
+ </div>
+ </div>
+</div>
+</nav>
+
+
+
+
+ [% Hook.process("link-row") %]
+[% BLOCK link_to_documentation %]
+ [% IF doc_section %]
+ <li role="separator" class="divider"></li>
+ <li>
+ <a href="[% docs_urlbase _ doc_section FILTER html %]" style="color:#262626" target="_blank">Help</a>
+ </li>
+ [% END %]
+[% END %]
diff --git a/template/en/custom/global/footer.html.tmpl b/template/en/custom/global/footer.html.tmpl
new file mode 100644
index 000000000..8a76805cd
--- /dev/null
+++ b/template/en/custom/global/footer.html.tmpl
@@ -0,0 +1,121 @@
+[%# 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:
+ # This template has no interface. However, you must fulfill the interface to
+ # global/useful-links.html.tmpl.
+ #%]
+
+ [% Hook.process('main-end') %]
+ </div>
+
+
+
+<footer style="bottom: 0px !important; position: absolute !important; width: 100% !important; background-image: url('https://assets.gentoo.org/tyrian/black-thing.svg'),url('https://assets.gentoo.org/tyrian/znurt.svg')!important;">
+ <div class="container">
+ <div class="row">
+ <div class="col-xs-12 col-md-offset-2 col-md-7">
+ <div class="spacer"></div>
+ <ul id="f-list" style="list-style-type: none;">
+
+ [% IF user.id %]
+ <li>
+ [% title = BLOCK %]Open [% terms.bugs %] assigned to me[% END %]
+ <a href="buglist.cgi?f1=assigned_to&amp;o1=equals&amp;v1=%25user%25&amp;resolution=---">
+ [% title FILTER html %]</a> [% IF assignee_count %] ([% assignee_count FILTER html %]) [% END %]
+ <a href="buglist.cgi?f1=assigned_to&amp;o1=equals&amp;v1=%25user%25&amp;resolution=---&amp;ctype=atom&amp;title=[% title FILTER uri %]"><i class="fa fa-rss" aria-hidden="true" style="color:#54487A"></i></a>
+ </li>
+ <li>
+ [% title = BLOCK %]Open [% terms.bugs %] reported by me[% END %]
+ <a href="buglist.cgi?f1=reporter&amp;o1=equals&amp;v1=%25user%25&amp;resolution=---">
+ [% title FILTER html %]</a> [% IF reporter_count %] ([% reporter_count FILTER html %]) [% END %]
+ <a href="buglist.cgi?f1=reporter&amp;o1=equals&amp;v1=%25user%25&amp;resolution=---&amp;ctype=atom&amp;title=[% title FILTER uri %]" ><i class="fa fa-rss" aria-hidden="true" style="color:#54487A"></i></a>
+
+ </li>
+ [% IF Bugzilla.has_flags %]
+ <li>
+ [% title = BLOCK %]Requests addressed to me[% END %]
+ <a href="request.cgi?action=queue&amp;requestee=[% user.login FILTER uri %]&amp;group=type&amp;do_union=0">
+ [% title FILTER html %]</a> [% IF requestee_count %] ([% requestee_count FILTER html %]) [% END %]
+
+ <a href="buglist.cgi?f1=requestees.login_name&amp;o1=equals&amp;v1=%25user%25&amp;ctype=atom&amp;title=[% title FILTER uri %]"><i class="fa fa-rss" aria-hidden="true" style="color:#54487A"></i></a>
+
+ </li>
+ [% END %]
+ [% END %]
+
+ <li>
+ [% terms.Bugs %] reported in the
+ <a href="buglist.cgi?chfield=%5BBug%20creation%5D&amp;chfieldfrom=24h">last 24 hours</a>
+ [% title = BLOCK %][% terms.Bugs %] reported in the last 24 hours[% END %]
+
+ <a href="buglist.cgi?chfield=%5BBug%20creation%5D&amp;chfieldfrom=24h&amp;ctype=atom&amp;title=[% title FILTER uri %]"><i class="fa fa-rss" aria-hidden="true" style="color:#54487A"></i></a>
+
+ | <a href="buglist.cgi?chfield=%5BBug%20creation%5D&amp;chfieldfrom=12h">last 12 hours</a>
+ [% title = BLOCK %][% terms.Bugs %] reported in the last 12 hours[% END %]
+
+ <a href="buglist.cgi?chfield=%5BBug%20creation%5D&amp;chfieldfrom=12h&amp;ctype=atom&amp;title=[% title FILTER uri %]"><i class="fa fa-rss" aria-hidden="true" style="color:#54487A"></i></a>
+
+
+ | <a href="buglist.cgi?chfield=%5BBug%20creation%5D&amp;chfieldfrom=7d">last 7 days</a>
+ [% title = BLOCK %][% terms.Bugs %] reported in the last 7 days[% END %]
+
+ <a href="buglist.cgi?chfield=%5BBug%20creation%5D&amp;chfieldfrom=7d&amp;ctype=atom&amp;title=[% title FILTER uri %]"><i class="fa fa-rss" aria-hidden="true" style="color:#54487A"></i></a>
+
+ </li>
+ <li>
+ [% terms.Bugs %] changed in the
+ <a href="buglist.cgi?chfieldfrom=24h">last 24 hours</a>
+ [% title = BLOCK %][% terms.Bugs %] changed in the last 24 hours[% END %]
+
+ <a href="buglist.cgi?chfieldfrom=24h&amp;ctype=atom&amp;title=[% title FILTER uri %]"><i class="fa fa-rss" aria-hidden="true" style="color:#54487A"></i></a>
+
+ | <a href="buglist.cgi?chfieldfrom=12h">last 12 hours</a>
+ [% title = BLOCK %][% terms.Bugs %] changed in the last 12 hours[% END %]
+
+ <a href="buglist.cgi?chfieldfrom=12h&amp;ctype=atom&amp;title=[% title FILTER uri %]"><i class="fa fa-rss" aria-hidden="true" style="color:#54487A"></i></a>
+
+
+ | <a href="buglist.cgi?chfieldfrom=7d">last 7 days</a>
+ [% title = BLOCK %][% terms.Bugs %] changed in the last 7 days[% END %]
+ <a href="buglist.cgi?chfieldfrom=24h&amp;ctype=atom&amp;title=[% title FILTER uri %]"><i class="fa fa-rss" aria-hidden="true" style="color:#54487A"></i></a>
+ </li>
+ <li></li>
+ </ul>
+ [% PROCESS "global/useful-links.html.tmpl" %]
+ </div>
+ <div class="col-xs-12 col-md-3">
+
+ <br/><small><span id="information" class="header_addl_info">[% "version ${constants.BUGZILLA_VERSION}${constants.GENTOO_APPEND_VERSION} node ${constants.GENTOO_NODE}" %]</span></small>
+ <!-- No questions or comments, the Wiki has enough information on how to contact us. -->
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-xs-3 col-md-2">
+ <ul class="footerlinks three-icons">
+ <li><a href="https://twitter.com/gentoo" title="@Gentoo on Twitter"><span class="fa fa-twitter fa-fw"></span></a></li>
+ <li><a href="https://www.facebook.com/gentoo.org" title="Gentoo on Facebook"><span class="fa fa-facebook fa-fw"></span></a></li>
+ <li></li>
+ </ul>
+ </div>
+ <div class="col-xs-9 col-md-9">
+ <strong>© 2001–2019 Gentoo Foundation, Inc.</strong><br>
+ <small>
+ Gentoo is a trademark of the Gentoo Foundation, Inc.
+ The contents of this document, unless otherwise expressly stated, are licensed under the
+ <a href="https://creativecommons.org/licenses/by-sa/3.0/" rel="license">CC-BY-SA-3.0</a> license.
+ The <a href="https://www.gentoo.org/inside-gentoo/foundation/name-logo-guidelines.html">Gentoo Name and Logo Usage Guidelines</a> apply.
+ </small>
+ </div>
+ </div>
+ </div>
+</footer>
+
+ [% Hook.process("end") %]
+ </body>
+</html>
diff --git a/template/en/custom/global/header.html.tmpl b/template/en/custom/global/header.html.tmpl
new file mode 100644
index 000000000..82da6e7a1
--- /dev/null
+++ b/template/en/custom/global/header.html.tmpl
@@ -0,0 +1,278 @@
+[%# 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:
+ # (All the below interface elements are optional.)
+ # title: string. Page title.
+ # header: string. Main page header.
+ # subheader: string. Page subheader.
+ # header_addl_info: string. Additional header information.
+ # bodyclasses: array of extra CSS classes for the <body>
+ # onload: string. JavaScript code to run when the page finishes loading.
+ # javascript: string. Javascript to go in the header.
+ # javascript_urls: list. List of URLs to Javascript.
+ # style: string. CSS style.
+ # style_urls: list. List of URLs to CSS style sheets.
+ # message: string. A message to display to the user. May contain HTML.
+ # atomlink: Atom link URL, May contain HTML
+ # generate_api_token: generate a token which can be used to make authenticated webservice calls
+ #%]
+
+[% IF message %]
+ [% PROCESS global/messages.html.tmpl %]
+[% END %]
+
+[% DEFAULT
+ subheader = ""
+ header_addl_info = ""
+ onload = ""
+ style_urls = []
+ javascript_urls = []
+ yui = []
+ generate_api_token = 0
+ favicon_url = "images/favicon.ico"
+%]
+
+[% SET yui_css = {
+ autocomplete => 1,
+ calendar => 1,
+ datatable => 1,
+ button => 1,
+} %]
+
+[%# Note: This is simple dependency resolution--you can't have dependencies
+ # that depend on each other. You have to specify all of a module's deps,
+ # if that module is going to be specified in "yui".
+ #%]
+[% SET yui_deps = {
+ autocomplete => ['json', 'connection', 'datasource'],
+ datatable => ['json', 'connection', 'datasource', 'element'],
+} %]
+
+[%# When using certain YUI modules, we need to process certain
+ # extra JS templates.
+ #%]
+[% SET yui_templates = {
+ datatable => ['global/value-descs.js.tmpl'],
+} %]
+
+[%# These are JS URLs that are *always* on the page and come before
+ # every other JS URL.
+ #%]
+[% SET starting_js_urls = [
+ "js/yui/yahoo-dom-event/yahoo-dom-event.js",
+ "js/yui/cookie/cookie-min.js",
+] %]
+
+
+[%# We should be able to set the default value of the header variable
+ # to the value of the title variable using the DEFAULT directive,
+ # but that doesn't work if a caller sets header to the empty string
+ # to avoid header inheriting the value of title, since DEFAULT
+ # mistakenly treats empty strings as undefined and gives header the
+ # value of title anyway. To get around that problem we explicitly
+ # set header's default value here only if it is undefined. %]
+[% IF !header.defined %][% header = title %][% END %]
+
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ [% Hook.process("start") %]
+ <title>[% title %]</title>
+
+ [% IF Param('utf8') %]
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ [% END %]
+
+ [% SET yui = yui_resolve_deps(yui, yui_deps) %]
+
+ [% SET css_sets = css_files(style_urls, yui, yui_css) %]
+ [% IF constants.CONCATENATE_ASSETS %]
+ [% PROCESS format_css_link asset_url = css_sets.unified_standard_skin %]
+ [% ELSE %]
+ [% FOREACH asset_url = css_sets.standard %]
+ [% PROCESS format_css_link %]
+ [% END %]
+ [% FOREACH asset_url = css_sets.skin %]
+ [% PROCESS format_css_link %]
+ [% END %]
+ [% END %]
+
+ [% IF style %]
+ <style type="text/css">
+ [% style %]
+ </style>
+ [% END %]
+
+ [% IF css_sets.unified_custom %]
+ [% IF constants.CONCATENATE_ASSETS %]
+ [% PROCESS format_css_link asset_url = css_sets.unified_custom %]
+ [% ELSE %]
+ [% FOREACH asset_url = css_sets.custom %]
+ [% PROCESS format_css_link %]
+ [% END %]
+ [% END %]
+ [% END %]
+
+ [%# YUI Scripts %]
+ [% FOREACH yui_name = yui %]
+ [% starting_js_urls.push("js/yui/$yui_name/${yui_name}-min.js") %]
+ [% END %]
+ [% starting_js_urls.push('js/global.js') %]
+
+ [% FOREACH asset_url = concatenate_js(starting_js_urls) %]
+ [% PROCESS format_js_link %]
+ [% END %]
+
+ <script type="text/javascript">
+ <!--
+ YAHOO.namespace('bugzilla');
+ YAHOO.util.Event.addListener = function (el, sType, fn, obj, overrideContext) {
+ if ( ("onpagehide" in window || YAHOO.env.ua.gecko) && sType === "unload") { sType = "pagehide"; };
+ var capture = ((sType == "focusin" || sType == "focusout") && !YAHOO.env.ua.ie) ? true : false;
+ return this._addListener(el, this._getType(sType), fn, obj, overrideContext, capture);
+ };
+ if ( "onpagehide" in window || YAHOO.env.ua.gecko) {
+ YAHOO.util.Event._simpleRemove(window, "unload",
+ YAHOO.util.Event._unload);
+ }
+ [%# The language selector needs javascript to set its cookie,
+ # so it is hidden in HTML/CSS by the "bz_default_hidden" class.
+ # If the browser can run javascript, it will then "unhide"
+ # the language selector using the following code.
+ #%]
+ function unhide_language_selector() {
+ YAHOO.util.Dom.removeClass(
+ 'lang_links_container', 'bz_default_hidden'
+ );
+ }
+ YAHOO.util.Event.onDOMReady(unhide_language_selector);
+
+ [%# Make some Bugzilla information available to all scripts.
+ # We don't import every parameter and constant because we
+ # don't want to add a lot of uncached JS to every page.
+ #%]
+ var BUGZILLA = {
+ param: {
+ cookiepath: '[% Param('cookiepath') FILTER js %]',
+ maxusermatches: [% Param('maxusermatches') FILTER js %]
+ },
+ constant: {
+ COMMENT_COLS: [% constants.COMMENT_COLS FILTER js %]
+ },
+ string: {
+ [%# Please keep these in alphabetical order. %]
+
+ attach_desc_required:
+ "You must enter a Description for this attachment.",
+ component_required:
+ "You must select a Component for this [% terms.bug %].",
+ description_required:
+ "You must enter a Description for this [% terms.bug %].",
+ short_desc_required:
+ "You must enter a Summary for this [% terms.bug %].",
+ version_required:
+ "You must select a Version for this [% terms.bug %]."
+ }
+ [% IF generate_api_token %]
+ , api_token: '[% get_api_token FILTER js FILTER html %]'
+ [% END %]
+ };
+
+ [% FOREACH yui_name = yui %]
+ [% FOREACH yui_template = yui_templates.$yui_name %]
+ [% INCLUDE $yui_template %]
+ [% END %]
+ [% END %]
+ [% IF javascript %]
+ [% javascript %]
+ [% END %]
+ // -->
+ </script>
+
+ [% FOREACH asset_url = concatenate_js(javascript_urls) %]
+ [% PROCESS format_js_link %]
+ [% END %]
+
+ [%# this puts the live bookmark up on firefox for the Atom feed %]
+ [% IF atomlink %]
+ <link rel="alternate"
+ type="application/atom+xml" title="Atom feed"
+ href="[% atomlink FILTER html %]">
+ [% END %]
+
+ [%# Required for the 'Autodiscovery' feature in Firefox 2 and IE 7. %]
+ <link rel="search" type="application/opensearchdescription+xml"
+ title="[% terms.Bugzilla %]" href="./search_plugin.cgi">
+ <link rel="shortcut icon" href="[% favicon_url FILTER html %]">
+ [% Hook.process("additional_header") %]
+ </head>
+
+ <body [% IF onload %] onload="[% onload %]"[% END %]
+ class="[% urlbase.replace('^https?://','').replace('/$','').replace('[-~@:/.]+','-') FILTER css_class_quote %]
+ [% FOREACH class = bodyclasses %]
+ [%+ class FILTER css_class_quote %]
+ [% END %] yui-skin-sam">
+
+[% Hook.process("after_body_start") %]
+
+ <div id="header">
+ [% INCLUDE global/banner.html.tmpl %]
+
+ <div id="titles">
+ <span id="title">[% terms.Bugzilla %][% " &ndash; $header" IF header %]</span>
+
+ [% IF subheader %]
+ <span id="subtitle" class="subheader">[% subheader %]</span>
+ [% END %]
+
+ [% IF header_addl_info %]
+ <span id="information" class="header_addl_info">[% header_addl_info %]</span>
+ [% END %]
+ </div>
+
+ [% USE Bugzilla %]
+ [% IF Bugzilla.languages.size > 1 %]
+ <div id="lang_links_container" class="bz_default_hidden">
+ <ul class="links">
+ [% FOREACH lang = Bugzilla.languages.sort %]
+ <li>
+ [% IF NOT loop.first %]<span class="separator"> | </span>[% END %]
+ [% IF lang == current_language %]
+ <span class="lang_current">[% lang FILTER html FILTER upper %]</span>
+ [% ELSE %]
+ <a href="#" onclick="set_language('[% lang FILTER none %]');">
+ [%- lang FILTER html FILTER upper %]</a>
+ [% END %]
+ </li>
+ [% END %]
+ </ul>
+ </div>
+ [% END %]
+
+ <div id="common_links">
+ [% PROCESS "global/common-links.html.tmpl" qs_suffix = "_top" %]
+ </div>
+ </div>
+
+ <div id="bugzilla-body" class="container">
+ [% IF Param('announcehtml') %]
+ [% Param('announcehtml') FILTER none %]
+ [% END %]
+
+ [% IF message %]
+ <div class="alert alert-warning">[% message %]</div>
+ [% END %]
+
+[% BLOCK format_css_link %]
+ <link href="[% asset_url FILTER html %]" rel="stylesheet" type="text/css">
+[% END %]
+
+[% BLOCK format_js_link %]
+ <script type="text/javascript" src="[% asset_url FILTER mtime FILTER html %]"></script>
+[% END %]
diff --git a/template/en/custom/global/product-select.html.tmpl b/template/en/custom/global/product-select.html.tmpl
new file mode 100644
index 000000000..9ec3128dd
--- /dev/null
+++ b/template/en/custom/global/product-select.html.tmpl
@@ -0,0 +1,98 @@
+[%# 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:
+ # name: mandatory; field name
+ # id: optional; field id
+ # value: optional; default field value/selection
+ # classes: optional; an array of classes to be added
+ # onchange: optional; onchange attribute value
+ # disabled: optional; if true, the field is disabled
+ # accesskey: optional; accesskey attribute value
+ # add: optional; prepend menu option for value specified to start of select
+ # dontchange: optional; prepend menu option for "dontchange" to start of select
+ # multiple: optional; do multiselect box, value is size (height) of box
+ # title: optional; extra information to display as a tooltip
+ # products: optional; an array of custom product names
+ # isselect: optional; whether the product list should be displayed as a <select>
+ # or as just the plain text of its value.
+ # valueattribute: optional; the product attribute to be used for <option value="">,
+ # defaults to product name
+ #%]
+
+[% IF !isselect.defined %]
+ [% isselect = 1 %]
+[% END %]
+[% DEFAULT valueattribute = "name" %]
+[% IF isselect %]
+
+ <div class="col-sm-1 align-v-center align-h-right" style="padding-right:0px;">
+ Product:
+ </div>
+ <div class="col-sm-11">
+ <select name="[% name FILTER html %]"
+ [% IF id %] id="[% id FILTER html %]" [% END %]
+ [% IF classes %] class="form-control [% classes.join(' ') FILTER html %]" [% ELSE %] class="form-control" [% END %]
+ [% IF onchange %] onchange="[% onchange FILTER html %]" [% END %]
+ [% IF disabled %] disabled="[% disabled FILTER html %]" [% END %]
+ [% IF accesskey %] accesskey="[% accesskey FILTER html %]" [% END %]
+ [% IF multiple %] multiple="multiple" size="[% multiple FILTER html %]" [% END %]
+ [% IF title %] title="[% title FILTER html %]" [% END %]
+ >
+ [% IF add %]
+ <option value="">[% add FILTER html %]</option>
+ [% END %]
+ [% IF dontchange %]
+ <option value="[% dontchange FILTER html %]">[% dontchange FILTER html %]</option>
+ [% END %]
+
+ [% IF Param('useclassification') %]
+ [% classifications = {} %]
+ [% IF products %]
+ [% FOREACH p = products %]
+ [% IF NOT classifications.${p.classification.name}.defined %]
+ [% classifications.${p.classification.name} = [] %]
+ [% END %]
+ [% classifications.${p.classification.name}.push(p) %]
+ [% END %]
+ [% ELSE %]
+ [% FOREACH c = user.get_selectable_classifications %]
+ [% classifications.${c.name} = [] %]
+ [% FOREACH p = user.get_selectable_products(c.id) %]
+ [% classifications.${c.name}.push(p) %]
+ [% END %]
+ [% END %]
+ [% END %]
+
+ [% FOREACH c = all_classifications %]
+ [% NEXT UNLESS classifications.${c}.size %]
+ <optgroup label="[% c FILTER html %]">
+ [% FOREACH p = classifications.$c %]
+ <option value="[% p.$valueattribute FILTER html %]"
+ [% " selected" IF (cgi.param(name) == p.name) || (value.contains(p.name)) %]>
+ [% p.name FILTER html %]
+ </option>
+ [% END %]
+ </optgroup>
+ [% END %]
+ [% ELSE %]
+ [% IF NOT products.defined %]
+ [% products = user.get_selectable_products %]
+ [% END %]
+ [% FOREACH p = products %]
+ <option value="[% p.$valueattribute FILTER html %]"
+ [% " selected" IF (cgi.param(name) == p.name) || (value.contains(p.name)) %]>
+ [% p.name FILTER html %]
+ </option>
+ [% END %]
+ [% END %]
+ </select>
+</div>
+[% ELSE %]
+ [% value.join(', ') FILTER html %]
+[% END %]
diff --git a/template/en/custom/global/select-menu.html.tmpl b/template/en/custom/global/select-menu.html.tmpl
new file mode 100644
index 000000000..4d02b8c7e
--- /dev/null
+++ b/template/en/custom/global/select-menu.html.tmpl
@@ -0,0 +1,52 @@
+[%# 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:
+ # name: string; the name of the menu.
+ #
+ # multiple: boolean; whether or not the menu is multi-select
+ #
+ # size: integer; the number of items to display at once
+ #
+ # options: array or hash; the items with which to populate the array.
+ # If a hash is passed, the hash keys become the names displayed
+ # to the user while the hash values become the value of the item.
+ #
+ # default: string; the item selected in the menu by default.
+ #
+ # onchange: code; JavaScript to be run when the user changes the value
+ # selected in the menu.
+ #%]
+
+[%# Get the scalar representation of the options reference,
+ # which looks like "ARRAY(0xA352BA3F)" or "HASH(0xA352BA3F)",
+ # so we can figure out whether it is a reference to an array
+ # or a hash.
+ #%]
+[% options_type = BLOCK %][% options %][% END %]
+
+<select class="form-control" name="[% name FILTER html %]"
+ [% IF onchange %]onchange="[% onchange FILTER html %]"[% END %]
+ [% IF multiple %] multiple [% END %]
+ [% IF size %] size="[% size %]" [% END %]>
+ [% IF options_type.search("ARRAY") %]
+ [% FOREACH value = options %]
+ <option value="[% value FILTER html %]"
+ [% " selected" IF value == default %]>
+ [% value FILTER html %]
+ </option>
+ [% END %]
+ [% ELSIF options_type.search("HASH") %]
+ [% FOREACH option = options %]
+ <option value="[% option.value FILTER html %]"
+ [% " selected" IF option.value == default %]>
+ [% option.key FILTER html %]
+ </option>
+ [% END %]
+ [% END %]
+</select>
diff --git a/template/en/custom/global/tabs.html.tmpl b/template/en/custom/global/tabs.html.tmpl
new file mode 100644
index 000000000..4d6cb8bfd
--- /dev/null
+++ b/template/en/custom/global/tabs.html.tmpl
@@ -0,0 +1,50 @@
+[%# 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:
+ # tabs: List of hashes. Must have at least one item. Each hash has:
+ # name: string. Name of the tab.
+ # link: string. relative URL to the tab's resource on this installation.
+ # label: string. text displayed in the tab.
+ # current_tab_name: string. name of the currently selected tab
+ #%]
+
+<div class="bs-example bs-example-tabs" data-example-id="togglable-tabs">
+
+ <div class="panel panel-default">
+ <div >
+ <ul class="nav nav-pills nav-justified" id="myTabs" role="tablist">
+
+ [% FOREACH tab = tabs %]
+ [% IF tab.name == current_tab_name %]
+ <li role="presentation" class="active"><a href="#home" style="border-radius:0px!important;color:#555!important;" id="tab_[% tab.name FILTER html %]" role="tab" data-toggle="tab" aria-controls="tab_[% tab.name FILTER html %]" aria-expanded="true">[% tab.label FILTER html %]</a></li>
+ [% ELSE %]
+ <li onClick="document.location='[% tab.link FILTER js FILTER html %]'" role="presentation"><a href="[% tab.link FILTER html %]" style="border-radius:0px!important;" id="tab_[% tab.name FILTER html %]" role="tab" data-toggle="tab" aria-controls="tab_[% tab.name FILTER html %]" aria-expanded="true">[% tab.label FILTER html %]</a></li>
+ <!-- <a href="[% tab.link FILTER html %]"></a> -->
+ [% END %]
+ [% END %]
+ </ul>
+ </div>
+ <div class="panel-body">
+ <div class="tab-content" id="myTabContent">
+ <div class="tab-pane fade active in" role="tabpanel" id="home" aria-labelledby="tab_[% tab.name FILTER html %]">
+ [% content %]
+ </div>
+ <!--
+ <div class="tab-pane fade" role="tabpanel" id="profile" aria-labelledby="profile-tab">
+ </div>
+ -->
+
+
+ </div>
+ </div>
+ </div>
+
+
+
+</div>
diff --git a/template/en/custom/global/textarea.html.tmpl b/template/en/custom/global/textarea.html.tmpl
new file mode 100644
index 000000000..24cd51950
--- /dev/null
+++ b/template/en/custom/global/textarea.html.tmpl
@@ -0,0 +1,58 @@
+[%# 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:
+ #
+ # id: (optional) The "id"-attribute of the textarea.
+ # name: (optional) The "name"-attribute of the textarea.
+ # accesskey: (optional) The "accesskey"-attribute of the textarea.
+ # classes: (optional) The "class"-attribute of the textarea.
+ # wrap: (deprecated; optional) The "wrap"-attribute of the textarea.
+ # disabled: (optional) Disable the textarea.
+ # placeholder: (optional) Placeholder.
+ # readonly: (optional) Prevent the textarea from being edited.
+ # minrows: (required) Number of rows the textarea shall have initially
+ # and when not having focus.
+ # maxrows: (optional) Number of rows the textarea shall have if
+ # maximized (which happens on getting focus). If not given,
+ # the textarea doesn't maximize when getting focus.
+ # defaultrows: (optional) Number of rows the textarea shall have if
+ # the zoom_textareas user preference if off. If not given,
+ # minrows will be used.
+ # cols: (required) Number of columns the textarea shall have.
+ # defaultcontent: (optional) Default content for the textarea.
+ # mandatory: (optional) Boolean specifying whether or not the textarea
+ # is mandatory.
+ # field_hidden: (optional) True if the field is hidden. Only useful if
+ # the field is mandatory.
+ #%]
+
+<textarea [% IF name %]name="[% name FILTER html %]"[% END %]
+ [% IF id %] id="[% id FILTER html %]"[% END %]
+ [% IF accesskey %] accesskey="[% accesskey FILTER html %]"[% END %]
+ [% IF classes %] class="[% classes FILTER html %]"[% END %]
+ [% IF wrap %] wrap="[% wrap FILTER html %]"[% END %]
+ [% IF disabled %] disabled="disabled"[% END %]
+ [% IF placeholder %] placeholder="[% placeholder FILTER html %]"[% END %]
+ [% IF readonly %] readonly="readonly"[% END %]
+ [% IF defaultrows && user.settings.zoom_textareas.value == 'off' %]
+ rows="[% defaultrows FILTER html %]"
+ [% ELSE %]
+ rows="[% minrows FILTER html %]"
+ [% END %]
+ cols="[% cols FILTER html %]"
+ [% IF maxrows && user.settings.zoom_textareas.value == 'on' %]
+ onfocusout="this.rows=10"
+ onFocus="this.rows=[% maxrows FILTER html %]"
+ [% END %]
+ [% IF mandatory %]
+ data-required="true" [% 'aria-required="true" required' UNLESS field_hidden %]
+ [% END %]
+ [% IF onchange %]
+ onchange="[% onchange FILTER html %]"
+ [% END %]>[% defaultcontent FILTER html %]</textarea>
diff --git a/template/en/custom/global/useful-links.html.tmpl b/template/en/custom/global/useful-links.html.tmpl
new file mode 100644
index 000000000..086fe2e91
--- /dev/null
+++ b/template/en/custom/global/useful-links.html.tmpl
@@ -0,0 +1,74 @@
+[%# 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.
+ #%]
+
+<ul id="useful-links" style="list-style-type:none;">
+ <!--
+ <li id="links-actions">
+ [ % PROCESS "global/common-links.html.tmpl" qs_suffix = "_bottom" % ]
+ </li>
+ -->
+
+ [%# Saved searches %]
+
+ [% IF user.showmybugslink OR user.queries.size %]
+ <li id="links-saved">
+ <ul class="links">
+ [% print_pipe = 0 %]
+ [% IF user.showmybugslink %]
+ [% filtered_username = user.login FILTER uri %]
+ <li>
+ <a href="[% Param('mybugstemplate').replace('%userid%', filtered_username) %]">My [% terms.Bugs %]</a>
+ </li>
+ [% print_pipe = 1 %]
+ [% END %]
+
+ [% FOREACH q = user.queries %]
+ [% NEXT UNLESS q.link_in_footer %]
+ <li>
+ [% '<span class="separator">| </span>' IF print_pipe %]
+ <a href="buglist.cgi?cmdtype=runnamed&amp;namedcmd=[% q.name FILTER uri %]">[% q.name FILTER html %]</a>
+ </li>
+ [% print_pipe = 1 %]
+ [% END %]
+ </ul>
+ </li>
+ [% END %]
+
+ [% IF user.queries_subscribed.size %]
+ <li id="links-shared">
+ <ul class="links">
+ [% FOREACH q = user.queries_subscribed %]
+ <li>
+ [% '<span class="separator">| </span>' UNLESS loop.first %]
+ <a href="buglist.cgi?cmdtype=dorem&amp;remaction=run&amp;namedcmd=
+ [%- q.name FILTER uri %]&amp;sharer_id=[% q.user.id FILTER uri %]"
+ class="shared" title="Shared by [% q.user.identity FILTER html %]">
+ [%- q.name FILTER html %]</a>
+ </li>
+ [% END %]
+ </ul>
+ </li>
+ [% END %]
+
+ [% IF user.reports.size %]
+ <li id="reports-saved">
+ <ul class="links">
+ [% FOREACH r = user.reports %]
+ <li>
+ [% '<span class="separator">| </span>' UNLESS loop.first %]
+ <a href="report.cgi?[% r.query FILTER html %]&amp;saved_report_id=
+ [%~ r.id FILTER uri %]">[% r.name FILTER html %]</a>
+ </li>
+ [% END %]
+ </ul>
+ </li>
+ [% END %]
+
+ [%# Sections of links to more things users can do on this installation. %]
+ [% Hook.process("end") %]
+</ul>
diff --git a/template/en/custom/index.html.tmpl b/template/en/custom/index.html.tmpl
new file mode 100644
index 000000000..5fd09ab96
--- /dev/null
+++ b/template/en/custom/index.html.tmpl
@@ -0,0 +1,197 @@
+[%# 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:
+ # release: a hash containing data about new releases, if any.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "$terms.Bugzilla Main Page"
+ header = "Main Page"
+ header_addl_info = "version ${constants.BUGZILLA_VERSION}${constants.GENTOO_APPEND_VERSION} node ${constants.GENTOO_NODE}"
+%]
+
+[% IF release %]
+ <div id="new_release" class="alert alert-danger">
+ [% IF release.data %]
+ [% IF release.deprecated %]
+ <p>Bugzilla [%+ release.deprecated FILTER html %] is no longer
+ supported. You are highly encouraged to upgrade in order to keep your
+ system secure.</p>
+ [% END %]
+
+ <p>A new Bugzilla version ([% release.data.latest_ver FILTER html %])
+ is available at
+ <a href="[% release.data.url FILTER html %]">[% release.data.url FILTER html %]</a>.<br>
+ Release date: [% release.data.date FILTER html %]</p>
+
+ <p class="notice">This message is only shown to logged in users with admin privs.
+ You can configure this notification from the
+ <a href="editparams.cgi?section=general#upgrade_notification_desc">Parameters</a> page.</p>
+ [% ELSIF release.error == "cannot_download" %]
+ <p>The remote file <a href="[% constants.REMOTE_FILE FILTER html %]">
+ [%~ constants.REMOTE_FILE FILTER html %]</a> cannot be downloaded
+ (reason: [% release.reason FILTER html %]).<br>
+ Either the remote server is temporarily unavailable, or your web server cannot access
+ the web. If you are behind a proxy, set the
+ <a href="editparams.cgi?section=advanced#proxy_url_desc">proxy_url</a> parameter correctly.</p>
+ [% ELSIF release.error == "no_write" %]
+ <p>The local XML file '[% constants.LOCAL_FILE FILTER html %]' cannot be created
+ (reason: [% release.reason FILTER html %]).<br>
+ Please make sure the web server can write into this directory.
+ [% ELSIF release.error == "no_update" %]
+ <p>The local XML file '[% constants.LOCAL_FILE FILTER html %]' cannot be updated.
+ Please make sure the web server can edit this file.</p>
+ [% ELSIF release.error == "no_access" %]
+ <p>The local XML file '[% constants.LOCAL_FILE FILTER html %]' cannot be read.
+ Please make sure this file has the correct rights set on it.</p>
+ [% ELSIF release.error == "corrupted" %]
+ <p>The local XML file '[% constants.LOCAL_FILE FILTER html %]' has an invalid XML format.
+ Please delete it and try accessing this page again.</p>
+ [% ELSIF release.error == "unknown_parameter" %]
+ <p>'[% Param("upgrade_notification") FILTER html %]' is not a valid notification
+ parameter. Please check this parameter in the
+ <a href="editparams.cgi?section=general#upgrade_notification_desc">Parameters</a> page.</p>
+ [% END %]
+ </div>
+[% END %]
+
+<div id="page-index">
+
+<div class="jumbotron">
+ <h2 class="site-welcome stick-top" style="font-family: Bitter,'Open Sans',sans-serif; font-size: 2.5em;text-align: center;margin-bottom: 1em;">Welcome to [% terms.Bugzilla %]</h2>
+
+ <div>
+ <form id="quicksearchForm" name="quicksearchForm" action="buglist.cgi">
+
+
+ <div class="row">
+ <div class="col-lg-12">
+ <div class="input-group">
+ <input id="quicksearch_main" name="quicksearch" class="form-control" title="Quick Search" placeholder="Enter [% terms.abug %] # or some search terms" autofocus required>
+ <div class="input-group-btn">
+ <div class="btn-group">
+ <a href="page.cgi?id=quicksearch.html" title="Quick Search help" class="btn btn-default" type="button"><span class="fa fa-question"></span></a>
+ </div>
+ <div class="btn-group">
+ <button id="find" type="submit" class="btn btn-default" value="Quick Search">Search</button>
+ </div>
+ </div>
+ </div><!-- /input-group -->
+ </div><!-- /.col-lg-6 -->
+ </div>
+
+ </form>
+
+ <ul class="additional_links" style="display: none;">
+ [% Hook.process('additional_links') %]
+ </ul>
+ </div><br>
+ <small class="text-muted">[% Hook.process('intro') %]</small>
+
+</div>
+
+ <div class="intro"></div>
+
+
+ <div class="bz_common_actions">
+
+ <div class="row" style="width:80%; margin: 0 auto;">
+
+ <div class="col-lg-3" style="cursor:pointer;">
+ <a href="enter_bug.cgi">
+ <div class="row index_page_icon" style="height: 170px; width: 145px; margin: 0 auto">
+ <div class="col-12">
+ <i class="fa fa-file-text" aria-hidden="true" style="font-size:100px;"></i>
+ </div>
+ <div class="col-12" style="margin-top: 15px;">
+ File a Bug
+ </div>
+ </div>
+ </a>
+ </div>
+
+ <div class="col-lg-3" style="cursor:pointer;">
+ <a href="query.cgi">
+ <div class="row index_page_icon" style="height: 170px; width: 145px; margin: 0 auto">
+ <div class="col-12">
+ <i class="fa fa-search" aria-hidden="true" style="font-size:100px;"></i>
+ </div>
+ <div class="col-12" style="margin-top: 15px;">
+ Search
+ </div>
+ </div>
+ </a>
+ </div>
+
+
+ <div class="col-lg-3" onclick="" style="cursor:pointer;">
+ <a href="[% IF user.id %] userprefs.cgi [% ELSIF Param('createemailregexp') && user.authorizer.user_can_create_account %] createaccount.cgi [% ELSE %] ?GoAheadAndLogIn=1 [% END %]">
+ <div class="row index_page_icon" style="height: 170px; width: 145px; margin: 0 auto">
+ <div class="col-12">
+ <i class="fa fa-user-circle-o" aria-hidden="true" style="font-size:100px;"></i>
+ </div>
+ <div class="col-12" style="margin-top: 15px;">
+ [% IF user.id %]
+ User Preferences
+ [% ELSIF Param('createemailregexp') && user.authorizer.user_can_create_account %]
+ New Account
+ [% ELSE %]
+ Log In
+ [% END %]
+ </div>
+ </div>
+ </a>
+ </div>
+
+ <div class="col-lg-3" style="cursor:pointer;">
+ <a href="[% docs_urlbase FILTER html %]using/index.html">
+ <div class="row index_page_icon" style="height: 170px; width: 145px; margin: 0 auto">
+ <div class="col-12">
+ <i class="fa fa-question-circle" aria-hidden="true" style="font-size:100px;"></i>
+ </div>
+ <div class="col-12" style="margin-top: 15px;">
+ Documentation
+ </div>
+ </div>
+ </a>
+ </div>
+ </div>
+
+ <br><br><br><br><br>
+ <ul style="display: none">
+ <li>
+ <a id="enter_bug" href="enter_bug.cgi"><span>File [% terms.aBug %]</span></a>
+
+
+ </li>
+ <li>
+ <a id="query" href="query.cgi"><span>Search</span></a>
+ </li>
+ <li>
+ <a id="account"
+ [% IF user.id %]
+ href="userprefs.cgi"><span>User Preferences</span></a>
+ [% ELSIF Param('createemailregexp') && user.authorizer.user_can_create_account %]
+ href="createaccount.cgi"><span>New Account</span></a>
+ [% ELSE %]
+ href="?GoAheadAndLogIn=1"><span>Log In</span></a>
+ [% END %]
+ </li>
+ <li>
+ <a id="help" href="[% docs_urlbase FILTER html %]using/index.html"><span>Documentation</span></a>
+ </li>
+ </ul>
+ </div>
+
+
+
+
+</div>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/custom/list/list.html.tmpl b/template/en/custom/list/list.html.tmpl
new file mode 100644
index 000000000..df544b7ea
--- /dev/null
+++ b/template/en/custom/list/list.html.tmpl
@@ -0,0 +1,379 @@
+[%# 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:
+ # searchtype: string. Type of search - either "series", "saved" or undef.
+ # ...
+ # defaultsavename: string. The default name for saving the query.
+ #%]
+
+[%############################################################################%]
+[%# Template Initialization #%]
+[%############################################################################%]
+
+[% PROCESS "global/field-descs.none.tmpl" %]
+
+[% USE Bugzilla %]
+[% cgi = Bugzilla.cgi %]
+
+[% unfiltered_title = "$terms.Bug List" %]
+[% IF searchname || defaultsavename %]
+ [% unfiltered_title = unfiltered_title _ ": " _ (searchname OR defaultsavename) %]
+[% END %]
+[% title = unfiltered_title FILTER html %]
+
+[% qorder = order FILTER uri IF order %]
+
+[% javascript = BLOCK %]
+ [% IF quicksearch %]
+ [% new_param = BLOCK ~%]
+ quicksearch=[% quicksearch FILTER uri %]
+ [%~ IF cgi.param('list_id') ~%]
+ &list_id=[% cgi.param('list_id') FILTER uri %]
+ [%~ END %]
+ [% END %]
+ [% ELSIF cgi.param('token') != '' %]
+ [% new_param = cgi.canonicalise_query('token', 'cmdtype', 'remtype') %]
+ [% ELSE %]
+ [% new_param = cgi.canonicalise_query %]
+ [% END %]
+
+ [% IF new_param.length + 12 < constants.CGI_URI_LIMIT %]
+ if (history && history.replaceState) {
+ history.replaceState(null, "[% unfiltered_title FILTER js %]",
+ "buglist.cgi?[% new_param FILTER js %]");
+ document.title = "[% unfiltered_title FILTER js %]";
+ }
+ [% END %]
+ [% javascript FILTER none %]
+[% END %]
+
+[%############################################################################%]
+[%# Page Header #%]
+[%############################################################################%]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ generate_api_token = dotweak
+ atomlink = "buglist.cgi?$urlquerypart&title=$title&ctype=atom"
+ yui = [ 'autocomplete', 'calendar' ]
+ javascript_urls = [ "js/util.js", "js/field.js", "js/TUI.js" ]
+ style_urls = [ "skins/standard/buglist.css" ]
+ doc_section = "using/finding.html"
+%]
+
+
+<div class="bz_query_head">
+
+
+ <span class="bz_query_timestamp" style="color:#505050">
+ [% currenttime FILTER time('%a %b %e %Y %T %Z') FILTER html %]<br>
+ </span>
+ <br/>
+
+ [% IF debug %]
+ <div class="bz_query_debug">
+ <p>Total execution time: [% query_time FILTER html %] seconds</p>
+ [% FOREACH query = queries %]
+ <pre>[% query.sql FILTER html %]</pre>
+ <p>Execution time: [% query.time FILTER html %] seconds</p>
+ [% IF query.explain %]
+ <pre>[% query.explain FILTER html %]</pre>
+ [% END %]
+ [% END %]
+ </div>
+ [% END %]
+
+</div>
+
+[% IF toolong %]
+ <h2 class="bz_smallminded">
+ This list is too long for Bugzilla's little mind; the
+ Next/Prev/First/Last buttons won't appear on individual [% terms.bugs %].
+ </h2>
+[% END %]
+
+[% SET shown_types = [
+ 'notequals', 'regexp', 'notregexp', 'lessthan', 'lessthaneq',
+ 'greaterthan', 'greaterthaneq', 'changedbefore', 'changedafter',
+ 'changedfrom', 'changedto', 'changedby', 'notsubstring', 'nowords',
+ 'nowordssubstr', 'notmatches', 'isempty', 'isnotempty'
+] %]
+
+
+[%############################################################################%]
+[%# Preceding Status Line #%]
+[%############################################################################%]
+
+[% IF bugs.size > 9 %]
+ [% PROCESS num_results %]
+[% END %]
+
+[%############################################################################%]
+[%# Start of Change Form #%]
+[%############################################################################%]
+
+<div class="" style="color:#505050">
+ <ul class="search_description">
+ <li>[% PROCESS num_results %]</li>
+ [% FOREACH desc_item = search_description %]
+ <li>
+ <strong>[% field_descs.${desc_item.field} FILTER html %]:</strong>
+ [% IF shown_types.contains(desc_item.type) || debug %]
+ ([% search_descs.${desc_item.type} FILTER html %])
+ [% END %]
+ [% FOREACH val IN desc_item.value.split(',') %]
+ [%+ display_value(desc_item.field, val) FILTER html %][% ',' UNLESS loop.last %]
+ [% END %]
+ [% IF debug %]
+ (<code>[% desc_item.term FILTER html %]</code>)
+ [% END %]
+ </li>
+ [% END %]
+ </ul>
+</div>
+
+<hr style="margin-top:10px;" />
+
+
+
+
+[% IF dotweak %]
+ <form name="changeform" method="post" action="process_bug.cgi">
+[% END %]
+
+[%############################################################################%]
+[%# Bug Table #%]
+[%############################################################################%]
+
+[% PROCESS list/table.html.tmpl %]
+
+[%############################################################################%]
+[%# Succeeding Status Line #%]
+[%############################################################################%]
+
+
+[% IF bugs.size == 0 %]
+ <ul class="zero_result_links">
+ <li>[% PROCESS enter_bug_link %]</li>
+ [% IF one_product.defined %]
+ <li><a href="enter_bug.cgi">File a new [% terms.bug %] in a
+ different product</a></li>
+ [% END %]
+ <li><a href="[% PROCESS edit_search_url %]">Edit this search</a></li>
+ <li><a href="query.cgi">Start a new search</a></li>
+ </ul>
+[% END %]
+
+[%############################################################################%]
+[%# Rest of Change Form #%]
+[%############################################################################%]
+
+[% IF dotweak %]
+ [% PROCESS "list/edit-multiple.html.tmpl" %]
+ </form>
+ <hr>
+[% END %]
+
+<br>
+
+ <div>
+
+[%############################################################################%]
+[%# Navigation Bar #%]
+[%############################################################################%]
+
+ <div style="display: flex;flex-wrap: wrap;margin-top:10px;">
+ <div style="margin: 5px;">
+ <div class="btn-group" role="group">
+ <div class="">
+ <button class="btn btn-primary" type="button" id="edit_search"
+ onclick="document.location='[% PROCESS edit_search_url FILTER js %]'">
+ Edit Search</button>
+ </div>
+ </div>
+ </div>
+
+ [% IF bugs.size > 0 %]
+ <div style="margin: 5px;">
+ <form method="post" action="show_bug.cgi">
+ [% buglist_joined = buglist.join(",") %]
+ <input type="hidden" name="id" value="[% buglist_joined FILTER html %]">
+ <input type="hidden" name="format" value="multiple">
+ <input class="btn btn-default" type="submit" id="long_format" value="Long Format">
+ </form>
+ </div>
+
+ <div style="margin: 5px;">
+ [% IF user.is_timetracker %]
+ <form method="post" action="summarize_time.cgi">
+ <input type="hidden" name="id" value="[% buglist_joined FILTER html %]" />
+ <input class="btn btn-default" type="submit" id="timesummary" value="Time Summary" />
+ </form>
+ [% IF time_summary_limited %]
+ <span class="bz_info">
+ Time Summary will only include the [% terms.bugs %] shown above.
+ In order to see a time summary for all [% terms.bugs %] found
+ by the search, you can
+ <a href="buglist.cgi?[% urlquerypart FILTER html %]
+ [%- "&order=$qorder" FILTER html IF order %]&limit=0">
+ show all search results</a>.
+ </span>
+ [% END %]
+ [% END %]
+ </div>
+
+ <div style="margin: 5px;">
+ <form method="post" action="show_bug.cgi">
+ <input type="hidden" name="ctype" value="xml">
+ [% FOREACH id = buglist %]
+ <input type="hidden" name="id" value="[% id FILTER html %]">
+ [% END %]
+ <input type="hidden" name="excludefield" value="attachmentdata">
+ <div class="btn-group" role="group">
+ <button type="submit" id="xml" class="btn btn-default">
+ XML
+ </button>
+ <a href="buglist.cgi?[% urlquerypart FILTER html %]&amp;ctype=csv&amp;human=1" class="btn btn-default">
+ CSV
+ </a>
+ <a href="buglist.cgi?[% urlquerypart FILTER html %]&amp;title=
+ [%- title FILTER uri %]&amp;ctype=atom" class="btn btn-default">
+ <i class="fa fa-rss" aria-hidden="true"></i>
+ </a>
+ <a href="buglist.cgi?[% urlquerypart FILTER html %]&amp;ctype=ics" class="btn btn-default">
+ <i class="fa fa-calendar" aria-hidden="true"></i>
+ </a>
+ </div>
+ </form>
+ </div>
+
+
+ <div style="margin: 5px;">
+ <button class="btn btn-default" type="button" id="change_columns"
+ onclick="document.location='colchange.cgi?[% urlquerypart FILTER html %]&amp;query_based_on=
+ [%~ defaultsavename OR searchname FILTER uri FILTER js %]'">
+ Change Columns</button>
+ </div>
+
+ [% IF bugs.size > 1 && caneditbugs && !dotweak %]
+ <div style="margin: 5px;">
+ <button class="btn btn-default" type="button" id="mass_change"
+ onclick="document.location='buglist.cgi?[% urlquerypart FILTER html %]
+ [%- "&order=$qorder" FILTER html IF order %]&amp;tweak=1'">
+ Change Several [% terms.Bugs %] at Once</button>
+ </div>
+ [% END %]
+
+ [% IF bugowners && user.id %]
+ <div style="margin: 5px;">
+ <button class="btn btn-default" type="button" id="email_assignees"
+ onclick="document.location='mailto:[% bugowners FILTER html %]'">
+ Send Mail to [% terms.Bug %] Assignees</button>
+ </div>
+ [% END %]
+
+ [%# Links to more things users can do with this bug list. %]
+ [% Hook.process("links") %]
+
+
+ [% END %]
+ <div style="margin: 5px;">
+ [% IF searchtype == "saved" %]
+ <div class="bz_query_forget">
+ <button class="btn btn-default" type="button" id="forget_search"
+ onclick="document.location='buglist.cgi?cmdtype=dorem&amp;remaction=forget&amp;namedcmd=
+ [%- searchname FILTER uri FILTER js %]&amp;token=
+ [%- issue_hash_token([search_id, searchname]) FILTER uri %]'">
+ Forget Search '[% searchname FILTER html %]'</button>
+ </div>
+ [% ELSE %]
+ <div class="bz_query_remember">
+ <form method="get" action="buglist.cgi">
+ <input type="hidden" name="newquery"
+ value="[% urlquerypart FILTER html %][% "&order=$qorder" FILTER html IF order %]">
+ <input type="hidden" name="cmdtype" value="doit">
+ <input type="hidden" name="remtype" value="asnamed">
+ <input type="hidden" name="token" value="[% issue_hash_token(['savedsearch']) FILTER html %]">
+
+ <div class="input-group">
+
+ <span class="input-group-btn">
+ <button class="btn btn-default" type="submit" id="remember" value="Remember search">Remember search</button>
+ </span>
+ <span class="input-group-addon" id="basic-addon1">as</span>
+ <input type="text" class="form-control" id="save_newqueryname" name="newqueryname" size="20" style="margin-left:-1px;"
+ title="New query name" value="[% defaultsavename FILTER html %]" aria-describedby="basic-addon1">
+ </div>
+
+ </form>
+ </div>
+ [% END %]
+ </div>
+
+ </div>
+ </div>
+
+[% IF one_product.defined && bugs.size %]
+ <p class="bz_query_single_product" style="margin: 5px;">
+ [% PROCESS enter_bug_link %]
+ </p>
+[% END %]
+
+[%############################################################################%]
+[%# Page Footer #%]
+[%############################################################################%]
+
+[% PROCESS global/footer.html.tmpl %]
+
+[%##########%]
+[%# Blocks #%]
+[%##########%]
+
+[% BLOCK edit_search_url %]
+ [% editqueryname = searchname OR defaultsavename OR '' %]
+ query.cgi?[% urlquerypart FILTER html %]
+ [%- IF editqueryname != '' %]&amp;known_name=
+ [%- editqueryname FILTER uri %]
+ [% END %]
+[% END %]
+
+[% BLOCK enter_bug_link %]
+ <a href="enter_bug.cgi
+ [%- IF one_product.defined %]?product=
+ [%- one_product.name FILTER uri %]
+ [%- IF one_component.defined %]&amp;component=
+ [%- one_component FILTER uri %][% END %][% END %]">File
+ a new [% terms.bug %]
+ [% IF one_product.defined %]
+ in the
+ [% IF one_component.defined %]
+ "[% one_component FILTER html %]" component of the
+ [% END %]
+ "[% one_product.name FILTER html %]" product
+ [% END %]</a>
+[% END %]
+
+[% BLOCK num_results %]
+ <small class="bz_result_count">
+ [% IF bugs.size == 0 %]
+ <span class="zero_results">[% terms.zeroSearchResults %].</span>
+ [% ELSIF default_limited AND bugs.size >= Param('default_search_limit') %]
+ This result was limited to [% Param('default_search_limit') FILTER html %]
+ [%+ terms.bugs %].
+ <a href="buglist.cgi?[% urlquerypart FILTER html %]
+ [%- "&order=$qorder" FILTER html IF order %]&limit=0">See
+ all search results for this query</a>.
+ [% time_summary_limited = 1 %]
+ [% ELSIF bugs.size == 1 %]
+ <b><span style="text-transform: capitalize;">[% terms.bug %] found:</span></b> One
+ [% ELSE %]
+ <b><span style="text-transform: capitalize;">[%+ terms.bugs %]</span> found:</b> [% bugs.size %]
+ [% END %]
+ </small>
+[% END %]
diff --git a/template/en/custom/list/table.html.tmpl b/template/en/custom/list/table.html.tmpl
new file mode 100644
index 000000000..efed2cc11
--- /dev/null
+++ b/template/en/custom/list/table.html.tmpl
@@ -0,0 +1,267 @@
+[%# 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.
+ #%]
+
+[%############################################################################%]
+[%# Initialization #%]
+[%############################################################################%]
+
+[%# Don't display the table or do any processing if there are no bugs
+ # to display %]
+[% RETURN IF !bugs.size %]
+
+[%# Columns whose titles or values should be abbreviated to make the list
+ # more compact. For columns whose titles should be abbreviated,
+ # the shortened title is included. For columns whose values should be
+ # abbreviated, a maximum length is provided along with the ellipsis that
+ # should be added to an abbreviated value, if any.
+ # wrap is set if a column's contents should be allowed to be word-wrapped
+ # by the browser.
+ #%]
+
+[% field_descs.short_short_desc = field_descs.short_desc %]
+[% field_descs.assigned_to_realname = field_descs.assigned_to %]
+[% field_descs.reporter_realname = field_descs.reporter %]
+[% field_descs.qa_contact_realname = field_descs.qa_contact %]
+
+[%# Setting maxlength => 0 means no limit. We set it for performance reasons. %]
+[% abbrev =
+ {
+ "bug_severity" => { maxlength => 3 , title => "Sev" } ,
+ "priority" => { maxlength => 7 , title => "Pri" } ,
+ "rep_platform" => { maxlength => 3 , title => "HW" } ,
+ "bug_status" => { maxlength => 4 } ,
+ "assigned_to" => { maxlength => 30 , ellipsis => "..." } ,
+ "assigned_to_realname" => { maxlength => 20 , ellipsis => "..." } ,
+ "reporter" => { maxlength => 30 , ellipsis => "..." } ,
+ "reporter_realname" => { maxlength => 20 , ellipsis => "..." } ,
+ "qa_contact" => { maxlength => 30 , ellipsis => "..." , title => "QAContact" } ,
+ "qa_contact_realname" => { maxlength => 20 , ellipsis => "..." , title => "QAContact" } ,
+ "resolution" => { maxlength => 4 } ,
+ "short_desc" => { maxlength => 0, wrap => 1 } ,
+ "short_short_desc" => { maxlength => 60 , ellipsis => "..." , wrap => 1 } ,
+ "status_whiteboard" => { maxlength => 0, title => "Whiteboard" , wrap => 1 } ,
+ "keywords" => { maxlength => 0, wrap => 1 } ,
+ "tags" => { maxlength => 0, title => "Tags", wrap => 1},
+ "dependson" => { maxlength => 0, wrap => 1 } ,
+ "blocked" => { maxlength => 0, wrap => 1 } ,
+ "flagtypes.name" => { maxlength => 0, wrap => 1 } ,
+ "component" => { maxlength => 8 , title => "Comp" } ,
+ "product" => { maxlength => 8 } ,
+ "version" => { maxlength => 5 , title => "Vers" } ,
+ "op_sys" => { maxlength => 12 } ,
+ "bug_file_loc" => { maxlength => 30 } ,
+ "target_milestone" => { maxlength => 0, title => "TargetM" } ,
+ "longdescs.count" => { maxlength => 0, title => "# Comments" },
+ "percentage_complete" => { maxlength => 0, format_value => "%d %%" } ,
+ }
+%]
+
+[% PROCESS bug/time.html.tmpl %]
+
+[% Hook.process("before_table") %]
+
+[%############################################################################%]
+[%# Table Header #%]
+[%############################################################################%]
+
+[% tableheader = BLOCK %]
+ <table class="bz_buglist">
+ <tr class="bz_buglist_header bz_first_buglist_header">
+ [% IF dotweak %]
+ <th>&nbsp;</th>
+ [% END %]
+ <th colspan="[% splitheader ? 2 : 1 %]" class="first-child">
+ <a style="color:#4A406C;text-decoration: none;" href="buglist.cgi?
+ [% urlquerypart FILTER html %]&amp;order=
+ [% PROCESS new_order id='bug_id' %]
+ [%-#%]&amp;query_based_on=
+ [% defaultsavename OR searchname FILTER uri %]">ID
+ [% PROCESS order_arrow id='bug_id' ~%]
+ </a>
+ </th>
+
+ [% IF splitheader %]
+
+ [% FOREACH id = displaycolumns %]
+ [% NEXT UNLESS loop.count() % 2 == 0 %]
+ [% column = columns.$id %]
+ [% PROCESS columnheader %]
+ [% END %]
+
+ </tr><tr class="bz_buglist_header">
+ [% IF dotweak %]
+ <th>&nbsp;</th>
+ [% END %]
+ <th>&nbsp;</th>
+
+ [% FOREACH id = displaycolumns %]
+ [% NEXT IF loop.count() % 2 == 0 %]
+ [% column = columns.$id %]
+ [% PROCESS columnheader %]
+ [% END %]
+
+ [% ELSE %]
+
+ [% FOREACH id = displaycolumns %]
+ [% column = columns.$id %]
+ [% PROCESS columnheader %]
+ [% END %]
+
+ [% END %]
+
+ </tr>
+[% END %]
+
+[% BLOCK columnheader %]
+ <th colspan="[% splitheader ? 2 : 1 %]">
+ <a style="color:#4A406C;text-decoration: none;" href="buglist.cgi?[% urlquerypart FILTER html %]&amp;order=
+ [% PROCESS new_order %]
+ [%-#%]&amp;query_based_on=
+ [% defaultsavename OR searchname FILTER uri %]">
+ [%- abbrev.$id.title || field_descs.$id || column.title FILTER html -%]
+ [% PROCESS order_arrow ~%]
+ </a>
+ </th>
+[% END %]
+
+[% BLOCK new_order %]
+ [% desc = '' %]
+ [% IF (om = order.match("\\b$id( DESC)?")) %]
+ [% desc = ' DESC' IF NOT om.0 %]
+ [% END %]
+ [% id _ desc FILTER uri %]
+ [% IF id != 'bug_id' AND order %]
+ [% ',' _ order.remove("\\b$id( DESC)?(,\\s*|\$)") FILTER uri %]
+ [% END %]
+[% END %]
+
+[% BLOCK order_arrow %]
+ [% IF order.search("^$id DESC") %]
+ <span class="bz_sort_order_primary">&#x25BC;</span>
+ [% ELSIF order.search("^$id(,\\s*|\$)") %]
+ <span class="bz_sort_order_primary">&#x25B2;</span>
+ [% ELSIF order.search("\\b$id DESC") %]
+ <span class="bz_sort_order_secondary">&#x25BC;</span>
+ [% ELSIF order.search("\\b$id(,\\s*|\$)") %]
+ <span class="bz_sort_order_secondary">&#x25B2;</span>
+ [% END %]
+[% END %]
+
+[%############################################################################%]
+[%# Bug Table #%]
+[%############################################################################%]
+
+[% tableheader %]
+
+[% FOREACH bug = bugs %]
+ [% count = loop.count() %]
+
+ <tr id="b[% bug.bug_id %]" class="bz_bugitem
+ bz_[% bug.bug_severity FILTER css_class_quote -%]
+ bz_[% bug.priority FILTER css_class_quote -%]
+ bz_[% bug.bug_status FILTER css_class_quote -%]
+ [%+ "bz_$bug.resolution" FILTER css_class_quote IF bug.resolution -%]
+ [%+ "bz_secure" IF bug.secure_mode -%]
+ [%+ "bz_secure_mode_$bug.secure_mode" FILTER css_class_quote IF bug.secure_mode -%]
+ [%+ count % 2 == 1 ? "bz_row_odd" : "bz_row_even" -%]
+ ">
+
+ [% IF dotweak %]
+ <td class="bz_checkbox_column">
+ <input type="checkbox" name="id_[% bug.bug_id %]">
+ </td>
+ [% END %]
+ <td class="first-child bz_id_column">
+ <a href="show_bug.cgi?id=[% bug.bug_id %]">[% bug.bug_id %]</a>
+ <span class="bz_default_hidden">[%+ '[SEC]' IF bug.secure_mode %]</span>
+ </td>
+
+ [% FOREACH column = displaycolumns %]
+ [% col_abbrev = abbrev.$column %]
+ <td class="bz_[% column FILTER css_class_quote %]_column
+ [%~ ' nowrap' UNLESS col_abbrev.wrap
+ OR bug_fields.$column.type == constants.FIELD_TYPE_FREETEXT
+ OR bug_fields.$column.type == constants.FIELD_TYPE_TEXTAREA %]">
+ [% IF col_abbrev.maxlength %]
+ <span title="[%- display_value(column, bug.$column) FILTER html %]">
+ [% END %]
+ [% IF col_abbrev.format_value %]
+ [%- bug.$column FILTER format(col_abbrev.format_value) FILTER html -%]
+ [% ELSIF column == 'actual_time' ||
+ column == 'remaining_time' ||
+ column == 'estimated_time' %]
+ [% PROCESS formattimeunit time_unit=bug.$column %]
+ [%# Display the login name of the user if their real name is empty. %]
+ [% ELSIF column.search('_realname$') && bug.$column == '' %]
+ [% SET login_column = column.remove('_realname$') %]
+ [% bug.${login_column}.truncate(col_abbrev.maxlength,
+ col_abbrev.ellipsis) FILTER html %]
+ [% ELSIF column == 'short_desc' || column == "short_short_desc" %]
+ <a href="show_bug.cgi?id=[% bug.bug_id FILTER html %]">
+ [%- bug.$column.truncate(col_abbrev.maxlength, col_abbrev.ellipsis) FILTER html -%]
+ </a>
+ [% ELSIF bug_fields.$column.type == constants.FIELD_TYPE_BUG_ID %]
+ <a href="show_bug.cgi?id=[% bug.$column FILTER html %]">
+ [%- bug.$column.truncate(col_abbrev.maxlength, col_abbrev.ellipsis) FILTER html -%]
+ </a>
+ [% ELSIF bug_fields.$column.type == constants.FIELD_TYPE_TEXTAREA %]
+ [%- bug.$column.truncate(256, '...') FILTER html -%]
+ [% ELSIF column == 'bug_file_loc' && is_safe_url(bug.bug_file_loc) %]
+ <a href="[% bug.bug_file_loc FILTER html %]" target="_blank"
+ rel="noreferrer" title="[% bug.bug_file_loc FILTER html %]">
+ [%- display_value(column, bug.$column).truncate(col_abbrev.maxlength, col_abbrev.ellipsis) FILTER html -%]
+ </a>
+ [% ELSE %]
+ [%- display_value(column, bug.$column).truncate(col_abbrev.maxlength, col_abbrev.ellipsis) FILTER html -%]
+ [% END %]
+ [% IF col_abbrev.maxlength %]
+ </span>
+ [% END %]
+ </td>
+ [% END %]
+
+ </tr>
+[% END %]
+
+[% IF time_info.time_present %]
+ [% PROCESS time_summary_line %]
+[% END %]
+
+</table>
+
+[% BLOCK time_summary_line %]
+ <tr class="bz_time_summary_line">
+ [% columns_to_span = 1 %] [%# bugID %]
+ [% IF dotweak %]
+ [% columns_to_span = columns_to_span + 1 %]
+ [% END %]
+ [% FOREACH column = displaycolumns %]
+ [% IF column == 'actual_time' ||
+ column == 'remaining_time' ||
+ column == 'estimated_time' ||
+ column == 'percentage_complete' %]
+ [% IF columns_to_span > 0 %]
+ <td class="bz_total bz_total_label" colspan="
+ [%- columns_to_span FILTER html %]"><b>Totals</b></td>
+ [% columns_to_span = 0 %]
+ [% END %]
+ [% IF column == 'percentage_complete' %]
+ <td class="bz_total">[% time_info.percentage_complete
+ FILTER format(abbrev.$column.format_value) FILTER html %]</td>
+ [% ELSE %]
+ <td class="bz_total">
+ [%- PROCESS formattimeunit time_unit=time_info.$column %]</td>
+ [% END %]
+ [% ELSIF columns_to_span == 0 %] [%# A column following the first total %]
+ <td class="bz_total">&nbsp;</td>
+ [% ELSE %] [%# We haven't gotten to a time column yet, keep computing span %]
+ [% columns_to_span = columns_to_span + 1 %]
+ [% END %]
+ [% END %]
+ </tr>
+[% END %]
diff --git a/template/en/custom/reports/components.html.tmpl b/template/en/custom/reports/components.html.tmpl
new file mode 100644
index 000000000..648b1c516
--- /dev/null
+++ b/template/en/custom/reports/components.html.tmpl
@@ -0,0 +1,150 @@
+[%# 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:
+ # product: object. The product for which we want to display component
+ # descriptions.
+ #%]
+
+[% title = BLOCK %]
+ Components for [% product.name FILTER html %]
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ style_urls = ['skins/standard/buglist.css']
+ title = title
+%]
+
+[% IF Param("useqacontact") %]
+ [% numcols = 3 %]
+[% ELSE %]
+ [% numcols = 2 %]
+[% END %]
+
+<div class="row">
+ <div class="col-sm-2"></div>
+ <div class="col-sm-8">
+ <div class="text-center">
+ <h1>[% product.name FILTER html %]</h1>
+
+ <p id="product_desc">[% product.description FILTER html_light %]</p>
+
+ <p><small>Select a component to see open [% terms.bugs %] in that component.</small></p>
+ </div>
+ </div>
+ <div class="col-sm-2"></div>
+</div>
+
+
+
+<div class="row" style="margin-bottom:10px;">
+<div class="col-sm-11">
+
+ <ul class="nav nav-pills pull-right" role="tablist">
+ <li role="presentation" class=" active">
+ <a class="btn btn-default btn-xs bgo_tab" style="border-right:0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px;" href="#detailed" aria-controls="detailed" role="tab" data-toggle="tab"><i class="fa fa-th-list" aria-hidden="true"></i></a>
+ </li>
+ <li role="presentation" class="" style="margin-left:0px;">
+ <a class="btn btn-default btn-xs bgo_tab" style="border-top-left-radius: 0px; border-bottom-left-radius: 0px;" href="#condensed" aria-controls="condensed" role="tab" data-toggle="tab"><i class="fa fa-list-ul" aria-hidden="true"></i></a>
+ </li>
+ </ul>
+</div>
+<div class="col-sm-1"></div>
+</div>
+
+<div class="row">
+<div class="col-sm-1"></div>
+<div class="col-sm-10">
+
+ <div class="tab-content">
+ <div role="tabpanel" class="tab-pane" id="condensed">
+ <table id="component_table">
+ <tr>
+ <th>Component</th>
+ <th>Default Assignee</th>
+ [% IF Param("useqacontact") %]
+ <th>Default QA Contact</th>
+ [% END %]
+ </tr>
+ [% FOREACH comp = product.components %]
+ [% INCLUDE describe_comp %]
+ [% END %]
+ </table>
+ </div>
+ <div role="tabpanel" class="tab-pane active" id="detailed">
+ [% FOREACH comp = product.components %]
+ [% INCLUDE describe_comp_detailed %]
+ [% END %]
+ </div>
+ </div>
+
+</div>
+<div class="col-sm-1"></div>
+</div>
+
+[% PROCESS global/footer.html.tmpl %]
+
+[%############################################################################%]
+[%# BLOCK for components %]
+[%############################################################################%]
+
+
+[% BLOCK describe_comp_detailed %]
+<div id="[% comp.name FILTER html %]" class="panel panel-default" style="margin-bottom:10px;">
+<div class="panel-body">
+ <div class="row">
+
+ <div class="col-sm-4">
+
+ <h3 style="font-weight:400;margin-top:0px;margin-bottom:0px;"><a href="buglist.cgi?product=
+ [%- product.name FILTER uri %]&amp;component=
+ [%- comp.name FILTER uri %]&amp;resolution=---">
+ [% comp.name FILTER html %]</a></h3>
+
+ </div>
+
+ <div class="col-sm-8">
+ <!-- TODO Include QA contract
+ [% IF Param("useqacontact") %]
+ [% IF comp.default_qa_contact %]
+ [% INCLUDE global/user.html.tmpl who = comp.default_qa_contact %]
+ [% END %]
+ [% END %]
+ -->
+ [% comp.description FILTER html_light %]
+ |<small>[% INCLUDE global/user.html.tmpl who = comp.default_assignee %]</small>
+ </div>
+ </div>
+</div>
+</div>
+[% END %]
+
+
+[% BLOCK describe_comp %]
+ <tr id="[% comp.name FILTER html %]">
+ <td rowspan="2" class="component_name">
+ <a href="buglist.cgi?product=
+ [%- product.name FILTER uri %]&amp;component=
+ [%- comp.name FILTER uri %]&amp;resolution=---">
+ [% comp.name FILTER html %]</a>
+ </td>
+ <td class="component_assignee">
+ [% INCLUDE global/user.html.tmpl who = comp.default_assignee %]
+ </td>
+ [% IF Param("useqacontact") %]
+ [% IF comp.default_qa_contact %]
+ [% INCLUDE global/user.html.tmpl who = comp.default_qa_contact %]
+ [% END %]
+ [% END %]
+ </tr>
+ <tr>
+ <td colspan="[% numcols - 1 %]" class="component_description">
+ [% comp.description FILTER html_light %]
+ </td>
+ </tr>
+[% END %]
diff --git a/template/en/custom/reports/duplicates-simple.html.tmpl b/template/en/custom/reports/duplicates-simple.html.tmpl
new file mode 100644
index 000000000..c94b30f4e
--- /dev/null
+++ b/template/en/custom/reports/duplicates-simple.html.tmpl
@@ -0,0 +1,27 @@
+[%# 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:
+ # You need to fulfill the interface to duplicates-table.html.tmpl.
+ #%]
+
+<!DOCTYPE html>
+<html>
+ [% IF product.size %]
+ [% title = BLOCK %]
+ Most Frequently Reported [% terms.Bugs %] for [% product.join(', ') FILTER html %]
+ [% END %]
+ [% ELSE %]
+ [% title = "Most Frequently Reported $terms.Bugs" %]
+ [% END%]
+
+
+ <body>
+ [% PROCESS "reports/duplicates-table.html.tmpl" %]
+ </body>
+</html>
diff --git a/template/en/custom/reports/duplicates-table.html.tmpl b/template/en/custom/reports/duplicates-table.html.tmpl
new file mode 100644
index 000000000..92f9b617f
--- /dev/null
+++ b/template/en/custom/reports/duplicates-table.html.tmpl
@@ -0,0 +1,112 @@
+[%# 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:
+ # bugs: list of hashes. May be empty. Each hash has three members:
+ # bug: A Bugzilla::Bug object
+ # count: integer. The number of dupes
+ # delta: integer. The change in count in the last $changedsince days
+ #
+ # bug_ids: list of integers. May be empty. The IDs of the bugs in $bugs.
+ #
+ # sortby: string. the column on which we are sorting the buglist.
+ # reverse: boolean. True if we are reversing the current sort.
+ # maxrows: integer. Max number of rows to display.
+ # changedsince: integer. The number of days ago for the changedsince column.
+ # openonly: boolean. True if we are only showing open bugs.
+ # product: array of strings. Restrict to these products only.
+ #%]
+
+[%# *** Column Headers *** %]
+
+[% SET columns = [
+ { name => "id", description => "$terms.Bug #" },
+ { name => "count", description => "Dupe<br>Count" },
+ { name => "delta",
+ description => "Change in last<br>$changedsince day(s)" },
+ { name => "component", description => field_descs.component },
+ { name => "bug_severity", description => field_descs.bug_severity },
+ { name => "priority", description => field_descs.priority },
+ { name => "target_milestone", description => field_descs.target_milestone },
+ { name => "short_desc", description => field_descs.short_desc },
+] %]
+
+[% SET base_args = [] %]
+[% FOREACH param = ['maxrows', 'openonly', 'format', 'sortvisible',
+ 'changedsince', 'product']
+%]
+ [% NEXT IF NOT ${param}.defined %]
+ [% FOREACH value = ${param} %]
+ [% filtered_value = value FILTER uri %]
+ [% base_args.push("$param=$filtered_value") %]
+ [% END %]
+[% END %]
+[% IF sortvisible %]
+ [% bug_ids_string = bug_ids.nsort.join(',') FILTER uri %]
+ [% base_args.push("bug_id=$bug_ids_string") %]
+[% END %]
+[% base_args_string = base_args.join('&amp;') %]
+
+
+
+[% IF bugs.size %]
+ <table id="duplicates_table" class="table">
+ <thead>
+ <tr>
+ [% FOREACH column = columns %]
+ [% IF column.name == sortby %]
+ [%# We add this to the column object so it doesn't affect future
+ # iterations of the loop.
+ #%]
+ [% column.reverse_sort = reverse ? 0 : 1 %]
+ [% END %]
+ <th class="[% column.name FILTER html %]">
+ <a href="duplicates.cgi?sortby=[% column.name FILTER uri %]
+ [% IF column.reverse_sort.defined %]
+ [%- %]&amp;reverse=[% column.reverse_sort FILTER uri %]
+ [% END %]
+ [% IF base_args_string %]
+ [% "&amp;$base_args_string" FILTER none %]
+ [% END %]"
+ >[% column.description FILTER none %]</a>
+ </th>
+ [% END %]
+ </tr>
+ </thead>
+
+ [%# *** Buglist *** %]
+
+ <tbody>
+ [% FOREACH item = bugs %]
+ [% SET bug = item.bug %]
+ <tr [% " class='resolved'" IF NOT bug.isopened %]>
+ <td class="id">
+ [% bug.id FILTER bug_link(bug) FILTER none %]
+ </td>
+ <td class="count">[% item.count FILTER html %]</td>
+ <td class="delta">[% item.delta FILTER html %]</td>
+ <td class="component">[% bug.component FILTER html %]</td>
+ <td class="bug_severity">
+ [%- display_value('bug_severity', bug.bug_severity) FILTER html %]
+ </td>
+ <td class="priority">
+ [%- display_value('priority', bug.priority) FILTER html %]
+ </td>
+ <td class="target_milestone">
+ [% display_value('target_milestone',
+ bug.target_milestone) FILTER html %]
+ </td>
+ <td class="short_desc">[% bug.short_desc FILTER html %]</td>
+ </tr>
+ [% END %]
+ </tbody>
+ </table>
+[% ELSE %]
+<div class="row" style="margin: 20px;"><div class="col-sm-12"><div class="text-center">No duplicate [% terms.bugs %] found.</div></div></div>
+[% END %]
+
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>
diff --git a/template/en/custom/whine/schedule.html.tmpl b/template/en/custom/whine/schedule.html.tmpl
new file mode 100644
index 000000000..7538a1425
--- /dev/null
+++ b/template/en/custom/whine/schedule.html.tmpl
@@ -0,0 +1,412 @@
+[%# 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:
+ # events: hash, keyed by event_id number. Values are anonymous hashes of:
+ # schedule: array of hashes containing schedule info:
+ # day: value in day column
+ # time: value selected in time column
+ # mailto_type: 0=user 1=group
+ # mailto: recipient's id (profile or group)
+ # queries: as with schedule, an anonymous array containing hashes of:
+ # name: the named query's name
+ # title: title to be displayed on the results
+ # sort: integer that sets execution order on named queries
+ #%]
+
+[% title = "Set up whining" %]
+[% PROCESS global/header.html.tmpl
+ title = title
+ style_urls = ['skins/standard/admin.css']
+ doc_section = "using/index.html"
+%]
+
+<p>
+ "Whining" is when Bugzilla executes a saved search at a regular interval
+ and sends the resulting list of [% terms.bugs %] via email.
+</p>
+
+<p>
+ To set up a new whine event, click "Add a new event." Enter a subject line
+ for the message that will be sent, along with a block of text that will
+ accompany the [% terms.bug %] list in the body of the message.
+</p>
+
+<p>
+ Schedules are added to an event by clicking on "Add a new schedule." A schedule
+ consists of a day, a time of day or interval of times
+ (e.g., every 15 minutes), and a target email address that may or may not be
+ alterable, depending on your privileges. Events may have more than one schedule
+ in order to run at multiple times or for different users.
+</p>
+
+<p>
+ Searches come from saved searches, which are created by executing a <a
+ href="query.cgi">search</a>, then telling Bugzilla to remember
+ the search under a particular name. Add a search by clicking "Add a
+ search", and select the desired saved search name under "Search" and add a
+ title for the [% terms.bug %] table. The optional number entered under
+ "Sort" will determine the execution order (lowest to highest) if multiple
+ queries are listed. If you check "One message per [% terms.bug %]," each [%
+ terms.bug %] that matches the search will be sent in its own email message.
+</p>
+
+<p>
+ All times are server local time ([% local_timezone FILTER html %]).
+</p>
+
+<form method="post" action="editwhines.cgi">
+[%# This hidden submit button must be here to set default behavior when
+ the user presses return on a form input field #%]
+<input type="submit" value="Update / Commit" id="commit" name="commit"
+ class="bz_default_hidden">
+<input type="hidden" name="update" value="1">
+<input type="hidden" name="token" value="[% token FILTER html %]">
+
+[% FOREACH event = events %]
+
+<table class="whining_list">
+ <tr>
+ <th class="subtitle">Event:</th>
+ <th colspan="2">
+ <input type="submit" value="Remove Event"
+ name="remove_event_[% event.key %]"
+ id="remove_event_[% event.key %]">
+ </th>
+ </tr>
+
+ <tr>
+ <th>Email subject line:</th>
+ <td colspan="2">
+ <input type="text" name="event_[% event.key %]_subject"
+ size="60" maxlength="128" value="
+ [%- event.value.subject FILTER html %]">
+ </td>
+ </tr>
+
+ <tr>
+ <th>Descriptive text sent within whine message:</th>
+ <td colspan="2">
+ [% INCLUDE global/textarea.html.tmpl
+ name = "event_${event.key}_body"
+ minrows = 3
+ maxrows = 10
+ defaultrows = 5
+ cols = 80
+ defaultcontent = event.value.body
+ %]
+ </td>
+ </tr>
+
+ <tr>
+ <th>Send a message even if there are no [% terms.bugs %] in the search result:</th>
+ <td colspan="2">
+ <input type="checkbox" name="event_[% event.key %]_mailifnobugs"
+ [%- IF event.value.mailifnobugs == 1 %] checked [% END %]>
+ </td>
+ </tr>
+
+ [% IF event.value.schedule.size == 0 %]
+
+ <tr>
+ <th>Schedule:</th>
+ <td class="unset" colspan="2">
+ Not scheduled to run<br>
+ <input type="submit" value="Add a new schedule"
+ name="add_schedule_[% event.key %]"
+ id="add_schedule_[% event.key %]">
+ </td>
+ </tr>
+
+ [% ELSE %]
+
+ <tr>
+ <th>Schedule:</th>
+ <td class="set" colspan="2">
+
+ <table class="schedule_list">
+ <tr>
+ <th>Interval</th>
+ <th>
+ [% IF mail_others %]
+ Mail to
+ [% END %]
+ </th>
+ <th></th>
+ </tr>
+
+ [% FOREACH schedule = event.value.schedule %]
+ <tr>
+ <td>
+ [%# these hidden fields allow us to compare old values instead
+ of reading the database to tell if a field has changed %]
+
+ <input type="hidden" value="[% schedule.day FILTER html %]"
+ name="orig_day_[% schedule.id %]">
+ <input type="hidden" value="[% schedule.time FILTER html %]"
+ name="orig_time_[% schedule.id %]">
+ [% PROCESS day_field val=schedule.day %]
+ [% PROCESS time_field val=schedule.time %]
+ </td>
+ <td>
+ [% IF mail_others %]
+ <input type="hidden" name="orig_mailto_type_[% schedule.id %]"
+ value="[% schedule.mailto_type FILTER html %]">
+ <select name="mailto_type_[% schedule.id %]">
+ <option value="0" [% IF schedule.mailto_type == 0 %]
+ selected
+ [% END %]>User</option>
+ <option value="1" [% IF schedule.mailto_type == 1 %]
+ selected
+ [% END %]>Group</option>
+ </select>
+ <input type="hidden" name="orig_mailto_[% schedule.id %]"
+ value="[% schedule.mailto FILTER html %]">
+ <input type="text" name="mailto_[% schedule.id %]"
+ value="[% schedule.mailto FILTER html %]" size="30">
+ [% END %]
+ </td>
+ <td>
+ <input type="submit" value="Remove"
+ name="remove_schedule_[% schedule.id %]"
+ id="remove_schedule_[% schedule.id %]">
+ </td>
+ </tr>
+ [% END %]
+
+ <tr>
+ <td colspan="3">
+ <input type="submit" value="Add a new schedule"
+ name="add_schedule_[% event.key %]"
+ id="add_schedule_[% event.key %]">
+ </td>
+ </tr>
+ </table>
+
+ </td>
+ </tr>
+
+ [% END %]
+
+ [% IF event.value.queries.size == 0 %]
+
+ <tr>
+ <th>Searches:</th>
+ <td>
+ No searches <br>
+ <input type="submit" value="Add a search"
+ name="add_query_[% event.key %]"
+ id="add_query_[% event.key %]">
+ </td>
+ <td class="right">
+ <input type="submit" value="Update / Commit" name="commit" id="update">
+ </td>
+ </tr>
+
+ [% ELSE %]
+
+ <tr>
+ <th>Searches:</th>
+ <td colspan="2">
+
+ <table class="search_list">
+ <tr>
+ <th>Sort</th>
+ <th>Search</th>
+ <th>Title</th>
+ <th colspan="2"></th>
+ </tr>
+
+ [% FOREACH query = event.value.queries %]
+
+ <tr>
+ <td>
+ <input type="text" name="query_sort_[% query.id %]"
+ size="3" value="[% query.sort %]">
+ <input type="hidden" value="[% query.sort %]"
+ name="orig_query_sort_[% query.id %]">
+ </td>
+ <td>
+ <input type="hidden" value="[% query.name FILTER html %]"
+ name="orig_query_name_[% query.id %]">
+ [% PROCESS query_field thisquery=query.name %]
+ </td>
+ <td>
+ <input type="hidden" value="[% query.title FILTER html %]"
+ name="orig_query_title_[% query.id %]">
+ <input type="text" name="query_title_[% query.id %]"
+ size="50" value="[% query.title FILTER html %]"
+ maxlength="64">
+ </td>
+ <td>
+ <input type="hidden" value="[% query.onemailperbug FILTER html %]"
+ name="orig_query_onemailperbug_[% query.id %]">
+ <input type="checkbox" [% IF query.onemailperbug == 1 %] checked [% END %]
+ id="query_onemailperbug_[% query.id %]"
+ name="query_onemailperbug_[% query.id %]">
+ <label for="query_onemailperbug_[% query.id %]">One message per [% terms.bug %]</label>
+ </td>
+ <td>
+ <input type="submit" value="Remove"
+ name="remove_query_[% query.id %]"
+ id="remove_query_[% query.id %]">
+ </td>
+ </tr>
+
+ [% END %]
+
+ <tr>
+ <td colspan="3">
+ <input type="submit" value="Add a search"
+ name="add_query_[% event.key %]"
+ id="add_query_[% event.key %]">
+ </td>
+ <td colspan="2" class="right">
+ <input type="submit" value="Update / Commit" name="commit" id="update">
+ </td>
+ </tr>
+ </table>
+
+ </td>
+ </tr>
+
+ [% END %]
+
+</table>
+
+[% END %]
+
+<p>
+ <input type="submit" class="btn btn-primary" value="Add a new event" name="add_event" id="add_event">
+</p>
+
+</form>
+
+[% PROCESS global/footer.html.tmpl %]
+
+[% BLOCK query_field +%]
+
+ [% IF available_queries.size > 0 %]
+
+ <select name="query_name_[% query.id %]">
+ [% FOREACH q = available_queries %]
+ <option [% "selected" IF q == thisquery %] value="[% q FILTER html %]">
+ [% q FILTER html %]
+ </option>
+ [% END %]
+ </select>
+
+ [% ELSE %]
+ Please visit the <a href="query.cgi">Search</a> page and save a search
+ [% END %]
+
+[%+ END %]
+
+[% BLOCK day_field +%]
+ <select name="day_[% schedule.id %]">
+ [%
+ options = [
+ ['All', 'Each day', ],
+ ['MF', 'Monday through Friday', ],
+ ['Sun', 'Sunday', ],
+ ['Mon', 'Monday', ],
+ ['Tue', 'Tuesday', ],
+ ['Wed', 'Wednesday', ],
+ ['Thu', 'Thursday', ],
+ ['Fri', 'Friday', ],
+ ['Sat', 'Saturday', ],
+ ['1', 'On the 1st of the month', ],
+ ['2', 'On the 2nd of the month', ],
+ ['3', 'On the 3rd of the month', ],
+ ['4', 'On the 4th of the month', ],
+ ['5', 'On the 5th of the month', ],
+ ['6', 'On the 6th of the month', ],
+ ['7', 'On the 7th of the month', ],
+ ['8', 'On the 8th of the month', ],
+ ['9', 'On the 9th of the month', ],
+ ['10', 'On the 10th of the month', ],
+ ['11', 'On the 11th of the month', ],
+ ['12', 'On the 12th of the month', ],
+ ['13', 'On the 13th of the month', ],
+ ['14', 'On the 14th of the month', ],
+ ['15', 'On the 15th of the month', ],
+ ['16', 'On the 16th of the month', ],
+ ['17', 'On the 17th of the month', ],
+ ['18', 'On the 18th of the month', ],
+ ['19', 'On the 19th of the month', ],
+ ['20', 'On the 20th of the month', ],
+ ['21', 'On the 21st of the month', ],
+ ['22', 'On the 22nd of the month', ],
+ ['23', 'On the 23rd of the month', ],
+ ['24', 'On the 24th of the month', ],
+ ['25', 'On the 25th of the month', ],
+ ['26', 'On the 26th of the month', ],
+ ['27', 'On the 27th of the month', ],
+ ['28', 'On the 28th of the month', ],
+ ['29', 'On the 29th of the month', ],
+ ['30', 'On the 30th of the month', ],
+ ['31', 'On the 31st of the month', ],
+ ['last', 'Last day of the month', ],
+ ]
+ %]
+
+ [% FOREACH option = options %]
+ <option value="[% option.0 %]"
+ [%- IF val == option.0 +%] selected[% END %]>
+ [%- option.1 -%]
+ </option>
+ [% END %]
+
+ </select>
+[%+ END %]
+
+[% BLOCK time_field +%]
+<select name="time_[% schedule.id %]">
+
+ [%
+ options = [
+ [ '0', 'at midnight', ],
+ [ '1', 'at 01:00', ],
+ [ '2', 'at 02:00', ],
+ [ '3', 'at 03:00', ],
+ [ '4', 'at 04:00', ],
+ [ '5', 'at 05:00', ],
+ [ '6', 'at 06:00', ],
+ [ '7', 'at 07:00', ],
+ [ '8', 'at 08:00', ],
+ [ '9', 'at 09:00', ],
+ [ '10', 'at 10:00', ],
+ [ '11', 'at 11:00', ],
+ [ '12', 'at 12:00', ],
+ [ '13', 'at 13:00', ],
+ [ '14', 'at 14:00', ],
+ [ '15', 'at 15:00', ],
+ [ '16', 'at 16:00', ],
+ [ '17', 'at 17:00', ],
+ [ '18', 'at 18:00', ],
+ [ '19', 'at 19:00', ],
+ [ '20', 'at 20:00', ],
+ [ '21', 'at 21:00', ],
+ [ '22', 'at 22:00', ],
+ [ '23', 'at 23:00', ],
+ [ '60min', 'every hour', ],
+ [ '30min', 'every 30 minutes', ],
+ [ '15min', 'every 15 minutes', ],
+ ]
+ %]
+
+ [% FOREACH option = options %]
+ <option value="[% option.0 %]"
+ [%- IF val == option.0 +%] selected[% END %]>
+ [%- option.1 -%]
+ </option>
+ [% END %]
+
+</select>
+
+[%+ END %]