forked from holmari/gerritstats
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rewrite the UI with modern Javascript (React / ES2015)
This rewrite is done in order to modernize the frontend of the tool's HTML output. It uses all the cool things like webpack, React, Babel, immutable and many other JS libs to nicely encapsulate and give structure to the UI. This also eases some parts of the UI development: simply running `npm run webpack-watch` after building the data files automatically recompiles the .jsx to .js, leaning itself to a pretty fast development experience. This does not require a node server to display the HTML output. This huge commit also fixes some bugs, like not showing the right amount of approvals per user, and improves the UI for the overview page by moving the team graph to its own widget at the bottom of the page, instead of overlaying it on top of the table.
- Loading branch information
Showing
93 changed files
with
4,941 additions
and
2,954 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
{ | ||
"presets": ["es2015"] | ||
"presets": ["es2015", "react"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import React from 'react'; | ||
|
||
export default class ClearFloat extends React.Component { | ||
constructor(props) { | ||
super(props); | ||
} | ||
|
||
render() { | ||
const clearStyle = { | ||
clear: 'both' | ||
}; | ||
return ( | ||
<div style={clearStyle}></div> | ||
); | ||
} | ||
} | ||
|
||
ClearFloat.displayName = 'ClearFloat'; |
79 changes: 79 additions & 0 deletions
79
GerritStats/src/main/frontend/common/GerritVersionAlerts.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import React from 'react'; | ||
|
||
import {Alert} from 'react-bootstrap'; | ||
|
||
// show this alert just once for the whole app; it'll come back on refresh. | ||
var alertShown = false; | ||
|
||
export default class GerritVersionAlerts extends React.Component { | ||
|
||
constructor(props) { | ||
super(props); | ||
this.state = { | ||
alertVisible: !this.isGerritVersionAtLeast(2, 9) && !alertShown | ||
}; | ||
} | ||
|
||
isGerritVersionAtLeast(major, minor) { | ||
var gerritVersion = this.props.datasetOverview['gerritVersion'] || {}; | ||
return gerritVersion['major'] >= major | ||
&& gerritVersion['minor'] >= minor; | ||
} | ||
|
||
isGerritVersionUnknown() { | ||
var gerritVersion = this.props.datasetOverview['gerritVersion'] || {}; | ||
return gerritVersion['major'] === -1 | ||
&& gerritVersion['minor'] === -1 | ||
&& gerritVersion['patch'] === -1; | ||
} | ||
|
||
getPrintableGerritVersion() { | ||
var gerritVersion = this.props.datasetOverview['gerritVersion'] || {}; | ||
return gerritVersion['major'] + '.' | ||
+ gerritVersion['minor'] + '.' | ||
+ gerritVersion['patch']; | ||
} | ||
|
||
handleAlertDismiss(event) { | ||
alertShown = true; | ||
this.setState({ | ||
alertVisible: false | ||
}); | ||
} | ||
|
||
render() { | ||
if (!this.state.alertVisible) { | ||
return null; | ||
} | ||
|
||
if (this.isGerritVersionUnknown()) { | ||
return ( | ||
<Alert bsStyle="warning" onDismiss={this.handleAlertDismiss.bind(this)}> | ||
<strong>Unknown Gerrit version warning</strong>: | ||
Some or all of this data has been generated with data from an unknown Gerrit version. | ||
Some data is not included in the sources. | ||
Rerun GerritDownloader and GerritStats to get rid of this message. | ||
</Alert> | ||
); | ||
} else if (!this.isGerritVersionAtLeast(2, 9)) { | ||
const gerritVersion = this.getPrintableGerritVersion(); | ||
return ( | ||
<Alert bsStyle="warning" onDismiss={this.handleAlertDismiss.bind(this)}> | ||
<strong>Old Gerrit version warning</strong>: | ||
Some or all of this data has been generated with data from an old Gerrit version ({gerritVersion}). | ||
Versions prior to 2.9 do not provide enough information on who was added as a reviewer, | ||
so much of the data will be incorrect. | ||
Update Gerrit to get better statistics! | ||
</Alert> | ||
); | ||
} else { | ||
return null; | ||
} | ||
} | ||
} | ||
|
||
GerritVersionAlerts.displayName = 'GerritVersionAlerts'; | ||
|
||
GerritVersionAlerts.defaultProps = { | ||
datasetOverview: {} | ||
}; |
19 changes: 19 additions & 0 deletions
19
GerritStats/src/main/frontend/common/HorizontalCenterDiv.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import './HorizontalCenterDiv.scss' | ||
|
||
import React from 'react'; | ||
|
||
export default class HorizontalCenterDiv extends React.Component { | ||
constructor(props) { | ||
super(props); | ||
} | ||
|
||
render() { | ||
return ( | ||
<div className='horizontalCenterDiv'> | ||
{this.props.children} | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
HorizontalCenterDiv.displayName = 'HorizontalCenterDiv'; |
4 changes: 4 additions & 0 deletions
4
GerritStats/src/main/frontend/common/HorizontalCenterDiv.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
.horizontalCenterDiv { | ||
margin-left: 0px; | ||
text-align: center; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import './PageFooter.scss' | ||
|
||
import ClearFloat from './ClearFloat'; | ||
|
||
import React from 'react'; | ||
import moment from 'moment'; | ||
|
||
export default class PageFooter extends React.Component { | ||
constructor(props) { | ||
super(props); | ||
} | ||
|
||
renderTimestamp(timestamp) { | ||
if (!timestamp) { | ||
return '\u2013'; | ||
} else { | ||
return moment(timestamp).format('YYYY-MM-DD hh:mm:ss') | ||
} | ||
} | ||
|
||
render() { | ||
return ( | ||
<footer> | ||
<div className="footerContent"> | ||
<div className="footerLeft"> | ||
<a href="https://github.com/holmari/gerritstats">Github</a> | ||
</div> | ||
<div className="footerRight"> | ||
Generated on {this.renderTimestamp(this.props.datasetOverview['generatedDate'])} | ||
</div> | ||
<ClearFloat /> | ||
</div> | ||
</footer> | ||
); | ||
} | ||
} | ||
|
||
PageFooter.displayName = 'PageFooter'; | ||
|
||
PageFooter.defaultProps = { | ||
datasetOverview: { | ||
generatedDate: 0 | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
footer { | ||
display: block; | ||
clear: both; | ||
padding-top: 1em; | ||
} | ||
|
||
.footerContent { | ||
background-color: #303138; | ||
padding-top: 10px; | ||
padding-bottom: 10px; | ||
padding-left: 14px; | ||
padding-right: 14px; | ||
color: #f4f4f4; | ||
} | ||
|
||
.footerLeft { | ||
float: left; | ||
} | ||
|
||
.footerRight { | ||
float: right; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import './Panel.scss'; | ||
|
||
import classnames from 'classnames'; | ||
import {List} from 'immutable'; | ||
import React from 'react'; | ||
|
||
export default class Panel extends React.Component { | ||
constructor(props) { | ||
super(props); | ||
} | ||
|
||
getClassNames() { | ||
return classnames( | ||
'panel', | ||
{'thirdWidth': this.props.size == 'third'}, | ||
{'twoThirdsWidth': this.props.size == 'twoThirds'}, | ||
{'halfWidth': this.props.size == 'half'}, | ||
{'fullWidth': this.props.size == 'full'}, | ||
{'flexWidth': this.props.size == 'flex'}, | ||
{'fourthWidth': this.props.size == 'fourth'}, | ||
{'threeFourthsWidth': this.props.size == 'threeFourths'}, | ||
); | ||
} | ||
|
||
render() { | ||
const className = this.getClassNames(); | ||
return ( | ||
<div className={className}> | ||
<h2>{this.props.title}</h2> | ||
{this.props.children} | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
Panel.displayName = 'Panel'; | ||
|
||
Panel.defaultProps = { | ||
size: 'normal' | ||
}; | ||
|
||
Panel.propTypes = { | ||
title: React.PropTypes.string.isRequired, | ||
size: React.PropTypes.oneOf([ | ||
'normal', 'third', 'twoThirds', | ||
'half', 'full', 'flex', | ||
'fourth', 'threeFourths' | ||
]).isRequired, | ||
}; |
Oops, something went wrong.