UNPKG

passbolt-styleguide

Version:

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

143 lines (132 loc) 4.56 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 3.0.0 */ import React, { Component } from "react"; import PropTypes from "prop-types"; import { Trans, withTranslation } from "react-i18next"; import { withAppContext } from "../../../../shared/context/AppContext/AppContext"; import CaretDownSVG from "../../../../img/svg/caret_down.svg"; import CaretRightSVG from "../../../../img/svg/caret_right.svg"; class DisplayUnexpectedError extends Component { /** * Constructor * @param {Object} props */ constructor(props) { super(props); this.state = this.defaultState; this.bindCallbacks(); } /** * Returns the component default state */ get defaultState() { return { showErrorDetails: false, // Display flag of the error details area }; } /** * Bind the component handlers */ bindCallbacks() { this.handleErrorDetailsToggle = this.handleErrorDetailsToggle.bind(this); } /** * Whenever the user click on the action */ onClick() { if (this.props.context.port) { // A reload from iframe cannot reload the parent due to cross origin so the extension will do this.props.context.port.request("passbolt.tab.reload"); } else { window.location.reload(); } } /** * Handle the toggle display of error details */ handleErrorDetailsToggle() { this.setState({ showErrorDetails: !this.state.showErrorDetails }); } /** * Does the provided error carry details. * @returns {boolean} */ get hasErrorDetails() { const error = this.props?.error; return Boolean(error?.details) || Boolean(error?.data?.body); } /** * Format the error details as a string. * @returns {string} */ formatErrors() { const errorMessage = this.props.error?.details || this.props.error?.data; return JSON.stringify(errorMessage, null, 4); } /** * Render the component * @returns {JSX} */ render() { return ( <div className="setup-error"> <h1>{this.props.title}</h1> <p>{this.props.message}</p> <p>{this.props.error && this.props.error.message}</p> {this.hasErrorDetails && ( <div className="accordion error-details"> <div className="accordion-header"> <button className="no-border" type="button" onClick={this.handleErrorDetailsToggle}> {this.state.showErrorDetails ? ( <CaretDownSVG className="caret-down" /> ) : ( <CaretRightSVG className="caret-right" /> )} <span> <Trans>Error details</Trans> </span> </button> </div> {this.state.showErrorDetails && ( <div className="accordion-content"> <div className="input text"> <label htmlFor="js_field_debug" className="visuallyhidden"> <Trans>Error details</Trans> </label> <textarea id="js_field_debug" defaultValue={`${this.formatErrors()}`} readOnly /> </div> </div> )} </div> )} <div className="form-actions"> <button onClick={this.onClick.bind(this)} className="button primary big full-width" role="button"> <Trans>Try again</Trans> </button> </div> </div> ); } } DisplayUnexpectedError.defaultProps = { title: <Trans>Something went wrong!</Trans>, message: <Trans>The operation failed with the following error:</Trans>, }; DisplayUnexpectedError.propTypes = { context: PropTypes.any, // The application context title: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node, PropTypes.string]), message: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node, PropTypes.string]), error: PropTypes.any, // The error to display }; export default withAppContext(withTranslation("common")(DisplayUnexpectedError));