diff options
author | Grégoire Aubert <gregoire.aubert@sonarsource.com> | 2017-06-23 11:45:49 +0200 |
---|---|---|
committer | Grégoire Aubert <gregoire.aubert@sonarsource.com> | 2017-07-04 14:15:34 +0200 |
commit | d55ab331ed66b29cfd99c0a41f94c4ddf521f4ca (patch) | |
tree | bb561751117453751b27af781dece5661da143b1 /server | |
parent | b41d68b7105b3d9704319183dcb7e573e6dd1386 (diff) | |
download | sonarqube-d55ab331ed66b29cfd99c0a41f94c4ddf521f4ca.tar.gz sonarqube-d55ab331ed66b29cfd99c0a41f94c4ddf521f4ca.zip |
SONAR-8550 Group analyses by version in the project activity list
Diffstat (limited to 'server')
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; |