Show count of untriaged bugs for each component
This commit is contained in:
Родитель
873aa56dbe
Коммит
5931f54246
|
@ -27,6 +27,7 @@
|
|||
"@material-ui/icons": "^3.0.1",
|
||||
"@mozilla-frontend-infra/components": "^2.0.0",
|
||||
"prop-types": "^15",
|
||||
"query-string": "^6.2.0",
|
||||
"react": "^16",
|
||||
"react-dom": "^16",
|
||||
"react-hot-loader": "^4",
|
||||
|
|
|
@ -2,7 +2,8 @@ import React from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
import OpenInNew from '@material-ui/icons/OpenInNew';
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import getBugzillaComponentLink from '../../utils/getBugzillaComponentLink';
|
||||
import getLinkToComponent from '../../utils/bugzilla/getLinkToComponent';
|
||||
import getUntriagedBugsCount from '../../utils/bugzilla/getUntriagedBugsCount';
|
||||
|
||||
const styles = theme => ({
|
||||
root: {
|
||||
|
@ -11,22 +12,48 @@ const styles = theme => ({
|
|||
icon: {
|
||||
margin: 0,
|
||||
fontSize: '1rem',
|
||||
verticalAlign: 'text-top',
|
||||
},
|
||||
});
|
||||
|
||||
const BugzillaComponentSummary = ({ classes, product, component }) => (
|
||||
<div className={classes.root}>
|
||||
<span>{`${product}::${component}`}</span>
|
||||
<a href={getBugzillaComponentLink(product, component)} target="_blank" rel="noopener noreferrer">
|
||||
<OpenInNew className={classes.icon} />
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
class BugzillaComponentSummary extends React.Component {
|
||||
state = {
|
||||
untriaged: undefined,
|
||||
};
|
||||
|
||||
BugzillaComponentSummary.propTypes = {
|
||||
classes: PropTypes.shape({}).isRequired,
|
||||
product: PropTypes.string.isRequired,
|
||||
component: PropTypes.string.isRequired,
|
||||
};
|
||||
static propTypes = {
|
||||
classes: PropTypes.shape({}).isRequired,
|
||||
product: PropTypes.string.isRequired,
|
||||
component: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
async componentDidMount() {
|
||||
this.fetchData(this.props);
|
||||
}
|
||||
|
||||
async fetchData({ product, component }) {
|
||||
const untriaged = await getUntriagedBugsCount(product, component);
|
||||
this.setState({ untriaged });
|
||||
}
|
||||
|
||||
render() {
|
||||
const { classes, product, component } = this.props;
|
||||
const { untriaged } = this.state;
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<span>{`${product}::${component}`}</span>
|
||||
<a
|
||||
href={getLinkToComponent(product, component)}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
title="Link to component's untriaged bugs"
|
||||
>
|
||||
<OpenInNew className={classes.icon} />
|
||||
</a>
|
||||
{!!untriaged && <span title="Number of untriaged bugs">{untriaged}</span>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withStyles(styles)(BugzillaComponentSummary);
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
import { stringify } from 'query-string';
|
||||
import settings from './settings';
|
||||
import untriagedParameters from './untriagedParameters';
|
||||
|
||||
const getBugzillaComponentLink = (product, component) => (
|
||||
`${settings.BZ_HOST}/buglist.cgi?${stringify({ product, component, ...untriagedParameters() })}`);
|
||||
|
||||
export default getBugzillaComponentLink;
|
|
@ -0,0 +1,23 @@
|
|||
import { stringify } from 'query-string';
|
||||
import untriagedParameters from './untriagedParameters';
|
||||
import fetchJson from '../fetchJson';
|
||||
import settings from './settings';
|
||||
|
||||
const queryBugzilla = async queryParameters => (
|
||||
fetchJson(`${settings.BZ_HOST}/rest/bug?${queryParameters}`));
|
||||
|
||||
const getUntriagedBugsCount = async (product, component) => {
|
||||
// eslint-disable-next-line camelcase
|
||||
const { bug_count = 0 } = await queryBugzilla(
|
||||
stringify({
|
||||
product,
|
||||
component,
|
||||
...untriagedParameters(),
|
||||
count_only: 1, // This only returns the bug count
|
||||
}),
|
||||
);
|
||||
// eslint-disable-next-line camelcase
|
||||
return bug_count;
|
||||
};
|
||||
|
||||
export default getUntriagedBugsCount;
|
|
@ -0,0 +1,5 @@
|
|||
const settings = {
|
||||
BZ_HOST: 'https://bugzilla.mozilla.org',
|
||||
};
|
||||
|
||||
export default settings;
|
|
@ -0,0 +1,11 @@
|
|||
/* eslint-disable indent */
|
||||
/* eslint-disable object-property-newline */
|
||||
/* eslint-disable no-multi-spaces */
|
||||
const untriagedParameters = () => ({
|
||||
f1: 'bug_severity', o1: 'notequals', v1: 'enhancement',
|
||||
f2: 'keywords', o2: 'notsubstring', v2: 'meta',
|
||||
f3: 'resolution', o3: 'isempty',
|
||||
limit: 0,
|
||||
});
|
||||
|
||||
export default untriagedParameters;
|
|
@ -0,0 +1,13 @@
|
|||
const jsonHeaders = {
|
||||
Accept: 'application/json',
|
||||
};
|
||||
|
||||
const fetchJson = async (url) => {
|
||||
const response = await fetch(url, jsonHeaders);
|
||||
if (!response) {
|
||||
return null;
|
||||
}
|
||||
return response.json();
|
||||
};
|
||||
|
||||
export default fetchJson;
|
|
@ -1,7 +0,0 @@
|
|||
const getBugzillaComponentLink = (product, component) => (
|
||||
'https://bugzilla.mozilla.org/buglist.cgi?f1=bug_severity&o1=notequals&v1=enhancement'
|
||||
+ `&f2=keywords&o2=notsubstring&v2=meta&f3=product&o3=equals&v3=${product}&f4=component`
|
||||
+ `&o4=equals&v4=${component}&f5=resolution&o5=isempty&limit=0`
|
||||
);
|
||||
|
||||
export default getBugzillaComponentLink;
|
|
@ -1,8 +0,0 @@
|
|||
const getBugzillaComponents = async () => {
|
||||
const { products } = await (await fetch('https://bugzilla.mozilla.org/rest/product'
|
||||
+ '?type=accessible&include_fields=name&include_fields=components'
|
||||
+ '&exclude_fields=components.flag_types&exclude_fields=components.description')).json();
|
||||
return products;
|
||||
};
|
||||
|
||||
export default getBugzillaComponents;
|
13
yarn.lock
13
yarn.lock
|
@ -6939,6 +6939,14 @@ qs@6.5.2, qs@~6.5.2:
|
|||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
|
||||
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
|
||||
|
||||
query-string@^6.2.0:
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.2.0.tgz#468edeb542b7e0538f9f9b1aeb26f034f19c86e1"
|
||||
integrity sha512-5wupExkIt8RYL4h/FE+WTg3JHk62e6fFPWtAZA9J5IWK1PfTfKkMS93HBUHcFpeYi9KsY5pFbh+ldvEyaz5MyA==
|
||||
dependencies:
|
||||
decode-uri-component "^0.2.0"
|
||||
strict-uri-encode "^2.0.0"
|
||||
|
||||
querystring-es3@^0.2.0:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
|
||||
|
@ -8041,6 +8049,11 @@ stream-shift@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952"
|
||||
integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=
|
||||
|
||||
strict-uri-encode@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546"
|
||||
integrity sha1-ucczDHBChi9rFC3CdLvMWGbONUY=
|
||||
|
||||
string-argv@^0.0.2:
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.0.2.tgz#dac30408690c21f3c3630a3ff3a05877bdcbd736"
|
||||
|
|
Загрузка…
Ссылка в новой задаче