UNPKG

glass-app-manager

Version:

Informatica's Glass Framework CLI for bootstrapping

143 lines (117 loc) 4.29 kB
// @flow import React, { Component } from "react"; import PropTypes from "prop-types"; import ReactCountdownClock from "react-countdown-clock"; import Dialog from "../dialog/Dialog"; import Button from "../button/Button"; type Props = { /** * A custom function to extend the session when the user * clicks to stay logged in. */ extendSession: () => any, /** * A callback to execute after the timer completes. Add all logout logic, * `sessionStorage` cleanup, etc. in this callback. */ onLogout: () => any, /** * The length of the session as the number of _seconds_ * or as a string (e.g. `30m`, `0.5h`, etc.) */ sessionLength: number | string, /** * The number of seconds before the logout that the dialog is shown. */ showDialogBeforeLogout: number | string, /** * The time the user logged into the web app. */ loginTime: number, }; const simpleConvert = (t: number | string): number => { if (typeof t === "string") { if (!/(0|\.)?\d+[smh]/.test(t)) { throw new Error("Malformed time string. Acceptable values are h, m, and s only!"); } let offset = 1000; const time = parseFloat(t.substring(0, t.length - 1)); if (time < 0) { throw new Error("Time cannot be negative"); } const duration = t.substring(t.length - 1, t.length); switch (duration) { case "s": break; case "m": offset *= 60; break; case "h": offset *= 3600; break; default: break; } return time * offset; } return t * 1000; }; export default class Timeout extends Component<Props, { closed: boolean }> { static propTypes = { extendSession: PropTypes.func.isRequired, onLogout: PropTypes.func.isRequired, sessionLength: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), showDialogBeforeLogout: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), loginTime: PropTypes.number, }; static defaultProps = { sessionLength: "30m", showDialogBeforeLogout: "1m", loginTime: window.sessionStorage.loginTime && window.sessionStorage.loginTime instanceof Date ? new Date(window.sessionStorage.loginTime).getTime() : window.sessionStorage.loginTime, }; state = { closed: true }; timeout = null; sessionLength = simpleConvert(this.props.sessionLength); showDialogBeforeLogout = simpleConvert(this.props.showDialogBeforeLogout); componentDidMount() { const showDialogTime = this.props.loginTime + this.sessionLength - this.showDialogBeforeLogout; this.timeout = setInterval(() => { if (this.timeout && new Date().getTime() >= showDialogTime) { clearInterval(this.timeout); this.timeout = null; this.setState({ closed: false }); } }, 1000); } componentWillUnmount() { if (this.timeout) { clearInterval(this.timeout); this.timeout = null; } } render() { return ( <Dialog onClose={this.props.extendSession} closed={this.state.closed}> <Dialog.Header title="Timeout" /> <Dialog.Content> <ReactCountdownClock seconds={this.showDialogBeforeLogout / 1000} color="#39F" size={175} alpha={0.75} fontSize="3rem" showMilliseconds={false} weight={8} onComplete={this.props.onLogout} /> </Dialog.Content> <Dialog.Footer> {(onClose) => <Button onClick={this.props.extendSession}>Stay Logged In</Button>} </Dialog.Footer> </Dialog> ); } }