UNPKG

passbolt-styleguide

Version:

Passbolt styleguide contains common styling assets used by the different sites, plugin, etc.

206 lines (188 loc) 5.79 kB
/** * Passbolt ~ Open source password manager for teams * Copyright (c) 2020 Passbolt SA (https://www.passbolt.com) * * Licensed under GNU Affero General Public License version 3 of the or any later version. * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * * @copyright Copyright (c) 2020 Passbolt SA (https://www.passbolt.com) * @license https://opensource.org/licenses/AGPL-3.0 AGPL License * @link https://www.passbolt.com Passbolt(tm) * @since 2.12.0 */ import React, { Component } from "react"; import { withProgress } from "../../../../contexts/ProgressContext"; import { Trans, withTranslation } from "react-i18next"; import PropTypes from "prop-types"; import SpinnerSVG from "../../../../../img/svg/spinner.svg"; class DisplayProgress extends Component { /** * Default constructor * @param props Component props */ constructor(props) { super(props); this.infiniteTimerUpdateIntervalId = null; // The infinite timer update interval ID this.state = this.defaultState; } /** * Returns the component default state * @return {object} */ get defaultState() { return { infiniteTimer: 0, // The timer for the infinite calculation, used only if infinite progress mode. }; } /** * Component did mount */ componentDidMount() { this.startInfiniteTimerUpdateProgress(); } /** * Start the infinite timer update. * @return {void} */ startInfiniteTimerUpdateProgress() { if (!this.isInfiniteProgressMode()) { return; } this.infiniteTimerUpdateIntervalId = setInterval(() => { this.setState({ infiniteTimer: this.state.infiniteTimer + 2 }); }, 500); } /** * Component did update * @return {void} */ componentDidUpdate() { if (!this.isInfiniteProgressMode() && this.infiniteTimerUpdateIntervalId) { this.resetInterval(); } } /** * Component will unmount */ componentWillUnmount() { this.resetInterval(); } /** * Check if the component should display an infinite progress bar. * @returns {boolean} */ isInfiniteProgressMode() { return !this.props.progressContext.progressDialogProps?.goals; } /** * Reset interval */ resetInterval() { if (this.infiniteTimerUpdateIntervalId) { clearInterval(this.infiniteTimerUpdateIntervalId); this.infiniteTimerUpdateIntervalId = null; } } /** * Calculate the progress * @return {number} */ calculateProgress() { if (this.props.progressContext.progressDialogProps?.goals > 0) { return this.calculateGoalsProgress(); } else { return this.calculateInfiniteProgress(); } } /** * Calculate the infinite progress * @return {number} */ calculateInfiniteProgress() { return 100 - 100 / Math.pow(1.1, this.state.infiniteTimer); } /** * Calculate the progress based on the goals * @return {number} */ calculateGoalsProgress() { const completed = this.props.progressContext.progressDialogProps?.completed || 0; let progress = Math.round((100 * completed) / this.props.progressContext.progressDialogProps?.goals); if (progress > 100) { progress = 100; } return progress; } /** * Decode html characters * @param {string} text with html encoded characters * @return {string} */ decodedHtmlCharacters(text) { if (text) { try { const doc = new DOMParser().parseFromString(text, "text/html"); return doc.documentElement.textContent; } catch (error) { console.error(error); } } return text; } /** * Render * @returns {JSX.Element} */ render() { const progress = this.calculateProgress(); const progressBarStyle = { width: `${progress}%` }; return ( <div className="dialog-wrapper progress-dialog"> <div className="dialog"> <div className="dialog-header"> <span className="dialog-title-wrapper"> <h2> {this.decodedHtmlCharacters(this.props.progressContext.progressDialogProps?.title) || ( <Trans>Please wait...</Trans> )} </h2> </span> </div> <div className="dialog-content"> <div className="form-content"> <label> <Trans>Take a deep breath and enjoy being in the present moment...</Trans> </label> <div className="progress-bar-wrapper"> <span className="progress-bar"> <span className={`progress ${progress === 100 ? "completed" : ""}`} style={progressBarStyle} /> </span> {!this.isInfiniteProgressMode() && ( <div className="progress-details"> <span className="progress-step-label"> {this.decodedHtmlCharacters(this.props.progressContext.progressDialogProps?.message) || ( <Trans>Please wait...</Trans> )} </span> <span className="progress-percent">{progress}%</span> </div> )} </div> </div> <div className="submit-wrapper clearfix"> <button type="submit" className="disabled processing"> Submit <SpinnerSVG /> </button> </div> </div> </div> </div> ); } } DisplayProgress.propTypes = { progressContext: PropTypes.any, // The progress context }; export default withProgress(withTranslation("common")(DisplayProgress));