Skip to content

Commit

Permalink
Merge pull request #41 from Fgerthoffert/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
Fgerthoffert committed Sep 23, 2019
2 parents 9b216d4 + 4b1f5d2 commit e53393f
Show file tree
Hide file tree
Showing 15 changed files with 308 additions and 25 deletions.
1 change: 1 addition & 0 deletions api/src/roadmap/roadmap.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export class RoadmapService {

export const getTeamId = (teamName: string) => {
return String(teamName)
.replace('team-', '') // If team is prefixed by team-, we simply remove it from the string
.replace(/[^a-z0-9+]+/gi, '')
.toLowerCase();
};
Expand Down
1 change: 1 addition & 0 deletions api/src/velocity/velocity.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export class VelocityService {

export const getTeamId = (teamName: string) => {
return String(teamName)
.replace('team-', '') // If team is prefixed by team-, we simply remove it from the string
.replace(/[^a-z0-9+]+/gi, '')
.toLowerCase();
};
Expand Down
1 change: 1 addition & 0 deletions cli/src/utils/misc/teamUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/
export const getTeamId = (teamName: string) => {
return String(teamName)
.replace('team-', '') // If team is prefixed by team-, we simply remove it from the string
.replace(/[^a-z0-9+]+/gi, '')
.toLowerCase();
};
Expand Down
2 changes: 2 additions & 0 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@
"cytoscape": "^3.10.0",
"cytoscape-cose-bilkent": "^4.1.0",
"cytoscape-popper": "^1.0.4",
"date-fns": "^2.2.1",
"install": "^0.13.0",
"loglevel": "^1.6.3",
"material-color-hash": "^0.1.6",
"material-table": "^1.50.0",
"npm": "^6.11.3",
"react": "^16.9.0",
Expand Down
8 changes: 4 additions & 4 deletions ui/src/components/Charts/ChartJS/VelocityChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ class VelocityChart extends Component<any, any> {
if (this.chart.destroy !== undefined) {
this.chart.destroy();
}

this.chart = new Chart(myChartRef, {
type: 'bar',
data: {
Expand Down Expand Up @@ -88,9 +87,10 @@ class VelocityChart extends Component<any, any> {
const issues = dataset[idx].completion.list;
if (issues.length > 0 && this.allowClick === true) {
this.allowClick = false;
const keys = issues.map((i: any) => i.key);
const url =
issues[0].host + '/issues/?jql=key in (' + keys.toString() + ')';
// const keys = issues.map((i: any) => i.key);
// const url =
// issues[0].host + '/issues/?jql=key in (' + keys.toString() + ')';
const url = issues[0].host + '/issues/?jql=' + issues[0].jql;
window.open(url, '_blank');
setTimeout(() => {
this.resetAllowClick();
Expand Down
199 changes: 199 additions & 0 deletions ui/src/components/Charts/ChartJS/VelocityChartStacked.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
import React, { Component } from 'react'; // let's also import Component
import { Theme, createStyles, withStyles } from '@material-ui/core/styles';
import Chart from 'chart.js';
import toMaterialStyle from 'material-color-hash';

const styles = (theme: Theme) =>
createStyles({
root: {
// height: 400
}
});

class VelocityChartStacked extends Component<any, any> {
chartRef: any = React.createRef();
chart: any = {};
allowClick: boolean = true;

componentDidMount() {
this.buildChart();
}

componentDidUpdate() {
this.buildChart();
}

resetAllowClick = () => {
this.allowClick = true;
};

buildChart = () => {
const { dataset, defaultPoints } = this.props;
const myChartRef = this.chartRef.current.getContext('2d');
let metric = 'points';
if (!defaultPoints) {
metric = 'issues';
}

if (this.chart.destroy !== undefined) {
this.chart.destroy();
}

const days = [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday'
];
const weekDays = [];
// @ts-ignore
for (const [idx, day] of days.entries()) {
weekDays.push({
label: day,
// @ts-ignore
...toMaterialStyle('t', (idx + 1) * 100),
// backgroundColor: '#64b5f6',
// borderColor: '#64b5f6',
borderWidth: 2,
data: dataset.map(
(w: any) =>
w.weekDays.find((d: any) => d.weekdayTxt === day).completion[metric]
.count
)
});
}
this.chart = new Chart(myChartRef, {
type: 'bar',
data: {
datasets: [
{
label: 'Velocity (rolling average)',
data: dataset.map((w: any) => w.completion[metric].velocity),
backgroundColor: '#ef5350',
fill: false,
type: 'line'
},
...weekDays
],
labels: dataset.map((w: any) => w.legend)
},
options: {
onClick: this.clickChart,
scales: {
yAxes: [
{
ticks: {
beginAtZero: true
},
stacked: true
}
],
xAxes: [
{
stacked: true
}
]
},
tooltips: {
position: 'nearest',
mode: 'index',
intersect: false,
callbacks: {
label: (tooltipItem: any, data: any) => {
if (
tooltipItem.datasetIndex === 0 ||
parseInt(tooltipItem.value, 10) === 0
) {
return (
data.datasets[tooltipItem.datasetIndex].label +
': ' +
tooltipItem.value
);
}
const currentWeek = dataset.find(
(w: any) => w.weekTxt === tooltipItem.xLabel
);
const currentDay =
currentWeek.weekDays[tooltipItem.datasetIndex - 1];
return (
currentDay.weekdayTxt +
' (' +
currentDay.date.toJSON().slice(6, 10) +
'): ' +
tooltipItem.value
);
},
title: (tooltipItems: any, data: any) => {
// console.log(tooltipItems);
// console.log(data);
const currentWeek = dataset.find(
(w: any) => w.weekTxt === tooltipItems[0].xLabel
);
return (
currentWeek.weekTxt + ' week starting: ' + currentWeek.weekJira
);
}
}
}
}
});
};

// https://jsfiddle.net/u1szh96g/208/
clickChart = (event: any) => {
const { dataset } = this.props;
const activePoints = this.chart.getElementsAtEvent(event);
if (activePoints[0] !== undefined) {
const idx = activePoints[0]._index;
const issues = dataset[idx].completion.list;
if (issues.length > 0 && this.allowClick === true) {
this.allowClick = false;
const clickedWeek = dataset[idx];
let jqlString = '';
const activeWeeks = clickedWeek.weekDays.filter(
(d: any) => d.jql !== null
);
for (const [widx, day] of activeWeeks.entries()) {
jqlString = jqlString + ' (' + day.jql + ')';
if (widx < activeWeeks.length - 1) {
jqlString = jqlString + ' OR';
}
}
const url = issues[0].host + '/issues/?jql=' + jqlString;
window.open(url, '_blank');
setTimeout(() => {
this.resetAllowClick();
}, 1000);
}
// const issues = dataset[idx].completion.list;
// console.log(issues);
/*
if (issues.length > 0 && this.allowClick === true) {
this.allowClick = false;
const keys = issues.map((i: any) => i.key);
//const url =
// issues[0].host + '/issues/?jql=key in (' + keys.toString() + ')';
const url = issues[0].host + '/issues/?jql=' + issues[0].jql;
window.open(url, '_blank');
setTimeout(() => {
this.resetAllowClick();
}, 1000);
}
*/
}
};

render() {
const { classes } = this.props;
return (
<div className={classes.root}>
<canvas id='myChart' ref={this.chartRef} />
</div>
);
}
}

export default withStyles(styles)(VelocityChartStacked);
12 changes: 11 additions & 1 deletion ui/src/components/Charts/Nivo/RoadmapFutureChart.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import React, { Component } from 'react'; // let's also import Component
import { Theme, createStyles, withStyles } from '@material-ui/core/styles';
import { ResponsiveHeatMap } from '@nivo/heatmap';
import toMaterialStyle from 'material-color-hash';

import { getInitiativeTitle } from './utils';

const styles = (theme: Theme) =>
createStyles({
Expand Down Expand Up @@ -30,6 +33,13 @@ class RoadmapFutureChart extends Component<any, any> {
Display different background colors based on the percentage of the effort spent on a particular activity for a week
*/
getCompletionColor = (data: any, value: any) => {
const { roadmap } = this.props;
const initiative = roadmap.byFutureInitiative.find(
(i: any) => getInitiativeTitle(i) === data.yKey
);
if (initiative !== undefined) {
return toMaterialStyle(initiative.team.name, 200).backgroundColor;
}
return 'rgb(65, 171, 93)';
};

Expand All @@ -43,7 +53,7 @@ class RoadmapFutureChart extends Component<any, any> {
const dataset: IDatasetObj[] = [];
for (const initiative of roadmap.byFutureInitiative) {
const initiativeData: IDatasetObj = {
initiative: initiative.fields.summary + ' (' + initiative.key + ')'
initiative: getInitiativeTitle(initiative)
};
for (const week of initiative.weeks) {
initiativeData[week.weekTxt] = week[metric].count;
Expand Down
7 changes: 6 additions & 1 deletion ui/src/components/Charts/Nivo/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@ export const getCellDataInitiatives = (
};

export const getInitiativeTitle = (initiative: any) => {
return initiative.fields.summary + ' (' + initiative.key + ')';
const maxTitleLength = 30;
const initiativeTitle =
initiative.fields.summary.length > maxTitleLength
? initiative.fields.summary.slice(0, maxTitleLength) + '...'
: initiative.fields.summary;
return initiativeTitle + ' (' + initiative.key + ')';
};

export const getNonInitiativeTitle = () => {
Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/Header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ const Header: FC<connectedProps> = ({ setShowMenu, showMenu, pageTitle }) => {
{pageTitle}
</Typography>
<SwitchPoints />
{window._env_.AUTH0_DISABLED !== true && <Login />}
{JSON.parse(window._env_.AUTH0_DISABLED) !== true && <Login />}
</Toolbar>
</AppBar>
);
Expand Down
2 changes: 1 addition & 1 deletion ui/src/layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export default function Layout(props: LayoutProps) {
<div className={classes.root}>
<CssBaseline />
<Header />
{window._env_.AUTH0_DISABLED !== true && <LoginDialog />}
{JSON.parse(window._env_.AUTH0_DISABLED) !== true && <LoginDialog />}
<Menu />
<main
className={clsx(classes.content, {
Expand Down
15 changes: 8 additions & 7 deletions ui/src/models/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,14 @@ export const global = createModel({
},

async initAuth() {
log.info('User not logged in, initilizing authentication');

if (window.Auth0 !== undefined) {
this.setAuth0Initialized(true);
} else {
await setAuth0Config();
this.setAuth0Initialized(true);
if (JSON.parse(window._env_.AUTH0_DISABLED) !== true) {
log.info('User not logged in, initializing authentication');
if (window.Auth0 !== undefined) {
this.setAuth0Initialized(true);
} else {
await setAuth0Config();
this.setAuth0Initialized(true);
}
}
},

Expand Down
11 changes: 8 additions & 3 deletions ui/src/models/roadmap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,17 @@ export const roadmap = createModel({
const setLoading = this.setLoading;

if (
Object.values(rootState.roadmap.roadmap).length === 0 &&
rootState.global.accessToken !== ''
JSON.parse(window._env_.AUTH0_DISABLED) === true ||
(JSON.parse(window._env_.AUTH0_DISABLED) !== true &&
rootState.global.accessToken !== '')
) {
setLoading(true);
const host =
window._env_.API_URL !== undefined
? window._env_.API_URL
: 'http://127.0.0.1:3001';
const headers =
window._env_.AUTH0_DISABLED !== true
JSON.parse(window._env_.AUTH0_DISABLED) !== true
? { Authorization: `Bearer ${rootState.global.accessToken}` }
: {};
axios({
Expand All @@ -123,6 +124,10 @@ export const roadmap = createModel({
setRoadmap({});
setLoading(false);
});
} else {
log.info(
'Not loading data, either there is already some data in cache or user token not present'
);
}
},
async updateGraph(payload, rootState) {
Expand Down
7 changes: 4 additions & 3 deletions ui/src/models/velocity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ export const velocity = createModel({
const setSelectedTeam = this.setSelectedTeam;

if (
rootState.velocity.teams.length === 0 &&
rootState.global.accessToken !== ''
JSON.parse(window._env_.AUTH0_DISABLED) === true ||
(JSON.parse(window._env_.AUTH0_DISABLED) !== true &&
rootState.global.accessToken !== '')
) {
log.info('Loading data');

Expand All @@ -45,7 +46,7 @@ export const velocity = createModel({
? window._env_.API_URL
: 'http://127.0.0.1:3001';
const headers =
window._env_.AUTH0_DISABLED !== true
JSON.parse(window._env_.AUTH0_DISABLED) !== true
? { Authorization: `Bearer ${rootState.global.accessToken}` }
: {};
axios({
Expand Down
Loading

0 comments on commit e53393f

Please sign in to comment.