UNPKG

passbolt-styleguide

Version:

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

249 lines (232 loc) 8.93 kB
/** * Passbolt ~ Open source password manager for teams * Copyright (c) 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) Passbolt SA (https://www.passbolt.com) * @license https://opensource.org/licenses/AGPL-3.0 AGPL License * @link https://www.passbolt.com Passbolt(tm) * @since 5.2.0 */ import React, { Component, Fragment } from "react"; import PropTypes from "prop-types"; import { Trans, withTranslation } from "react-i18next"; import { withResourceTypesLocalStorage } from "../../../../shared/context/ResourceTypesLocalStorageContext/ResourceTypesLocalStorageContext"; import AttentionSVG from "../../../../img/svg/attention.svg"; import DeleteSVG from "../../../../img/svg/delete.svg"; import AddSVG from "../../../../img/svg/add.svg"; const URIS_LIMIT = 20; class AddResourceUris extends Component { constructor(props) { super(props); this.bindCallbacks(); } /** * Get the translation function * @returns {function(...[*]=)} */ get translate() { return this.props.t; } /** * Bind callbacks */ bindCallbacks() { this.handleInputChange = this.handleInputChange.bind(this); this.handleAddUriClick = this.handleAddUriClick.bind(this); this.handleDeleteUriClick = this.handleDeleteUriClick.bind(this); } /** * Handle form input change. * @params {ReactEvent} The react event. */ handleInputChange(event) { if (this.props.onChange) { this.props.onChange(event); } } /** * Handle the click on the add uri button */ handleAddUriClick() { const eventUri = { target: { name: `metadata.uris.${this.props.resource.metadata.uris.length}`, value: "", }, }; this.props.onChange?.(eventUri); } /** * Handle the click on the delete uri button * @param {number} index The index of the uri to delete */ handleDeleteUriClick(index) { const eventUri = { target: { name: `metadata.uris.${index}`, value: null, }, }; this.props.onChange?.(eventUri); } /** * Additional uris * @returns {Array<string>} */ get additionalUris() { return this.props.resource.metadata.uris.slice(1); } /** * Has multiple uris * @returns {boolean} */ get hasMultipleUris() { return this.props.resource?.metadata?.uris?.length > 0; } /** * Can add uri * @returns {boolean} */ get canAddUri() { const lastUri = this.props.resource?.metadata?.uris?.[this.props.resource.metadata.uris.length - 1]; return lastUri?.length > 0 && this.props.resource.metadata.uris.length < URIS_LIMIT; } /** * Checks if there is a max length warning for a specific property. * * @param {string} propName - The name of the property to check for max length warnings. * @returns {boolean} - Returns true if there is a max length warning for the property, false otherwise. */ isMaxLengthWarnings(propName, association) { return !this.isMaxLengthError(propName) && this.props.warnings?.hasError(`${association}.${propName}`, "maxLength"); } /** * Checks if there is a max length error for a specific property. * * @param {string} propName - The name of the property to check for max length errors. * @returns {boolean} - Returns true if there is a max length error for the property, false otherwise. */ isMaxLengthError(propName) { const segments = propName.split("."); const propArrayName = segments[0]; const propsArrayIndex = segments[1]; return this.props.errors?.details?.metadata?.details?.[propArrayName]?.[propsArrayIndex]?.maxLength; } /* * ============================================================= * Render view * ============================================================= */ render() { return ( <> <div className="title"> <h2> <Trans>URIs</Trans> </h2> </div> <div className="content"> <div className="uris-fields"> <div className={`input text ${this.props.disabled ? "disabled" : ""}`}> <label htmlFor="resource-main-uri"> <Trans>Main URI</Trans> {this.isMaxLengthWarnings("uris.0", "metadata") && <AttentionSVG className="attention-required" />} </label> <input id="resource-main-uri" disabled={this.props.disabled} name="metadata.uris.0" maxLength="1024" type="text" autoComplete="off" placeholder={this.translate("URI")} value={this.props.resource?.metadata?.uris?.[0]} onChange={this.handleInputChange} /> {this.isMaxLengthError("uris.0") && ( <div className="main-uri error-message"> <Trans>This is the maximum size for this field, make sure your data was not truncated.</Trans> </div> )} {this.isMaxLengthWarnings("uris.0", "metadata") && ( <div className="main-uri warning-message"> <strong> <Trans>Warning:</Trans> </strong>{" "} <Trans>this is the maximum size for this field, make sure your data was not truncated.</Trans> </div> )} </div> <div className={`input text ${this.props.disabled ? "disabled" : ""}`}> <label htmlFor={`resource-additional-uri-${this.hasMultipleUris ? this.additionalUris.length : ""}`}> <Trans>Additional URI</Trans> {this.isMaxLengthWarnings("uris", "metadata") && <AttentionSVG className="attention-required" />} </label> {this.hasMultipleUris && this.additionalUris.map((uri, index) => ( <> <div key={index} className="additional-uri-wrapper"> <input id={`resource-additional-uri-${index + 1}`} autoFocus={index + 1 === this.additionalUris.length} disabled={this.props.disabled} name={`metadata.uris.${index + 1}`} maxLength="1024" type="text" autoComplete="off" placeholder={this.translate("URI")} value={this.props.resource.metadata.uris[index + 1]} onChange={this.handleInputChange} /> <button type="button" className="button-icon" id={`resource-delete-additional-uri-${index + 1}`} onClick={() => this.handleDeleteUriClick(index + 1)} > <DeleteSVG /> </button> </div> {this.isMaxLengthError(`uris.${index + 1}`) && ( <div className={`additional-uri-${index + 1} error-message`}> <Trans>This is the maximum size for this field, make sure your data was not truncated.</Trans> </div> )} {this.isMaxLengthWarnings(`uris.${index + 1}`, "metadata") && ( <div className={`additional-uri-${index + 1} warning-message`}> <strong> <Trans>Warning:</Trans> </strong>{" "} <Trans>this is the maximum size for this field, make sure your data was not truncated.</Trans> </div> )} </> ))} </div> <div className="uri-add"> <button type="button" disabled={!this.canAddUri} onClick={this.handleAddUriClick}> <AddSVG /> <span> <Trans>Add URI</Trans> </span> </button> </div> </div> </div> </> ); } } AddResourceUris.propTypes = { resource: PropTypes.object, // The resource to edit or create onChange: PropTypes.func, //The resource setter t: PropTypes.func, // The translation function warnings: PropTypes.object, //The warnings validation errors: PropTypes.object, // The errors entity error validation disabled: PropTypes.bool, // The disabled property }; export default withResourceTypesLocalStorage(withTranslation("common")(AddResourceUris));