summaryrefslogtreecommitdiffstats
path: root/extensions/BMO/web
diff options
context:
space:
mode:
authorKohei Yoshino <kohei.yoshino@gmail.com>2018-09-24 21:55:28 +0200
committerDylan William Hardison <dylan@hardison.net>2018-09-24 21:55:28 +0200
commitb3ad67dc224403c463fbea5ddb5f01dcacf3cb02 (patch)
treebfaf21cf064c0b41efd68dbe678baf182ce802d1 /extensions/BMO/web
parent8047b0395f5175da934f3aaf09b15a15d83da755 (diff)
downloadbugzilla-b3ad67dc224403c463fbea5ddb5f01dcacf3cb02.tar.gz
bugzilla-b3ad67dc224403c463fbea5ddb5f01dcacf3cb02.tar.xz
Bug 1473417 - Show often/recently used products/components on New Bug page
Diffstat (limited to 'extensions/BMO/web')
-rw-r--r--extensions/BMO/web/js/new-bug-frequent-comp.js111
-rw-r--r--extensions/BMO/web/styles/choose_product.css19
2 files changed, 130 insertions, 0 deletions
diff --git a/extensions/BMO/web/js/new-bug-frequent-comp.js b/extensions/BMO/web/js/new-bug-frequent-comp.js
new file mode 100644
index 000000000..4ca1fcf89
--- /dev/null
+++ b/extensions/BMO/web/js/new-bug-frequent-comp.js
@@ -0,0 +1,111 @@
+/* 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. */
+
+/**
+ * Reference or define the Bugzilla app namespace.
+ * @namespace
+ */
+var Bugzilla = Bugzilla || {}; // eslint-disable-line no-var
+
+/**
+ * Show the current user's most-used components on the New Bug page.
+ */
+Bugzilla.NewBugFrequentComp = class NewBugFrequentComp {
+ /**
+ * Initialize a new NewBugFrequentComp instance.
+ */
+ constructor() {
+ this.$container = document.querySelector('#frequent-components');
+
+ if (this.$container && BUGZILLA.user.login) {
+ this.init();
+ }
+ }
+
+ /**
+ * Initialize the UI.
+ */
+ async init() {
+ this.$results = this.$container.querySelector('.results');
+ this.$message = this.$results.appendChild(document.createElement('p'));
+ this.$message.textContent = 'Loading...';
+ this.$results.setAttribute('aria-busy', 'true');
+ this.$container.hidden = false;
+
+ try {
+ const results = await this.fetch();
+
+ this.$message.remove();
+ this.$results.insertAdjacentHTML('beforeend',
+ `<ul>${results.map(({ product, component }) => (
+ `<li><a href="/enter_bug.cgi?product=${encodeURIComponent(product)}&amp;component=` +
+ `${encodeURIComponent(component)}">${product.htmlEncode()} :: ${component.htmlEncode()}</a></li>`
+ )).join('')}</ul>`
+ );
+ } catch (error) {
+ this.$message.textContent = error.message || 'Your frequent components could not be retrieved.';
+ }
+
+ this.$results.removeAttribute('aria-busy');
+ }
+
+ /**
+ * Retrieve frequently used components.
+ * @param {Number} [max=10] Maximum number of results.
+ * @returns {Promise} Results or error.
+ */
+ async fetch(max = 10) {
+ const params = new URLSearchParams({
+ email1: BUGZILLA.user.login,
+ emailreporter1: '1',
+ emailtype1: 'exact',
+ chfield: '[Bug creation]',
+ chfieldfrom: '-1y',
+ chfieldto: 'Now',
+ include_fields: 'product,component',
+ });
+
+ return new Promise((resolve, reject) => {
+ bugzilla_ajax({
+ url: `/rest/bug?${params.toString()}`
+ }, response => {
+ if (!response.bugs) {
+ reject(new Error('Your frequent components could not be retrieved.'));
+
+ return;
+ }
+
+ if (!response.bugs.length) {
+ reject(new Error(('Your frequent components could not be found.')));
+
+ return;
+ }
+
+ const results = [];
+
+ for (const { product, component } of response.bugs) {
+ const index = results.findIndex(result => product === result.product && component === result.component);
+
+ if (index > -1) {
+ results[index].count++;
+ } else {
+ results.push({ product, component, count: 1 });
+ }
+ }
+
+ // Sort in descending order
+ results.sort((a, b) => (a.count < b.count ? 1 : a.count > b.count ? -1 : 0));
+
+ resolve(results.slice(0, max));
+ }, () => {
+ reject(new Error('Your frequent components could not be retrieved.'));
+ });
+ });
+ }
+};
+
+window.addEventListener('DOMContentLoaded', () => new Bugzilla.NewBugFrequentComp(), { once: true });
diff --git a/extensions/BMO/web/styles/choose_product.css b/extensions/BMO/web/styles/choose_product.css
index 5fd8c49e7..a4ecf749f 100644
--- a/extensions/BMO/web/styles/choose_product.css
+++ b/extensions/BMO/web/styles/choose_product.css
@@ -16,6 +16,22 @@
text-align: left;
}
+#frequent-components ul {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ margin: 8px auto;
+ padding: 0;
+ list-style-type: none;
+ white-space: nowrap;
+}
+
+#frequent-components li {
+ flex: none;
+ margin: 8px 16px;
+ padding: 0;
+}
+
#product-list {
margin: 32px 0;
}
@@ -55,6 +71,7 @@
}
@media screen and (min-width: 1024px) {
+ #frequent-components ul,
#product-list .tile {
width: 960px;
}
@@ -65,6 +82,7 @@
}
@media screen and (min-width: 768px) and (max-width: 1023px) {
+ #frequent-components ul,
#product-list .tile {
width: 720px;
}
@@ -75,6 +93,7 @@
}
@media screen and (max-width: 767px) {
+ #frequent-components ul,
#product-list .tile {
width: auto;
max-width: 480px;