Skip to content

Commit 7312215

Browse files
author
lewis617
committed
add r2-bs-alert
1 parent 8d6655e commit 7312215

File tree

15 files changed

+6175
-0
lines changed

15 files changed

+6175
-0
lines changed

r2-bs-alert/.gitignore

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# See http://help.github.com/ignore-files/ for more about ignoring files.
2+
3+
# dependencies
4+
node_modules
5+
6+
# testing
7+
coverage
8+
9+
# production
10+
build
11+
12+
# misc
13+
.DS_Store
14+
.env
15+
npm-debug.log

r2-bs-alert/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# React Redux Bootstrap Alert Example

r2-bs-alert/package.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "r2-bs-alert",
3+
"version": "0.1.0",
4+
"private": true,
5+
"devDependencies": {
6+
"enzyme": "^2.6.0",
7+
"react-addons-test-utils": "^15.3.2",
8+
"react-scripts": "0.7.0",
9+
"redux-mock-store": "^1.2.1",
10+
"redux-thunk": "^2.1.0"
11+
},
12+
"dependencies": {
13+
"bootstrap": "3",
14+
"react": "^15.3.2",
15+
"react-bootstrap": "^0.30.6",
16+
"react-dom": "^15.3.2",
17+
"react-redux": "^4.4.6",
18+
"redux": "^3.6.0"
19+
},
20+
"scripts": {
21+
"start": "react-scripts start",
22+
"build": "react-scripts build",
23+
"test": "react-scripts test --env=jsdom",
24+
"eject": "react-scripts eject"
25+
}
26+
}

r2-bs-alert/public/favicon.ico

24.3 KB
Binary file not shown.

r2-bs-alert/public/index.html

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1">
6+
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
7+
<!--
8+
Notice the use of %PUBLIC_URL% in the tag above.
9+
It will be replaced with the URL of the `public` folder during the build.
10+
Only files inside the `public` folder can be referenced from the HTML.
11+
12+
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
13+
work correctly both with client-side routing and a non-root public URL.
14+
Learn how to configure a non-root public URL by running `npm run build`.
15+
-->
16+
<title>React App</title>
17+
</head>
18+
<body>
19+
<div id="root"></div>
20+
<!--
21+
This HTML file is a template.
22+
If you open it directly in the browser, you will see an empty page.
23+
24+
You can add webfonts, meta tags, or analytics to this file.
25+
The build step will place the bundled scripts into the <body> tag.
26+
27+
To begin the development, run `npm start`.
28+
To create a production bundle, use `npm run build`.
29+
-->
30+
</body>
31+
</html>

r2-bs-alert/src/App.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.App{
2+
width: 500px;
3+
}

r2-bs-alert/src/App.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import React, { Component } from 'react';
2+
import { AlertList } from './alert';
3+
import { ButtonGroup, Button } from 'react-bootstrap';
4+
import { connect } from 'react-redux';
5+
import { alertMessage } from './alert';
6+
import './App.css';
7+
8+
class App extends Component {
9+
render() {
10+
return (
11+
<div className="App">
12+
<AlertList />
13+
<ButtonGroup>
14+
<Button
15+
onClick={() => this.props.dispatch(alertMessage('Success', 'success'))}
16+
bsStyle="success"
17+
>
18+
Success
19+
</Button>
20+
<Button
21+
onClick={() => this.props.dispatch(alertMessage('Danger', 'danger', 5500))}
22+
bsStyle="danger"
23+
>
24+
Danger
25+
</Button>
26+
<Button
27+
onClick={() => this.props.dispatch(alertMessage('Warning', 'warning'))}
28+
bsStyle="warning"
29+
>
30+
Warning
31+
</Button>
32+
<Button
33+
onClick={() => this.props.dispatch(alertMessage('Info', 'info'))}
34+
bsStyle="info"
35+
>
36+
Info
37+
</Button>
38+
</ButtonGroup>
39+
</div>
40+
);
41+
}
42+
}
43+
44+
export default connect()(App);

