Add component room-admin/AddRoomDialog

Change-Id: Ia6546dff76388b4542f8a2fe22181556297cc3b6
This commit is contained in:
Manuel Stahl 2019-08-22 19:58:29 +02:00
parent 8109f19c0e
commit 2628c70cdf
6 changed files with 191 additions and 8 deletions

View File

@ -0,0 +1,127 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from '@material-ui/core';
import { Button, Checkbox, CircularProgress, FormControlLabel, TextField } from '@material-ui/core';
import * as actions from './redux/actions';
export class AddRoomDialog extends Component {
static propTypes = {
open: PropTypes.bool.isRequired,
onClose: PropTypes.func.isRequired,
roomAdmin: PropTypes.object.isRequired,
actions: PropTypes.object.isRequired,
};
constructor(props) {
super(props);
this.state = {
is_public: false,
is_federated: false,
room_alias_name: '',
name: '',
topic: '',
};
this.handleChange = this.handleChange.bind(this);
this.handleCheckbox = this.handleCheckbox.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
if (this.props.roomAdmin.createRoomError) this.props.actions.dismissCreateRoomError();
}
componentDidUpdate(prevProps) {
if (!this.props.roomAdmin.createRoomError
&& prevProps.roomAdmin.createRoomPending
&& !this.props.roomAdmin.createRoomPending) {
this.props.onClose();
}
}
handleChange(e) {
const { name, value } = e.target;
this.setState({ [name]: value });
if (this.props.roomAdmin.createRoomError) this.props.actions.dismissCreateRoomError();
}
handleCheckbox(e) {
const { name, checked } = e.target;
this.setState({ [name]: checked });
if (this.props.roomAdmin.createRoomError) this.props.actions.dismissCreateRoomError();
}
handleSubmit(e) {
e.preventDefault();
const { is_public, is_federated } = this.state;
var creation_content = {};
creation_content['m.federate'] = is_federated;
this.setState({
visibility: is_public ? 'public' : 'private',
creation_content: creation_content,
});
this.props.actions.createRoom(this.state)
}
render() {
const { open, onClose } = this.props;
const { createRoomPending, createRoomError } = this.props.roomAdmin;
return (
<Dialog className="room-admin-add-room-dialog" open={open} onClose={onClose} aria-labelledby="form-dialog-title">
<DialogTitle id="form-dialog-title">Add Room</DialogTitle>
<DialogContent>
{createRoomError && <DialogContentText color="error">{createRoomError.message}</DialogContentText>}
<form className="app-login" onSubmit={this.handleSubmit}>
<div>
<FormControlLabel
label="Public"
name="is_public"
onChange={this.handleCheckbox}
control={<Checkbox color="primary" />}
margin="dense"
labelPlacement="start"
/>
<FormControlLabel
label="Federated"
name="is_federated"
onChange={this.handleCheckbox}
control={<Checkbox color="primary" />}
margin="dense"
labelPlacement="start"
/>
</div>
<div><TextField label="Alias" name="room_alias_name" onChange={this.handleChange} margin="dense" autoFocus /></div>
<div><TextField label="Name" name="name" onChange={this.handleChange} margin="dense" /></div>
<div><TextField label="Topic" name="topic" onChange={this.handleChange} margin="dense" /></div>
{createRoomPending ?
(<CircularProgress size={24} className="buttonProgress" />) :
(<DialogActions className="button">
<Button variant="outlined" color="primary" margin="normal" onClick={onClose}>Cancel</Button>
<Button variant="contained" color="primary" margin="normal" type="submit">Create</Button>
</DialogActions>)
}
</form>
</DialogContent>
</Dialog>
);
}
}
/* istanbul ignore next */
function mapStateToProps(state) {
return {
roomAdmin: state.roomAdmin,
};
}
/* istanbul ignore next */
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({ ...actions }, dispatch)
};
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(AddRoomDialog);

View File

@ -0,0 +1 @@
@import '../../styles/mixins';

View File

@ -3,28 +3,62 @@ import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { Redirect } from 'react-router-dom'
import { Table, TableBody, TableCell, TableHead, TableRow } from '@material-ui/core';
import { withStyles } from '@material-ui/core/styles';
import { Fab, Table, TableBody, TableCell, TableHead, TableRow } from '@material-ui/core';
import AddIcon from '@material-ui/icons/Add';
import AddRoomDialog from './AddRoomDialog';
import * as actions from './redux/actions';
const styles = theme => ({
fab: {
margin: 0,
top: 'auto',
right: 20,
bottom: 20,
left: 'auto',
position: 'fixed',
},
});
export class List extends Component {
static propTypes = {
roomAdmin: PropTypes.object.isRequired,
actions: PropTypes.object.isRequired,
classes: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
};
componentDidMount() {
const { fetchPublicRooms } = this.props.actions;
fetchPublicRooms();
constructor(props) {
super(props);
this.state = {
addRoomDialogOpen: false,
};
}
render() {
const { mtx } = this.props;
const { roomList, fetchRoomsPending } = this.props.roomAdmin;
componentDidMount() {
this.props.actions.fetchPublicRooms();
}
handleOpenAddDialog = () => {
this.setState({ addRoomDialogOpen: true });
};
handleCloseAddDialog = () => {
this.setState({ addRoomDialogOpen: false });
this.props.actions.fetchPublicRooms();
};
render() {
const { classes, mtx } = this.props;
const { roomList, fetchRoomsPending } = this.props.roomAdmin;
const { addRoomDialogOpen } = this.state;
return (
<div className="room-admin-list">
{(!mtx || !mtx.clientRunning) && <Redirect to="/" />}
{fetchRoomsPending && <img alt="logging in" src="data:image/gif;base64,R0lGODlhEAAQAPIAAP///wAAAMLCwkJCQgAAAGJiYoKCgpKSkiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA==" />}
<Fab color="primary" className={classes.fab} onClick={this.handleOpenAddDialog}><AddIcon /></Fab>
<AddRoomDialog open={addRoomDialogOpen} onClose={this.handleCloseAddDialog} />
<Table className="room-list">
<TableHead>
<TableRow>
@ -68,4 +102,4 @@ function mapDispatchToProps(dispatch) {
export default connect(
mapStateToProps,
mapDispatchToProps
)(List);
)(withStyles(styles, { withTheme: true })(List));

View File

@ -1 +1,2 @@
export { default as List } from './List';
export { default as AddRoomDialog } from './AddRoomDialog';

View File

@ -1,2 +1,3 @@
@import '../../styles/mixins';
@import './List';
@import './AddRoomDialog';

View File

@ -0,0 +1,19 @@
import React from 'react';
import { shallow } from 'enzyme';
import { AddRoomDialog } from '../../../src/features/room-admin/AddRoomDialog';
describe('room-admin/AddRoomDialog', () => {
it('renders node with correct class name', () => {
const props = {
roomAdmin: {},
actions: {},
};
const renderedComponent = shallow(
<AddRoomDialog {...props} />
);
expect(
renderedComponent.find('.room-admin-add-room-dialog').length
).toBe(1);
});
});