Merge pull request #421 from yuya-oc/remove-server-modal

Add "Remove Server" modal
This commit is contained in:
Yuya Ochiai 2017-01-25 20:50:30 +09:00 committed by GitHub
commit da64cec869
6 changed files with 162 additions and 3 deletions

View file

@ -40,6 +40,7 @@
"babel-core": "^6.21.0", "babel-core": "^6.21.0",
"babel-eslint": "^7.1.1", "babel-eslint": "^7.1.1",
"babel-loader": "^6.2.10", "babel-loader": "^6.2.10",
"babel-plugin-transform-object-rest-spread": "^6.22.0",
"babel-preset-react": "^6.16.0", "babel-preset-react": "^6.16.0",
"chai": "^3.5.0", "chai": "^3.5.0",
"chai-as-promised": "^6.0.0", "chai-as-promised": "^6.0.0",
@ -77,7 +78,10 @@
}, },
{ {
"from": "resources/linux", "from": "resources/linux",
"filter": ["create_desktop_file.sh", "README.md"] "filter": [
"create_desktop_file.sh",
"README.md"
]
} }
] ]
}, },

View file

@ -0,0 +1,42 @@
const React = require('react');
const {Button, Modal} = require('react-bootstrap');
function DestructiveConfirmationModal(props) {
const {
title,
body,
acceptLabel,
cancelLabel,
onAccept,
onCancel,
...rest} = props;
return (
<Modal {...rest}>
<Modal.Header closeButton={true}>
<Modal.Title>{title}</Modal.Title>
</Modal.Header>
{body}
<Modal.Footer>
<Button
bsStyle='link'
onClick={onCancel}
>{cancelLabel}</Button>
<Button
bsStyle='danger'
onClick={onAccept}
>{acceptLabel}</Button>
</Modal.Footer>
</Modal>
);
}
DestructiveConfirmationModal.propTypes = {
title: React.PropTypes.string.isRequired,
body: React.PropTypes.node.isRequired,
acceptLabel: React.PropTypes.string.isRequired,
cancelLabel: React.PropTypes.string.isRequired,
onAccept: React.PropTypes.func.isRequired,
onCancel: React.PropTypes.func.isRequired
};
module.exports = DestructiveConfirmationModal;

View file

@ -0,0 +1,32 @@
const React = require('react');
const {Modal} = require('react-bootstrap');
const DestructiveConfirmationModal = require('./DestructiveConfirmModal.jsx');
function RemoveServerModal(props) {
const {serverName, ...rest} = props;
return (
<DestructiveConfirmationModal
{...rest}
title='Remove Server'
acceptLabel='Remove'
cancelLabel='Cancel'
body={(
<Modal.Body>
<p>
{'This will remove the server from your Desktop App but will not delete any of its data' +
' - you can add the server back to the app at any time.'}
</p>
<p>
{'Confirm you wish to remove the '}<strong>{serverName}</strong>{' server?'}
</p>
</Modal.Body>
)}
/>
);
}
RemoveServerModal.propTypes = {
serverName: React.PropTypes.string.isRequired
};
module.exports = RemoveServerModal;

View file

@ -2,6 +2,7 @@ const React = require('react');
const {ListGroup} = require('react-bootstrap'); const {ListGroup} = require('react-bootstrap');
const TeamListItem = require('./TeamListItem.jsx'); const TeamListItem = require('./TeamListItem.jsx');
const TeamListItemNew = require('./TeamListItemNew.jsx'); const TeamListItemNew = require('./TeamListItemNew.jsx');
const RemoveServerModal = require('./RemoveServerModal.jsx');
const TeamList = React.createClass({ const TeamList = React.createClass({
propTypes: { propTypes: {
@ -13,6 +14,7 @@ const TeamList = React.createClass({
getInitialState() { getInitialState() {
return { return {
showTeamListItemNew: false, showTeamListItemNew: false,
indexToRemoveServer: -1,
team: { team: {
url: '', url: '',
name: '', name: '',
@ -58,11 +60,20 @@ const TeamList = React.createClass({
} }
}); });
}, },
openServerRemoveModal(indexForServer) {
this.setState({indexToRemoveServer: indexForServer});
},
closeServerRemoveModal() {
this.setState({indexToRemoveServer: -1});
},
render() { render() {
var self = this; var self = this;
var teamNodes = this.props.teams.map((team, i) => { var teamNodes = this.props.teams.map((team, i) => {
function handleTeamRemove() { function handleTeamRemove() {
self.handleTeamRemove(i); self.openServerRemoveModal(i);
} }
function handleTeamEditing() { function handleTeamEditing() {
@ -95,10 +106,25 @@ const TeamList = React.createClass({
addTeamForm = ''; addTeamForm = '';
} }
const removeServer = this.props.teams[this.state.indexToRemoveServer];
const removeServerModal = (
<RemoveServerModal
show={this.state.indexToRemoveServer !== -1}
serverName={removeServer ? removeServer.name : ''}
onHide={this.closeServerRemoveModal}
onCancel={this.closeServerRemoveModal}
onAccept={() => {
this.handleTeamRemove(this.state.indexToRemoveServer);
this.closeServerRemoveModal();
}}
/>
);
return ( return (
<ListGroup className='teamList'> <ListGroup className='teamList'>
{ teamNodes } { teamNodes }
{ addTeamForm } { addTeamForm }
{ removeServerModal}
</ListGroup> </ListGroup>
); );
} }

View file

@ -191,4 +191,58 @@ describe('browser/settings.html', function desc() {
}); });
}); });
}); });
describe('RemoveServerModal', () => {
const modalTitleSelector = '.modal-title=Remove Server';
beforeEach(() => {
env.addClientCommands(this.app.client);
return this.app.client.
loadSettingsPage().
isExisting(modalTitleSelector).should.eventually.false.
isVisible(modalTitleSelector).should.eventually.false.
click('=Remove').
waitForVisible(modalTitleSelector);
});
it('should remove existing team on click Remove', (done) => {
this.app.client.
element('.modal-dialog').click('.btn=Remove').
pause(500).
isExisting(modalTitleSelector).should.eventually.false.
click('#btnSave').
pause(500).then(() => {
const savedConfig = JSON.parse(fs.readFileSync(env.configFilePath, 'utf8'));
savedConfig.teams.should.deep.equal(config.teams.slice(1));
done();
});
});
it('should NOT remove existing team on click Cancel', (done) => {
this.app.client.
element('.modal-dialog').click('.btn=Cancel').
pause(500).
isExisting(modalTitleSelector).should.eventually.false.
click('#btnSave').
pause(500).then(() => {
const savedConfig = JSON.parse(fs.readFileSync(env.configFilePath, 'utf8'));
savedConfig.teams.should.deep.equal(config.teams);
done();
});
});
it('should disappear on click Close', () => {
return this.app.client.
click('.modal-dialog button.close').
pause(500).
isExisting(modalTitleSelector).should.eventually.false;
});
it('should disappear on click background', () => {
return this.app.client.
click('body').
pause(500).
isExisting(modalTitleSelector).should.eventually.false;
});
});
}); });

View file

@ -21,7 +21,8 @@ module.exports = merge(base, {
test: /\.jsx$/, test: /\.jsx$/,
loader: 'babel', loader: 'babel',
query: { query: {
presets: ['react'] presets: ['react'],
plugins: ['transform-object-rest-spread']
} }
}] }]
}, },