Merge pull request #421 from yuya-oc/remove-server-modal
Add "Remove Server" modal
This commit is contained in:
commit
da64cec869
|
@ -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"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
42
src/browser/components/DestructiveConfirmModal.jsx
Normal file
42
src/browser/components/DestructiveConfirmModal.jsx
Normal 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;
|
32
src/browser/components/RemoveServerModal.jsx
Normal file
32
src/browser/components/RemoveServerModal.jsx
Normal 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;
|
|
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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']
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue