aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Magorsch <max@magorsch.de>2019-12-23 04:07:14 +0100
committerMax Magorsch <max@magorsch.de>2019-12-23 04:07:14 +0100
commit9c74d6f0467f87407da28ef85e79733eeca35188 (patch)
tree2d8575d79122bc5fd1defca27d6bade58afea88e
parentAdd docker files for development purposes (diff)
downloadbugzilla-dev/tyrian-theme.tar.gz
bugzilla-dev/tyrian-theme.tar.bz2
bugzilla-dev/tyrian-theme.zip
Add a first draft of a tyrian based appearancedev/tyrian-theme
The bugzilla templates have been changed to match the tyrian theme. The second customization method from [1] has been choosen, as hooks aren't sufficient for the changes that are needed to make it work. Meaning: A new 'custom' folder is present in the 'template' directory. The custom directory contains templates which override the templates in the default directory. This is a first draft and not covering everything yet. There are still some parts / pages that need to be migrated to the new theme. However, this can easily be done by adding new templates in the 'custom' folder which will override the templates in the default folder by default. [1] https://bugzilla.readthedocs.io/en/5.0/integrating/templates.html Signed-off-by: Max Magorsch <max@magorsch.de>
-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 %]