From 0c5bdffbbcec46a05ec1bf4142f8f71357b260b5 Mon Sep 17 00:00:00 2001 From: Monkey Do Date: Wed, 10 Jun 2020 20:47:18 +0200 Subject: [PATCH] feat(author-credit): Add validation of author credits --- .../author-credit-editor/author-credit-row.js | 9 ++++++++- .../author-credit-section.js | 15 ++++++++++++--- src/client/entity-editor/validators/base.js | 2 +- src/client/entity-editor/validators/common.js | 16 ++++++++++++++-- src/client/entity-editor/validators/edition.js | 2 ++ 5 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/client/entity-editor/author-credit-editor/author-credit-row.js b/src/client/entity-editor/author-credit-editor/author-credit-row.js index 25eddf2db2..4122c53212 100644 --- a/src/client/entity-editor/author-credit-editor/author-credit-row.js +++ b/src/client/entity-editor/author-credit-editor/author-credit-row.js @@ -19,10 +19,15 @@ // @flow import { - type Action, type Author, removeAuthorCreditRow, updateCreditAuthorValue, updateCreditDisplayValue, + type Action, + type Author, + removeAuthorCreditRow, + updateCreditAuthorValue, + updateCreditDisplayValue, updateCreditJoinPhraseValue } from './actions'; import {Button, Col, Row} from 'react-bootstrap'; + import CustomInput from '../../input'; import EntitySearchFieldOption from '../common/entity-search-field-option'; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; @@ -89,6 +94,7 @@ function AuthorCreditRow({ instanceId={`author${index}`} label="Author" type="author" + validationState={!author ? 'error' : null} value={author} onChange={onAuthorChange} /> @@ -98,6 +104,7 @@ function AuthorCreditRow({ id={`authorDisplayName${index}`} label="Author as credited" type="text" + validationState={!name.length ? 'error' : null} value={name} onChange={onNameChange} /> diff --git a/src/client/entity-editor/author-credit-editor/author-credit-section.js b/src/client/entity-editor/author-credit-editor/author-credit-section.js index c160d9fb79..1a97055b83 100644 --- a/src/client/entity-editor/author-credit-editor/author-credit-section.js +++ b/src/client/entity-editor/author-credit-editor/author-credit-section.js @@ -33,8 +33,10 @@ import type {Dispatch} from 'redux'; // eslint-disable-line import/named import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; import PropTypes from 'prop-types'; import React from 'react'; +import ValidationLabel from '../common/validation-label'; import {connect} from 'react-redux'; import {convertMapToObject} from '../../helpers/utils'; +import {validateAuthorCreditSection} from '../validators/common'; type OwnProps = { @@ -66,13 +68,20 @@ function AuthorCreditSection({ } const authorCreditPreview = _map(authorCredit, (credit) => `${credit.name}${credit.joinPhrase}`).join(''); const noAuthorCredit = _keys(authorCredit).length <= 0; + const isValid = validateAuthorCreditSection(authorCredit); const editButton = ( ); + const label = ( + + Author Credit + + ); + return ( {editor} @@ -80,10 +89,10 @@ function AuthorCreditSection({ diff --git a/src/client/entity-editor/validators/base.js b/src/client/entity-editor/validators/base.js index d6db3d1b8a..7e5edd78f6 100644 --- a/src/client/entity-editor/validators/base.js +++ b/src/client/entity-editor/validators/base.js @@ -38,7 +38,7 @@ export function get( export function getIn( object: any, - path: string, + path: string | string[], defaultValue: ?mixed = null ): mixed { if (Iterable.isIterable(object)) { diff --git a/src/client/entity-editor/validators/common.js b/src/client/entity-editor/validators/common.js index 4a8030c7d7..6431cb2ea6 100644 --- a/src/client/entity-editor/validators/common.js +++ b/src/client/entity-editor/validators/common.js @@ -20,15 +20,16 @@ import { get, + getIn, validateOptionalString, validatePositiveInteger, - validateRequiredString + validateRequiredString, + validateUUID } from './base'; import {Iterable} from 'immutable'; import _ from 'lodash'; - export function validateMultiple( values: any[], validationFunction: (value: any, ...rest: any[]) => boolean, @@ -172,3 +173,14 @@ export function validateSubmissionSection( validateSubmissionSectionNote(get(data, 'note', null)) ); } + +export function validateAuthorCreditRow(row: any): boolean { + return validateUUID(getIn(row, ['author', 'id'], null), true) && + validateRequiredString(get(row, 'name', null)) && + validateOptionalString(get(row, 'joinPhrase', null)); +} + +export const validateAuthorCreditSection = _.partial( + validateMultiple, _.partial.placeholder, + validateAuthorCreditRow, _.partial.placeholder +); diff --git a/src/client/entity-editor/validators/edition.js b/src/client/entity-editor/validators/edition.js index 2d9e7f6c15..20d35db54f 100644 --- a/src/client/entity-editor/validators/edition.js +++ b/src/client/entity-editor/validators/edition.js @@ -21,6 +21,7 @@ import {get, validateDate, validatePositiveInteger, validateUUID} from './base'; import { validateAliases, + validateAuthorCreditSection, validateIdentifiers, validateNameSection, validateSubmissionSection @@ -125,6 +126,7 @@ export function validateForm( ), validateNameSection(get(formData, 'nameSection', {})), validateEditionSection(get(formData, 'editionSection', {})), + validateAuthorCreditSection(get(formData, 'authorCreditEditor', {})), validateSubmissionSection(get(formData, 'submissionSection', {})) ];