diff --git a/ui/src/pages/Applications.js b/ui/src/pages/Applications.js deleted file mode 100644 index 393bafd..0000000 --- a/ui/src/pages/Applications.js +++ /dev/null @@ -1,184 +0,0 @@ -import React, {Component} from 'react'; -import Grid from 'material-ui/Grid'; -import Table, {TableBody, TableCell, TableHead, TableRow} from 'material-ui/Table'; -import Paper from 'material-ui/Paper'; -import Button from 'material-ui/Button'; -import IconButton from 'material-ui/IconButton'; -import Dialog, {DialogActions, DialogContent, DialogContentText, DialogTitle} from 'material-ui/Dialog'; -import TextField from 'material-ui/TextField'; -import Tooltip from 'material-ui/Tooltip'; -import AppStore from '../stores/AppStore'; -import ToggleVisibility from '../component/ToggleVisibility'; -import ConfirmDialog from '../component/ConfirmDialog'; -import * as AppAction from '../actions/AppAction'; -import DefaultPage from '../component/DefaultPage'; -import PropTypes from 'prop-types'; -import Delete from 'material-ui-icons/Delete'; -import Avatar from 'material-ui/Avatar'; -import Edit from 'material-ui-icons/Edit'; - -class Applications extends Component { - constructor() { - super(); - this.uploadId = -1; - this.state = {apps: [], createDialog: false, deleteId: -1}; - } - - componentWillMount() { - AppStore.on('change', this.updateApps); - this.updateApps(); - } - - componentWillUnmount() { - AppStore.removeListener('change', this.updateApps); - } - - updateApps = () => this.setState({...this.state, apps: AppStore.get()}); - - uploadImage = (id) => { - this.uploadId = id; - this.upload.click(); - }; - onUploadImage = (e) => { - const file = e.target.files[0]; - if (!file) { - return; - } - if (['image/png', 'image/jpeg', 'image/gif'].indexOf(file['type']) !== -1) { - AppAction.uploadImage(this.uploadId, file); - } else { - alert('Uploaded file must be of type png, jpeg or gif.'); - } - }; - - showCreateDialog = () => this.setState({...this.state, createDialog: true}); - hideCreateDialog = () => this.setState({...this.state, createDialog: false}); - - showCloseDialog = (deleteId) => this.setState({...this.state, deleteId}); - hideCloseDialog = () => this.setState({...this.state, deleteId: -1}); - - render() { - const {apps, createDialog, deleteId} = this.state; - return ( - - - - - - - - Name - Token - Description - - - - - {apps.map((app) => { - return ( - this.uploadImage(app.id)} - fDelete={() => this.showCloseDialog(app.id)}/> - ); - })} - -
- this.upload = upload} type="file" style={{display: 'none'}} - onChange={this.onUploadImage}/> -
-
- {createDialog && } - {deleteId !== -1 && AppAction.deleteApp(deleteId)} - />} -
- ); - } -} - -class Row extends Component { - static propTypes = { - name: PropTypes.string.isRequired, - value: PropTypes.string.isRequired, - description: PropTypes.string.isRequired, - fDelete: PropTypes.func.isRequired, - fUpload: PropTypes.func.isRequired, - image: PropTypes.string.isRequired, - }; - - render() { - const {name, value, description, fDelete, fUpload, image} = this.props; - return ( - - -
- -
-
- {name} - - - - {description} - - - -
- ); - } -} - -class AddDialog extends Component { - static propTypes = { - fClose: PropTypes.func.isRequired, - fOnSubmit: PropTypes.func.isRequired, - }; - - constructor() { - super(); - this.state = {name: '', description: ''}; - } - - handleChange(propertyName, event) { - const state = this.state; - state[propertyName] = event.target.value; - this.setState(state); - } - - render() { - const {fClose, fOnSubmit} = this.props; - const {name, description} = this.state; - const submitEnabled = this.state.name.length !== 0; - const submitAndClose = () => { - fOnSubmit(name, description); - fClose(); - }; - return ( - - Create an application - - An application is allowed to send messages. - - - - - - -
- -
-
-
-
- ); - } -} - -export default Applications; diff --git a/ui/src/pages/Applications.tsx b/ui/src/pages/Applications.tsx new file mode 100644 index 0000000..632c7f5 --- /dev/null +++ b/ui/src/pages/Applications.tsx @@ -0,0 +1,131 @@ +import Delete from 'material-ui-icons/Delete'; +import Edit from 'material-ui-icons/Edit'; +import Avatar from 'material-ui/Avatar'; +import Grid from 'material-ui/Grid'; +import IconButton from 'material-ui/IconButton'; +import Paper from 'material-ui/Paper'; +import Table, {TableBody, TableCell, TableHead, TableRow} from 'material-ui/Table'; +import React, {ChangeEvent, Component, SFC} from 'react'; +import * as AppAction from '../actions/AppAction'; +import ConfirmDialog from '../component/ConfirmDialog'; +import DefaultPage from '../component/DefaultPage'; +import ToggleVisibility from '../component/ToggleVisibility'; +import AppStore from '../stores/AppStore'; +import AddApplicationDialog from './dialog/AddApplicationDialog'; + +interface IState { + apps: IApplication[] + createDialog: boolean + deleteId: number +} + +class Applications extends Component<{}, IState> { + public state = {apps: [], createDialog: false, deleteId: -1}; + private uploadId: number = -1; + private upload: HTMLInputElement | null = null; + + public componentWillMount() { + AppStore.on('change', this.updateApps); + this.updateApps(); + } + + public componentWillUnmount() { + AppStore.removeListener('change', this.updateApps); + } + + public render() { + const {apps, createDialog, deleteId} = this.state; + return ( + + + + + + + + Name + Token + Description + + + + + {apps.map((app: IApplication) => { + return ( + this.uploadImage(app.id)} + fDelete={() => this.showCloseDialog(app.id)}/> + ); + })} + +
+ this.upload = upload} type="file" style={{display: 'none'}} + onChange={this.onUploadImage}/> +
+
+ {createDialog && } + {deleteId !== -1 && AppAction.deleteApp(deleteId)} + />} +
+ ); + } + + private updateApps = () => this.setState({...this.state, apps: AppStore.get()}); + private uploadImage = (id: number) => { + this.uploadId = id; + if (this.upload) { + this.upload.click(); + } + }; + + private onUploadImage = (e: ChangeEvent) => { + const file = e.target.files && e.target.files[0]; + if (!file) { + return; + } + if (['image/png', 'image/jpeg', 'image/gif'].indexOf(file.type) !== -1) { + AppAction.uploadImage(this.uploadId, file); + } else { + alert('Uploaded file must be of type png, jpeg or gif.'); + } + }; + private showCreateDialog = () => this.setState({...this.state, createDialog: true}); + + private hideCreateDialog = () => this.setState({...this.state, createDialog: false}); + private showCloseDialog = (deleteId: number) => this.setState({...this.state, deleteId}); + + private hideCloseDialog = () => this.setState({...this.state, deleteId: -1}); +} + +interface IRowProps { + name: string + value: string + description: string + fUpload: VoidFunction + image: string + fDelete: VoidFunction +} + +const Row: SFC = ({name, value, description, fDelete, fUpload, image}) => ( + + +
+ +
+
+ {name} + + + + {description} + + + +
+); + +export default Applications; diff --git a/ui/src/pages/dialog/AddApplicationDialog.tsx b/ui/src/pages/dialog/AddApplicationDialog.tsx new file mode 100644 index 0000000..7abddea --- /dev/null +++ b/ui/src/pages/dialog/AddApplicationDialog.tsx @@ -0,0 +1,57 @@ +import Button from 'material-ui/Button'; +import Dialog, {DialogActions, DialogContent, DialogContentText, DialogTitle} from 'material-ui/Dialog'; +import TextField from 'material-ui/TextField'; +import Tooltip from 'material-ui/Tooltip'; +import React, {Component} from 'react'; + +interface IProps { + fClose: VoidFunction + fOnSubmit: (name: string, description: string) => void +} + +interface IState { + name: string + description: string +} + +export default class AddDialog extends Component { + public state = {name: '', description: ''}; + + public render() { + const {fClose, fOnSubmit} = this.props; + const {name, description} = this.state; + const submitEnabled = this.state.name.length !== 0; + const submitAndClose = () => { + fOnSubmit(name, description); + fClose(); + }; + return ( + + Create an application + + An application is allowed to send messages. + + + + + + +
+ +
+
+
+
+ ); + } + + private handleChange(propertyName: string, event: React.ChangeEvent) { + const state = this.state; + state[propertyName] = event.target.value; + this.setState(state); + } +} \ No newline at end of file