Skip to content

Commit 69d2397

Browse files
authored
Merge pull request #5 from AllenFang/app-alert
Implement for App Alert
2 parents 32c1dae + 6bc6dd0 commit 69d2397

22 files changed

+496
-14
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"bootstrap-sass": "^3.3.7",
3333
"color": "~1.0.3",
3434
"cookie-parser": "~1.4.3",
35+
"cors": "^2.8.3",
3536
"crossroads": "~0.12.2",
3637
"diff2html": "^2.3.0",
3738
"express": "~4.15.2",
@@ -60,6 +61,7 @@
6061
"react-dom": "^15.5.4",
6162
"react-redux": "^5.0.4",
6263
"redux": "^3.6.0",
64+
"redux-thunk": "^2.2.0",
6365
"rimraf": "~2.6.1",
6466
"semver": "~5.3.0",
6567
"serve-static": "~1.12.2",

source/server.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const BugTracker = require('./bugtracker');
33
const bugtracker = new BugTracker('server');
44
const usageStatistics = require('./usage-statistics');
55
const express = require('express');
6+
const cors = require('cors')
67
const gitApi = require('./git-api');
78
const winston = require('winston');
89
const sysinfo = require('./sysinfo');
@@ -107,6 +108,7 @@ const noCache = (req, res, next) => {
107108
app.use(noCache);
108109

109110
app.use(require('body-parser').json());
111+
app.use(cors()); // we should consider to remove it when we complete this project
110112

111113
if (config.autoShutdownTimeout) {
112114
let autoShutdownTimeout;
@@ -270,6 +272,20 @@ app.get('/serverdata.js', (req, res) => {
270272
});
271273
});
272274

