aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>2017-06-23 11:45:49 +0200
committerGrégoire Aubert <gregoire.aubert@sonarsource.com>2017-07-04 14:15:34 +0200
commitd55ab331ed66b29cfd99c0a41f94c4ddf521f4ca (patch)
treebb561751117453751b27af781dece5661da143b1 /server
parentb41d68b7105b3d9704319183dcb7e573e6dd1386 (diff)
downloadsonarqube-d55ab331ed66b29cfd99c0a41f94c4ddf521f4ca.tar.gz
sonarqube-d55ab331ed66b29cfd99c0a41f94c4ddf521f4ca.zip
SONAR-8550 Group analyses by version in the project activity list
Diffstat (limited to 'server')
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysesList.js65
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysis.js2
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityApp.js4
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/forms/AddEventForm.js2
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/projectActivity.css4
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/utils.js27
-rw-r--r--server/sonar-web/src/main/less/init/forms.less4
7 files changed, 72 insertions, 36 deletions
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysesList.js b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysesList.js
index 5242772fef8..e6dd14181e0 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysesList.js
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysesList.js
@@ -19,11 +19,11 @@
*/
// @flow
import React from 'react';
-import { groupBy } from 'lodash';
import moment from 'moment';
import ProjectActivityAnalysis from './ProjectActivityAnalysis';
import FormattedDate from '../../../components/ui/FormattedDate';
import { translate } from '../../../helpers/l10n';
+import { getAnalysesByVersionByDay } from '../utils';
import type { Analysis } from '../types';
type Props = {
@@ -50,35 +50,44 @@ export default function ProjectActivityAnalysesList(props: Props) {
);
}
- const firstAnalysis = props.analyses[0];
- const byDay = groupBy(props.analyses, analysis => moment(analysis.date).startOf('day').valueOf());
+ const firstAnalysisKey = props.analyses[0].key;
+ const byVersionByDay = getAnalysesByVersionByDay(props.analyses);
return (
<div className={props.className}>
- <ul className="project-activity-days-list">
- {Object.keys(byDay).map(day => (
- <li
- key={day}
- className="project-activity-day"
- data-day={moment(Number(day)).format('YYYY-MM-DD')}>
- <div className="project-activity-date">
- <FormattedDate date={Number(day)} format="LL" />
- </div>
-
- <ul className="project-activity-analyses-list">
- {byDay[day] != null &&
- byDay[day].map(analysis => (
- <ProjectActivityAnalysis
- addCustomEvent={props.addCustomEvent}
- addVersion={props.addVersion}
- analysis={analysis}
- canAdmin={props.canAdmin}
- changeEvent={props.changeEvent}
- deleteAnalysis={props.deleteAnalysis}
- deleteEvent={props.deleteEvent}
- isFirst={analysis === firstAnalysis}
- key={analysis.key}
- />
- ))}
+ <ul className="project-activity-versions-list">
+ {byVersionByDay.map((version, idx) => (
+ <li key={idx + version.version}>
+ {version.version &&
+ <span className="badge project-activity-version-badge spacer-top big-spacer-bottom">
+ {version.version}
+ </span>}
+ <ul className="project-activity-days-list">
+ {Object.keys(version.byDay).map(day => (
+ <li
+ key={day}
+ className="project-activity-day"
+ data-day={moment(Number(day)).format('YYYY-MM-DD')}>
+ <div className="project-activity-date">
+ <FormattedDate date={Number(day)} format="LL" />
+ </div>
+ <ul className="project-activity-analyses-list">
+ {version.byDay[day] != null &&
+ version.byDay[day].map(analysis => (
+ <ProjectActivityAnalysis
+ addCustomEvent={props.addCustomEvent}
+ addVersion={props.addVersion}
+ analysis={analysis}
+ canAdmin={props.canAdmin}
+ changeEvent={props.changeEvent}
+ deleteAnalysis={props.deleteAnalysis}
+ deleteEvent={props.deleteEvent}
+ isFirst={analysis.key === firstAnalysisKey}
+ key={analysis.key}
+ />
+ ))}
+ </ul>
+ </li>
+ ))}
</ul>
</li>
))}
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysis.js b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysis.js
index 870dfd61c6a..406f963f0a3 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysis.js
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysis.js
@@ -57,7 +57,7 @@ export default function ProjectActivityAnalysis(props: Props) {
<div className="project-activity-analysis-actions spacer-left">
<div className="dropdown display-inline-block">
<button
- className="js-analysis-actions button-small dropdown-toggle"
+ className="js-analysis-actions button-small button-compact dropdown-toggle"
data-toggle="dropdown">
<i className="icon-settings" />
{' '}
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityApp.js b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityApp.js
index 5419cf50e10..1904f8d975d 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityApp.js
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityApp.js
@@ -63,9 +63,7 @@ export default class ProjectActivityApp extends React.PureComponent {
nextProps.analyses !== this.props.analyses ||
activityQueryChanged(this.props.query, nextProps.query)
) {
- this.setState({
- filteredAnalyses: this.filterAnalyses(nextProps.analyses, nextProps.query)
- });
+ this.setState({ filteredAnalyses: this.filterAnalyses(nextProps.analyses, nextProps.query) });
}
}
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/forms/AddEventForm.js b/server/sonar-web/src/main/js/apps/projectActivity/components/forms/AddEventForm.js
index d83b4244d6a..92c4436f20d 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/forms/AddEventForm.js
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/forms/AddEventForm.js
@@ -136,7 +136,7 @@ export default class AddEventForm extends React.PureComponent {
render() {
return (
- <a className="js-add-event button-small" href="#" onClick={this.openForm}>
+ <a className="js-add-event" href="#" onClick={this.openForm}>
{translate(this.props.addEventButtonText)}
{this.state.open && this.renderModal()}
</a>
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/projectActivity.css b/server/sonar-web/src/main/js/apps/projectActivity/components/projectActivity.css
index 6754b5dfa12..e27947e03aa 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/projectActivity.css
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/projectActivity.css
@@ -46,7 +46,6 @@
.project-activity-graph {
flex: 1;
- max-height: 500px;
}
.project-activity-graph-legends {
@@ -171,7 +170,8 @@
.project-activity-version-badge {
vertical-align: middle;
- padding: 4px 8px;
+ padding: 4px 14px 4px 16px;
+ margin-left: -14px;
border-radius: 2px;
font-weight: bold;
font-size: 12px;
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/utils.js b/server/sonar-web/src/main/js/apps/projectActivity/utils.js
index 616633b0a25..4375069aad9 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/utils.js
+++ b/server/sonar-web/src/main/js/apps/projectActivity/utils.js
@@ -18,6 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
// @flow
+import moment from 'moment';
import {
cleanQuery,
parseAsDate,
@@ -26,7 +27,7 @@ import {
serializeString
} from '../../helpers/query';
import { translate } from '../../helpers/l10n';
-import type { MeasureHistory, Query } from './types';
+import type { Analysis, MeasureHistory, Query } from './types';
import type { RawQuery } from '../../helpers/query';
export const EVENT_TYPES = ['VERSION', 'QUALITY_GATE', 'QUALITY_PROFILE', 'OTHER'];
@@ -68,6 +69,30 @@ export const generateCoveredLinesMetric = (
};
};
+export const getAnalysesByVersionByDay = (
+ analyses: Array<Analysis>
+): Array<{
+ version: ?string,
+ byDay: { [string]: Array<Analysis> }
+}> =>
+ analyses.reduce((acc, analysis) => {
+ if (acc.length === 0) {
+ acc.push({ version: undefined, byDay: {} });
+ }
+ const currentVersion = acc[acc.length - 1];
+ const day = moment(analysis.date).startOf('day').valueOf().toString();
+ if (!currentVersion.byDay[day]) {
+ currentVersion.byDay[day] = [];
+ }
+ currentVersion.byDay[day].push(analysis);
+ const versionEvent = analysis.events.find(event => event.category === 'VERSION');
+ if (versionEvent) {
+ currentVersion.version = versionEvent.name;
+ acc.push({ version: undefined, byDay: {} });
+ }
+ return acc;
+ }, []);
+
const parseGraph = (value?: string): string => {
const graph = parseAsString(value);
return GRAPH_TYPES.includes(graph) ? graph : 'overview';
diff --git a/server/sonar-web/src/main/less/init/forms.less b/server/sonar-web/src/main/less/init/forms.less
index 6ef2319bae8..e01aeddf952 100644
--- a/server/sonar-web/src/main/less/init/forms.less
+++ b/server/sonar-web/src/main/less/init/forms.less
@@ -237,6 +237,10 @@ input[type="submit"].button-grey {
}
}
+.button-compact {
+ padding: 0 6px;
+}
+
.button-group {
display: inline-block;
vertical-align: middle;