From 7175d37b7e2664c2c508ea24377ecf4938f0f9a8 Mon Sep 17 00:00:00 2001 From: Alex P Date: Mon, 14 May 2018 16:22:52 -0700 Subject: [PATCH] Convert Notifications components to TypeScript --- .../{Notification.js => Notification.tsx} | 96 ++++++++++--------- ui/src/shared/components/Notifications.js | 44 --------- ui/src/shared/components/Notifications.tsx | 47 +++++++++ 3 files changed, 96 insertions(+), 91 deletions(-) rename ui/src/shared/components/{Notification.js => Notification.tsx} (65%) delete mode 100644 ui/src/shared/components/Notifications.js create mode 100644 ui/src/shared/components/Notifications.tsx diff --git a/ui/src/shared/components/Notification.js b/ui/src/shared/components/Notification.tsx similarity index 65% rename from ui/src/shared/components/Notification.js rename to ui/src/shared/components/Notification.tsx index e185e6d53c..9dc3bb5872 100644 --- a/ui/src/shared/components/Notification.js +++ b/ui/src/shared/components/Notification.tsx @@ -1,17 +1,32 @@ import React, {Component} from 'react' -import PropTypes from 'prop-types' import {connect} from 'react-redux' import {bindActionCreators} from 'redux' +import {Notification as NotificationType} from 'src/types/notifications' import classnames from 'classnames' -import {dismissNotification as dismissNotificationAction} from 'shared/actions/notifications' +import {dismissNotification as dismissNotificationAction} from 'src/shared/actions/notifications' -import {NOTIFICATION_TRANSITION} from 'shared/constants/index' +import {NOTIFICATION_TRANSITION} from 'src/shared/constants/index' import {ErrorHandling} from 'src/shared/decorators/errors' +interface Props { + notification: NotificationType + dismissNotification: (id: string) => void +} + +interface State { + opacity: number + height: number + dismissed: boolean +} + @ErrorHandling -class Notification extends Component { +class Notification extends Component { + private notificationRef: HTMLElement + private dismissalTimer: number + private deletionTimer: number + constructor(props) { super(props) @@ -22,7 +37,7 @@ class Notification extends Component { } } - componentDidMount() { + public componentDidMount() { const { notification: {duration}, } = this.props @@ -31,41 +46,16 @@ class Notification extends Component { if (duration >= 0) { // Automatically dismiss notification after duration prop - this.dismissTimer = setTimeout(this.handleDismiss, duration) + this.dismissalTimer = window.setTimeout(this.handleDismiss, duration) } } - updateHeight() { - if (this.notificationRef) { - const {height} = this.notificationRef.getBoundingClientRect() - this.setState({height}) - } + public componentWillUnmount() { + clearTimeout(this.dismissalTimer) + clearTimeout(this.deletionTimer) } - componentWillUnmount() { - clearTimeout(this.dismissTimer) - clearTimeout(this.deleteTimer) - } - - handleDismiss = () => { - const { - notification: {id}, - dismissNotification, - } = this.props - - this.setState({dismissed: true}) - this.deleteTimer = setTimeout( - () => dismissNotification(id), - NOTIFICATION_TRANSITION - ) - } - - onNotificationRef = ref => { - this.notificationRef = ref - this.updateHeight() - } - - render() { + public render() { const { notification: {type, message, icon}, } = this.props @@ -81,7 +71,7 @@ class Notification extends Component { return (
-
+
{message}
) } -} -const {func, number, shape, string} = PropTypes + private updateHeight = (): void => { + if (this.notificationRef) { + const {height} = this.notificationRef.getBoundingClientRect() + this.setState({height}) + } + } -Notification.propTypes = { - notification: shape({ - id: string.isRequired, - type: string.isRequired, - message: string.isRequired, - duration: number.isRequired, - icon: string.isRequired, - }).isRequired, - dismissNotification: func.isRequired, + private handleDismiss = (): void => { + const { + notification: {id}, + dismissNotification, + } = this.props + + this.setState({dismissed: true}) + this.deletionTimer = window.setTimeout( + () => dismissNotification(id), + NOTIFICATION_TRANSITION + ) + } + + private handleNotificationRef = (ref: HTMLElement): void => { + this.notificationRef = ref + this.updateHeight() + } } const mapDispatchToProps = dispatch => ({ diff --git a/ui/src/shared/components/Notifications.js b/ui/src/shared/components/Notifications.js deleted file mode 100644 index f08bec6245..0000000000 --- a/ui/src/shared/components/Notifications.js +++ /dev/null @@ -1,44 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import {connect} from 'react-redux' - -import Notification from 'shared/components/Notification' - -const Notifications = ({notifications, inPresentationMode}) => ( -
- {notifications.map(n => )} -
-) - -const {arrayOf, bool, number, shape, string} = PropTypes - -Notifications.propTypes = { - notifications: arrayOf( - shape({ - id: string.isRequired, - type: string.isRequired, - message: string.isRequired, - duration: number.isRequired, - icon: string, - }) - ), - inPresentationMode: bool, -} - -const mapStateToProps = ({ - notifications, - app: { - ephemeral: {inPresentationMode}, - }, -}) => ({ - notifications, - inPresentationMode, -}) - -export default connect(mapStateToProps, null)(Notifications) diff --git a/ui/src/shared/components/Notifications.tsx b/ui/src/shared/components/Notifications.tsx new file mode 100644 index 0000000000..aafe2e1e8b --- /dev/null +++ b/ui/src/shared/components/Notifications.tsx @@ -0,0 +1,47 @@ +import React, {PureComponent} from 'react' +import {connect} from 'react-redux' +import {Notification as NotificationType} from 'src/types/notifications' +import Notification from 'src/shared/components/Notification' + +interface Props { + inPresentationMode?: boolean + notifications: NotificationType[] +} + +class Notifications extends PureComponent { + public static defaultProps: Partial = { + inPresentationMode: false, + } + + public render() { + const {notifications} = this.props + + return ( +
+ {notifications.map(n => )} +
+ ) + } + + private get className(): string { + const {inPresentationMode} = this.props + + if (inPresentationMode) { + return 'notification-center__presentation-mode' + } + + return 'notification-center' + } +} + +const mapStateToProps = ({ + notifications, + app: { + ephemeral: {inPresentationMode}, + }, +}) => ({ + notifications, + inPresentationMode, +}) + +export default connect(mapStateToProps, null)(Notifications)