From c61987f7ad25057e1a643dc94513afc1360978d6 Mon Sep 17 00:00:00 2001 From: Michael Kurz Date: Fri, 22 Apr 2022 20:09:36 +0200 Subject: [PATCH] #38: add possibility to restrict currently viewed branch --- .../visualizations/team-awareness/config.js | 34 +++++++++++++++---- .../team-awareness/reducers/config.js | 4 ++- .../team-awareness/reducers/data.js | 2 ++ .../team-awareness/sagas/calculateFigures.js | 25 ++++++++++++-- .../team-awareness/sagas/getBranches.js | 27 +++++++++++++++ .../team-awareness/sagas/getCommits.js | 1 + .../team-awareness/sagas/index.js | 21 ++++++++---- .../visualizations/team-awareness/styles.scss | 4 +++ 8 files changed, 101 insertions(+), 17 deletions(-) create mode 100644 ui/src/visualizations/team-awareness/sagas/getBranches.js diff --git a/ui/src/visualizations/team-awareness/config.js b/ui/src/visualizations/team-awareness/config.js index 3b9c4db7..18ca680d 100644 --- a/ui/src/visualizations/team-awareness/config.js +++ b/ui/src/visualizations/team-awareness/config.js @@ -2,7 +2,7 @@ import React from 'react'; import { connect } from 'react-redux'; -import { setActivityDimensions, setActivityScale } from './sagas'; +import { setActivityDimensions, setActivityScale, setBranch } from './sagas'; import * as d3 from 'd3'; import { getState } from './util/util'; import _ from 'lodash'; @@ -13,9 +13,11 @@ const mapStateToProps = (appState /*, ownProps*/) => { const { config, data } = getState(appState); return { config: { - selectedActivity: config.selectedActivity + selectedActivityScale: config.selectedActivityScale, + selectedBranch: config.selectedBranch }, data: { + branches: data.data.branches, activityTimeline: data.data.activityTimeline, yDims: data.data.dataBoundaries } @@ -24,7 +26,8 @@ const mapStateToProps = (appState /*, ownProps*/) => { const mapDispatchToProps = dispatch => { return { onSelectActivityScale: selectActivity => dispatch(setActivityScale(selectActivity)), - onActivityDimensionsRestricted: restrictActivity => dispatch(setActivityDimensions(restrictActivity)) + onActivityDimensionsRestricted: restrictActivity => dispatch(setActivityDimensions(restrictActivity)), + onSelectBranch: selectActivity => dispatch(setBranch(selectActivity)) }; }; @@ -34,8 +37,9 @@ class ConfigComponent extends React.Component { } render() { - const { onActivityDimensionsRestricted, onSelectActivityScale, config } = this.props; - const { activityTimeline, yDims } = this.props.data; + const { onActivityDimensionsRestricted, onSelectActivityScale, config, onSelectBranch } = this.props; + const { activityTimeline, yDims, branches } = this.props.data; + console.log(activityTimeline); return (
@@ -55,15 +59,31 @@ class ConfigComponent extends React.Component {
+
+ +
+ +
+
0 ? activityTimeline : [{ date: 0, activity: 0 }]} d3offset={d3.stackOffsetDiverging} yDims={_.values(yDims)} onDimensionsRestricted={dims => onActivityDimensionsRestricted(dims)} diff --git a/ui/src/visualizations/team-awareness/reducers/config.js b/ui/src/visualizations/team-awareness/reducers/config.js index 30624450..ff953aeb 100644 --- a/ui/src/visualizations/team-awareness/reducers/config.js +++ b/ui/src/visualizations/team-awareness/reducers/config.js @@ -6,9 +6,11 @@ import _ from 'lodash'; export default handleActions( { SET_TEAM_AWARENESS_ACTIVITY_SCALE: (state, action) => _.assign({}, state, { selectedActivityScale: action.payload }), - SET_TEAM_AWARENESS_ACTIVITY_DIMENSIONS: (state, action) => _.assign({}, state, action.payload) + SET_TEAM_AWARENESS_ACTIVITY_DIMENSIONS: (state, action) => _.assign({}, state, action.payload), + SET_TEAM_AWARENESS_BRANCH: (state, action) => _.assign({}, state, { selectedBranch: action.payload }) }, { + selectedBranch: 'all', selectedActivityScale: 'commits', activityRestricted: false, activityDims: [] diff --git a/ui/src/visualizations/team-awareness/reducers/data.js b/ui/src/visualizations/team-awareness/reducers/data.js index 49629b8f..3df4a6d6 100644 --- a/ui/src/visualizations/team-awareness/reducers/data.js +++ b/ui/src/visualizations/team-awareness/reducers/data.js @@ -19,6 +19,7 @@ export default handleActions( PROCESS_TEAM_AWARENESS_DATA: (state, action) => { return _.assign({}, state, { data: { + branches: state.data.branches, commits: state.data.commits, stakeholders: action.payload.stakeholders, activityTimeline: action.payload.activityTimeline, @@ -29,6 +30,7 @@ export default handleActions( }, { data: { + branches: [], commits: [], stakeholders: [] }, diff --git a/ui/src/visualizations/team-awareness/sagas/calculateFigures.js b/ui/src/visualizations/team-awareness/sagas/calculateFigures.js index 0417b186..815083c5 100644 --- a/ui/src/visualizations/team-awareness/sagas/calculateFigures.js +++ b/ui/src/visualizations/team-awareness/sagas/calculateFigures.js @@ -17,15 +17,20 @@ function processData(appState) { const activities = new Map(); const dataBoundaries = { - min: Number.MAX_SAFE_INTEGER, + min: 0, max: Number.MIN_SAFE_INTEGER }; let activityCalculator = selectCalculationFunction(vizState.config); + console.log(vizState.data.data); if (vizState.config.activityRestricted === true) { const from = Date.parse(vizState.config.activityDims[0]); const to = Date.parse(vizState.config.activityDims[1]); - activityCalculator = filterCommit(from, to, activityCalculator); + activityCalculator = filterCommitOnDate(from, to, activityCalculator); + } + + if (vizState.config.selectedBranch && vizState.config.selectedBranch !== 'all') { + activityCalculator = filterCommitOnBranch(vizState.config.selectedBranch, activityCalculator); } vizState.data.data.commits.forEach(c => { @@ -80,7 +85,7 @@ function updateBoundaries(boundaries, value) { * @param fn {function} * @return {function(*): number} */ -function filterCommit(from, to, fn) { +function filterCommitOnDate(from, to, fn) { return commit => { const parsedDate = Date.parse(commit.date); if (from <= parsedDate && parsedDate <= to) { @@ -90,6 +95,20 @@ function filterCommit(from, to, fn) { }; } +/** + * @param selectedBranch {string} + * @param fn {function} + * @return {function(*): number} + */ +function filterCommitOnBranch(selectedBranch, fn) { + return commit => { + if (commit.branch === selectedBranch) { + return fn(commit); + } + return 0; + }; +} + function selectCalculationFunction(config) { const { selectedActivityScale } = config; if (!selectedActivityScale) { diff --git a/ui/src/visualizations/team-awareness/sagas/getBranches.js b/ui/src/visualizations/team-awareness/sagas/getBranches.js new file mode 100644 index 00000000..32e875cd --- /dev/null +++ b/ui/src/visualizations/team-awareness/sagas/getBranches.js @@ -0,0 +1,27 @@ +import { graphQl, traversePages } from '../../../utils'; + +/** + * Fetches branch data via GraphQL API from the data source. + */ +export default () => { + const buildList = []; + return traversePages(getBranches, build => buildList.push(build)).then(() => buildList); +}; + +const getBranches = (page, perPage) => { + return graphQl + .query( + ` + query($page:Int, $perPage:Int) { + branches(sort: "ASC", page:$page, perPage:$perPage) { + data { + id + branch + } + } + }`, + page, + perPage + ) + .then(result => result.branches); +}; diff --git a/ui/src/visualizations/team-awareness/sagas/getCommits.js b/ui/src/visualizations/team-awareness/sagas/getCommits.js index f82487bf..e075d1e8 100644 --- a/ui/src/visualizations/team-awareness/sagas/getCommits.js +++ b/ui/src/visualizations/team-awareness/sagas/getCommits.js @@ -16,6 +16,7 @@ const getCommits = (page, perPage) => { commits(page:$page, perPage:$perPage) { data { date + branch stakeholder { id gitSignature diff --git a/ui/src/visualizations/team-awareness/sagas/index.js b/ui/src/visualizations/team-awareness/sagas/index.js index 4354ca0e..1b621692 100644 --- a/ui/src/visualizations/team-awareness/sagas/index.js +++ b/ui/src/visualizations/team-awareness/sagas/index.js @@ -4,10 +4,12 @@ import { createAction } from 'redux-actions'; import { fork, takeEvery, throttle } from 'redux-saga/effects'; import { fetchFactory, mapSaga, timestampedActionFactory } from '../../../sagas/utils'; import getCommits from './getCommits'; -import test from './calculateFigures'; +import recalculate from './calculateFigures'; +import getBranches from './getBranches'; export const setActivityScale = createAction('SET_TEAM_AWARENESS_ACTIVITY_SCALE'); export const setActivityDimensions = createAction('SET_TEAM_AWARENESS_ACTIVITY_DIMENSIONS'); +export const setBranch = createAction('SET_TEAM_AWARENESS_BRANCH'); export const processTeamAwarenessData = timestampedActionFactory('PROCESS_TEAM_AWARENESS_DATA'); export const requestTeamAwarenessData = createAction('REQUEST_TEAM_AWARENESS_DATA'); @@ -20,6 +22,7 @@ const refresh = createAction('REFRESH'); export default function*() { yield fork(watchDataReceive); yield fork(watchActivityScaleSet); + yield fork(watchBranchSet); yield fork(watchActivityDimensionsSet); yield fork(watchRefreshRequests); yield fork(watchMessages); @@ -29,15 +32,19 @@ export default function*() { } function* watchDataReceive() { - yield takeEvery('RECEIVE_TEAM_AWARENESS_DATA', test); + yield takeEvery('RECEIVE_TEAM_AWARENESS_DATA', recalculate); } function* watchActivityScaleSet() { - yield takeEvery('SET_TEAM_AWARENESS_ACTIVITY_SCALE', test); + yield takeEvery('SET_TEAM_AWARENESS_ACTIVITY_SCALE', recalculate); +} + +function* watchBranchSet() { + yield takeEvery('SET_TEAM_AWARENESS_BRANCH', recalculate); } function* watchActivityDimensionsSet() { - yield takeEvery('SET_TEAM_AWARENESS_ACTIVITY_DIMENSIONS', test); + yield takeEvery('SET_TEAM_AWARENESS_ACTIVITY_DIMENSIONS', recalculate); } function* watchRefreshRequests() { @@ -55,9 +62,11 @@ function* watchMessages() { export const fetchAwarenessData = fetchFactory( function*() { //const state = getState(yield select()); - return yield Promise.all([getCommits()]).then(result => { + return yield Promise.all([getCommits(), getBranches()]).then(result => { + console.log(result); return { - commits: result[0] + commits: result[0], + branches: result[1] }; }); }, diff --git a/ui/src/visualizations/team-awareness/styles.scss b/ui/src/visualizations/team-awareness/styles.scss index 2dff22a3..220d2988 100644 --- a/ui/src/visualizations/team-awareness/styles.scss +++ b/ui/src/visualizations/team-awareness/styles.scss @@ -11,3 +11,7 @@ .activitySelect { width:100%; } + +.branchesSelect { + width:100%; +}