275+
app.get('/ungit/config', (req, res) => {
276+
sysinfo.getUserHash()
277+
.then((hash) => {
278+
const ungitConfig = {
279+
config,
280+
userHash: hash,
281+
version: config.ungitDevVersion,
282+
platform: os.platform(),
283+
pluginApiVersion: require('../package.json').ungitPluginApiVersion
284+
};
285+
res.send(JSON.stringify(ungitConfig));
286+
});
287+
});
288+
273289
app.get('/api/latestversion', (req, res) => {
274290
sysinfo.getUngitLatestVersion()
275291
.then((latestVersion) => {

src-react/actions/bootstrap.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { fetchUngitConfig } from './ungit-config';
2+
import { fetchLatestVersion, fetchGitVersion } from './version';
3+
import { pending } from './common';
4+
5+
export function bootstrap() {
6+
return dispatch => {
7+
dispatch(pending(3));
8+
dispatch(fetchUngitConfig());
9+
dispatch(fetchLatestVersion());
10+
dispatch(fetchGitVersion());
11+
};
12+
}

src-react/actions/common.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/* This export common using actionCreator */
2+
import * as types from 'constants/action-types';
3+
4+
export function pending(count) {
5+
return {
6+
type: types.PATH_PAGE_PENDING,
7+
payload: count || 1
8+
};
9+
};
10+
11+
export function apiError(message) {
12+
return {
13+
type: types.PATH_PAGE_API_ERR,
14+
payload: message
15+
};
16+
}

src-react/actions/ungit-config.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import * as types from 'constants/action-types';
2+
import { fetchUserConfig } from './user-config';
3+
import { apiError, pending } from './common';
4+
5+
export function fetchUngitConfig() {
6+
return dispatch => {
7+
// consider wrap API call in separate modules
8+
// it will be easy to stub module's function when testing
9+
fetch('http://localhost:8448/ungit/config')
10+
.then(response => response.json())
11+
.then(json => {
12+
if (!json.config.bugtracking) {
13+
dispatch(pending());
14+
dispatch(fetchUserConfig());
15+
}
16+
dispatch(receiveUngitConfig(json));
17+
})
18+
.catch(e => {
19+
dispatch(apiError(e.message));
20+
});
21+
};
22+
};
23+
24+
function receiveUngitConfig(ungitConfig) {
25+
return {
26+
type: types.RECEIVE_UNGIT_CONFIG,
27+
payload: ungitConfig
28+
};
29+
};

src-react/actions/user-config.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import * as types from 'constants/action-types';
2+
import { apiError } from './common';
3+
4+
export function fetchUserConfig() {
5+
return dispatch => {
6+
// consider wrap API call in separate modules
7+
// it will be easy to stub module's function when testing
8+
fetch('http://localhost:8448/api/userconfig')
9+
.then(response => response.json())
10+
.then(json => {
11+
dispatch(receiveUserConfig(json));
12+
})
13+
.catch(e => {
14+
dispatch(apiError(e.message));
15+
});
16+
};
17+
};
18+
19+
20+
function receiveUserConfig(userConfig) {
21+
return {
22+
type: types.RECEIVE_USER_CONFIG,
23+
payload: userConfig
24+
};
25+
};

src-react/actions/version.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import * as types from 'constants/action-types';
2+
import { apiError } from './common';
3+
4+
export function fetchLatestVersion() {
5+
return dispatch => {
6+
// consider wrap API call in separate modules
7+
// it will be easy to stub module's function when testing
8+
fetch('http://localhost:8448/api/latestversion')
9+
.then(response => response.json())
10+
.then(json => {
11+
dispatch(receiveLatestVersion(json));
12+
})
13+
.catch(e => {
14+
dispatch(apiError(e.message));
15+
});
16+
};
17+
}
18+
19+
export function fetchGitVersion() {
20+
return dispatch => {
21+
// consider wrap API call in separate modules
22+
// it will be easy to stub module's function when testing
23+
fetch('http://localhost:8448/api/gitversion')
24+
.then(response => response.json())
25+
.then(json => {
26+
dispatch(receiveGitVersion(json));
27+
})
28+
.catch(e => {
29+
dispatch(apiError(e.message));
30+
});
31+
};
32+
}
33+
34+
function receiveGitVersion(gitVersion) {
35+
return {
36+
type: types.RECEIVE_GIT_VERSION,
37+
payload: gitVersion
38+
};
39+
}
40+
41+
function receiveLatestVersion(latestVersion) {
42+
return {
43+
type: types.RECEIVE_LATEST_VERSION,
44+
payload: latestVersion
45+
};
46+
};
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import React, { Component } from 'react';
2+
3+
class BugTrackingNagScreen extends Component {
4+
render() {
5+
return (
6+
<div className="alert alert-info clearfix">
7+
<button type="button" className="close" data-bind="click: dismissBugtrackingNagscreen">&times;</button>
8+
<p><strong>Help make ungit better with the press of a button!</strong></p>
9+
<button className="btn btn-primary" data-bind="click: enableBugtrackingAndStatistics">Enable automatic bug reports + anonymous usage statistics</button>
10+
<button className="btn btn-primary" data-bind="click: enableBugtracking">Enable automatic bug reports</button>
11+
<button className="btn btn-default" data-bind="click: dismissBugtrackingNagscreen">Naah, I&#39;ll skip that</button>
12+
</div>
13+
);
14+
}
15+
}
16+
17+
export default BugTrackingNagScreen;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import React, { Component, PropTypes } from 'react';
2+
3+
class GitVersionError extends Component {
4+
static propTypes = {
5+
gitVersionError: PropTypes.string
6+
}
7+
8+
render() {
9+
return (
10+
<div class="alert alert-danger">
11+
<span>{ this.props.gitVersionError }</span>
12+
<button type="button" className="close" data-bind="click: dismissGitVersionError">&times;</button>
13+
</div>
14+
);
15+
}
16+
}
17+
18+
export default GitVersionError;
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import React, { Component, PropTypes } from 'react';
2+
3+
import GitVersionError from './git-version-error';
4+
import NewVersionAvailable from './new-version-available';
5+
import BugTrackingNagScreen from './bug-tracking-nag-screen';
6+
import NPSSurvey from './nps-survey';
7+
8+
class AlertArea extends Component {
9+
static propTypes = {
10+
config: PropTypes.object.isRequired,
11+
gitVersionErrorVisible: PropTypes.bool.isRequired,
12+
showNewVersionAvailable: PropTypes.bool.isRequired,
13+
showBugtrackingNagscreen: PropTypes.bool.isRequired,
14+
showNPSSurvey: PropTypes.bool.isRequired
15+
}
16+
17+
render() {
18+
const {
19+
config: {
20+
ungitConfig: { platform },
21+
versions: {
22+
gitVersion: { error },
23+
latestVersion: {
24+
latestVersion
25+
}
26+
}
27+
},
28+
gitVersionErrorVisible,
29+
showNewVersionAvailable,
30+
showBugtrackingNagscreen,
31+
showNPSSurvey
32+
} = this.props;
33+
return (
34+
<div className="container" data-ta-container="app">
35+
{
36+
gitVersionErrorVisible ? (
37+
<GitVersionError gitVersionError={ error }/>
38+
) : null
39+
}
40+
{
41+
showNewVersionAvailable ? (
42+
<NewVersionAvailable
43+
latestVersion={ latestVersion }
44+
platform={ platform }/>
45+
) : null
46+
}
47+
{
48+
showBugtrackingNagscreen ? (
49+
<BugTrackingNagScreen />
50+
) : null
51+
}
52+
{
53+
showNPSSurvey ? (
54+
<NPSSurvey />
55+
) : null
56+
}
57+
</div>
58+
);
59+
}
60+
}
61+
62+
export default AlertArea;

0 commit comments

Comments
 (0)