r2-bs-alert/src/App.test.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import React from 'react';
2+
import ReactDOM from 'react-dom';
3+
import { createStore, combineReducers, applyMiddleware } from 'redux';
4+
import { Provider } from 'react-redux';
5+
import thunk from 'redux-thunk';
6+
import App from './App';
7+
import { reducer as alertsReducer, alertMessage } from './alert';
8+
import 'bootstrap/dist/css/bootstrap.css';
9+
10+
const store = createStore(
11+
combineReducers({ alerts: alertsReducer }),
12+
{},
13+
applyMiddleware(thunk)
14+
);
15+
16+
it('renders without crashing', () => {
17+
const div = document.createElement('div');
18+
ReactDOM.render(
19+
<Provider store={store}>
20+
<App />
21+
</Provider>,
22+
div
23+
);
24+
});

r2-bs-alert/src/alert/AlertList.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import React, { Component, PropTypes } from 'react';
2+
import { connect } from 'react-redux';
3+
import Alert from 'react-bootstrap/lib/Alert';
4+
import { hideAllAlert, alertHide } from './redux';
5+
6+
class CustomAlert extends Component {
7+
static propTypes = {
8+
alerts: PropTypes.array.isRequired,
9+
hideAllAlert: PropTypes.func.isRequired,
10+
alertHide: PropTypes.func.isRequired
11+
};
12+
13+
componentDidMount() {
14+
this.props.hideAllAlert();
15+
}
16+
17+
render() {
18+
const { alerts, alertHide } = this.props;
19+
return (
20+
<div>
21+
{alerts.map((item, i) => (
22+
<Alert
23+
key={i}
24+
bsStyle={item.messageType}
25+
onDismiss={() => alertHide(item.key)}
26+
>
27+
{item.messageText}
28+
</Alert>
29+
))}
30+
</div>
31+
);
32+
}
33+
}
34+
35+
export default connect(
36+
state => ({
37+
alerts: state.alerts.items
38+
}),
39+
{ hideAllAlert, alertHide }
40+
)(CustomAlert);
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import React from 'react';
2+
import { mount } from 'enzyme';
3+
import { createStore, combineReducers, applyMiddleware } from 'redux';
4+
import { Provider } from 'react-redux';
5+
import thunk from 'redux-thunk';
6+
import { AlertList, reducer } from '../index';
7+
8+
function setup(state = {}) {
9+
const store = createStore(
10+
combineReducers({ alerts: reducer }),
11+
state,
12+
applyMiddleware(thunk)
13+
);
14+
const app = mount(
15+
<Provider store={store}>
16+
<AlertList />
17+
</Provider>
18+
);
19+
return {
20+
app,
21+
store
22+
};
23+
}
24+
25+
describe('AlertList', () => {
26+
let originalTimeout;
27+
beforeEach(function() {
28+
originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
29+
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
30+
});
31+
32+
afterEach(function() {
33+
jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
34+
});
35+
it('should display messages and hide all after delay', () => {
36+
const { app } = setup({ alerts: { lastKey: 1, items: [{ key: 0 }, { key: 1 }] } });
37+
expect(app.find('.alert').length).toBe(2);
38+
return new Promise(resolve => {
39+
setTimeout(() => {
40+
resolve();
41+
}, 5000)
42+
}).then(() => {
43+
expect(app.find('.alert').length).toBe(0);
44+
});
45+
});
46+
47+
it('should display messages and hide itself after clicked', () => {
48+
const { app } = setup({
49+
alerts: {
50+
lastKey: 1,
51+
items: [{ key: 0, messageText: 'messageText1' }, { key: 1, messageText: 'messageText2' }]
52+
}
53+
});
54+
app.find('.alert').at(1).find('button').at(0)
55+
.simulate('click');
56+
expect(app.find('.alert').text()).not.toMatch(/messageText2/);
57+
expect(app.find('.alert').text()).toMatch(/messageText1/);
58+
});
59+
});

0 commit comments

Comments
 (0)