Skip to content

Commit

Permalink
Merge pull request #559 from NASA-IMPACT/feature/multiple-contact-rev…
Browse files Browse the repository at this point in the history
…iewers

Feature/multiple-contact-reviewers
  • Loading branch information
wrynearson authored Oct 13, 2023
2 parents 331a14d + 2f68fba commit d5c62f8
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 180 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ const roleTypes = [
'Supervision',
'Investigation',
'Funding acquisition',
'Corresponding Author'
'Corresponding Author',
'Document Reviewer'
];

const emptyAffiliation = '';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
import React, { useCallback, useEffect } from 'react';
import T from 'prop-types';
import set from 'lodash.set';
import get from 'lodash.get';
import { FieldArray, Formik, Form as FormikForm } from 'formik';
import { Formik, Form as FormikForm } from 'formik';
import { Form } from '@devseed-ui/form';
import { GlobalLoading } from '@devseed-ui/global-loading';
import { glsp } from '@devseed-ui/theme-provider';
import styled from 'styled-components';

import { Inpage, InpageBody } from '../../../../styles/inpage';
import {
FormBlock,
FormBlockHeading,
FormSectionNotes
} from '../../../../styles/form-block';
import {
FormikSectionFieldset,
SectionFieldset
} from '../../../common/forms/section-fieldset';
import { FormikSectionFieldset } from '../../../common/forms/section-fieldset';
import ContactsList from './contacts-list';
import { Link } from '../../../../styles/clean/link';

Expand All @@ -29,17 +23,6 @@ import { getDocumentSectionLabel } from '../sections';
import { documentEdit } from '../../../../utils/url-creator';
import { LocalStore } from '../local-store';
import { FormikUnloadPrompt } from '../../../common/unload-prompt';
import { FormikInputText } from '../../../common/forms/input-text';
import { DeletableFieldset } from '../../../common/forms/deletable-fieldset';
import { FieldMultiItem } from '../../../common/forms/field-multi-item';

const emptyAffiliation = '';

const BasicInfoSection = styled.div`
display: grid;
grid-gap: ${glsp()};
grid-template-columns: 1fr 1fr;
`;

export default function StepContacts(props) {
const { renderInpageHeader, renderFormFooter, atbd, id, version, step } =
Expand Down Expand Up @@ -148,58 +131,6 @@ export default function StepContacts(props) {
</FormSectionNotes>
<ContactsList contactsList={contacts.data} />
</FormikSectionFieldset>
<SectionFieldset
label={getDocumentSectionLabel('reviewer_info')}
>
<BasicInfoSection>
<FormikInputText
id='reviewer_info.first_name'
name='reviewer_info.first_name'
label='First name'
/>
<FormikInputText
id='reviewer_info.last_name'
name='reviewer_info.last_name'
label='Last name'
/>
<FormikInputText
id='reviewer_info.email'
name='reviewer_info.email'
label='Email'
/>
</BasicInfoSection>
<FieldArray
name='reviewer_info.affiliations'
render={({ remove, push, form, name: affFieldName }) => {
const fieldValues = get(form.values, affFieldName) || [];
return (
<FieldMultiItem
id={affFieldName}
label='Affiliations relevant to this document'
emptyMessage='There are no affiliations. You can start by adding one.'
onAddClick={() => push(emptyAffiliation)}
>
{fieldValues.map((field, index) => (
<DeletableFieldset
/* eslint-disable-next-line react/no-array-index-key */
key={index}
id={`${affFieldName}-${index}`}
label={`Entry #${index + 1}`}
onDeleteClick={() => remove(index)}
>
<FormikInputText
id={`${affFieldName}-${index}`}
name={`${affFieldName}.${index}`}
label='Name'
labelHint='(required)'
/>
</DeletableFieldset>
))}
</FieldMultiItem>
);
}}
/>
</SectionFieldset>
{renderFormFooter()}
</Form>
</FormBlock>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ const STEP_CONTACTS = {
// affiliations: []
// }
],
reviewer_info: atbd?.reviewer_info,
sections_completed: {
contacts: 'incomplete'
}
Expand Down
200 changes: 93 additions & 107 deletions app/assets/scripts/components/documents/single-view/document-body.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ import { useCommentCenter } from '../../../context/comment-center';
import { isJournalPublicationIntended } from '../status';
import serializeSlateToString from '../../slate/serialize-to-string';
import { useContextualAbility } from '../../../a11n';
import { isDefined, isTruthyString } from '../../../utils/common';
import { formatDocumentTableCaptions } from '../../../utils/format-table-captions';
import { sortContacts } from '../../../utils/sort-contacts';

const PDFPreview = styled.iframe`
width: 100%;
Expand Down Expand Up @@ -1051,82 +1051,87 @@ const htmlAtbdContentSections = [
),
children: ({ atbd }) => {
const contactsLink = atbd?.contacts_link || [];
return contactsLink.map(({ contact, roles, affiliations }, idx) => ({
label: getContactName(contact),
id: `contacts_${idx + 1}`,
render: ({ element }) => (
<ContactItem
key={element.id}
id={element.id}
label={element.label}
contact={contact}
roles={roles}
affiliations={affiliations}
/>
return contactsLink
.filter(
({ roles }) =>
// Remove reviewers that have the role 'Document Reviewer'
!roles.includes('Document Reviewer')
)
}));
.sort(sortContacts)
.map(({ contact, roles, affiliations }, idx) => ({
label: getContactName(contact),
id: `contacts_${idx + 1}`,
render: ({ element }) => (
<ContactItem
key={element.id}
id={element.id}
label={element.label}
contact={contact}
roles={roles}
affiliations={affiliations}
/>
)
}));
}
},
{
label: 'Reviewer Information',
id: 'reviewer_info',
shouldRender: ({ atbd }) => {
if (!atbd || !atbd.reviewer_info) {
return false;
}
if (!atbd) return false;

const {
reviewer_info: { first_name, last_name }
} = atbd;
// Render if there are reviewers with the role 'Document Reviewer'
const contactsLink = atbd?.contacts_link || [];

if (!isTruthyString(first_name) && !isTruthyString(last_name)) {
return false;
for (const { roles } of contactsLink) {
if (roles.includes('Document Reviewer')) {
return true;
}
}

return true;
return false;
},
render: ({ element, atbd, printMode }) => {
if (!atbd || !atbd.reviewer_info) {
return null;
}

const {
reviewer_info: { first_name, last_name, email, affiliations }
} = atbd;

let fullName;
if (isTruthyString(first_name) || isTruthyString(last_name)) {
fullName = [first_name, last_name].filter(isDefined).join(' ');
}

if (!isTruthyString(fullName) && !isTruthyString(email)) {
render: ({ element, atbd, printMode, children }) => {
if (!atbd) {
return null;
}

return (
<AtbdSection
key={element.id}
id={element.id}
title={element.label}
atbd={atbd}
printMode={printMode}
className='pdf-preview-hidden'
>
<AtbdSubSection>
<h3>{fullName}</h3>
<DetailsList type='horizontal'>
<dt>Email</dt>
<dd>{email}</dd>
<dt>Affiliations</dt>
{affiliations.length ? (
<dd>{renderMultipleStringValues(affiliations)}</dd>
) : (
<dd>No affiliations for the reviewer</dd>
)}
</DetailsList>
</AtbdSubSection>
{React.Children.count(children) ? (
children
) : (
<p>There are no reviewers associated with this document</p>
)}
</AtbdSection>
);
},
children: ({ atbd }) => {
const contactsLink = atbd?.contacts_link || [];
return contactsLink
.filter(({ roles }) =>
// Include reviewers that have the role 'Document Reviewer'
roles.includes('Document Reviewer')
)
.sort(sortContacts)
.map(({ contact, roles, affiliations }, idx) => ({
label: getContactName(contact),
id: `contacts_${idx + 1}`,
render: ({ element }) => (
<ContactItem
key={element.id}
id={element.id}
label={element.label}
contact={contact}
roles={roles}
affiliations={affiliations}
/>
)
}));
}
},
{
Expand Down Expand Up @@ -1268,80 +1273,61 @@ const pdfAtbdContentSections = [
),
children: ({ atbd }) => {
const contactsLink = atbd?.contacts_link || [];
return contactsLink.map(({ contact, roles, affiliations }, idx) => ({
label: getContactName(contact),
id: `contacts_${idx + 1}`,
render: ({ element }) => (
<ContactItem
key={element.id}
id={element.id}
label={element.label}
contact={contact}
roles={roles}
affiliations={affiliations}
/>
return contactsLink
.filter(
({ roles }) =>
// Remove reviewers that have the role 'Document Reviewer'
!roles.includes('Document Reviewer')
)
}));
.map(({ contact, roles, affiliations }, idx) => ({
label: getContactName(contact),
id: `contacts_${idx + 1}`,
render: ({ element }) => (
<ContactItem
key={element.id}
id={element.id}
label={element.label}
contact={contact}
roles={roles}
affiliations={affiliations}
/>
)
}));
}
},
{
label: 'Reviewer Information',
id: 'reviewer_info',
shouldRender: ({ atbd }) => {
if (!atbd || !atbd.reviewer_info) {
return false;
}
if (!atbd) return false;

const {
reviewer_info: { first_name, last_name }
} = atbd;
// Render if there are reviewers with the role 'Document Reviewer'
const contactsLink = atbd?.contacts_link || [];

if (!isTruthyString(first_name) && !isTruthyString(last_name)) {
return false;
for (const { roles } of contactsLink) {
if (roles.includes('Document Reviewer')) {
return true;
}
}

return true;
return false;
},
render: ({ element, atbd, printMode }) => {
if (!atbd || !atbd.reviewer_info) {
render: ({ element, atbd, printMode, children }) => {
if (!atbd) {
return null;
}

const {
reviewer_info: { first_name, last_name, email, affiliations }
} = atbd;

let fullName;
if (isTruthyString(first_name) || isTruthyString(last_name)) {
fullName = [first_name, last_name].filter(isDefined).join(' ');
}

if (!isTruthyString(fullName) && !isTruthyString(email)) {
return null;
}

return (
<AtbdSection
key={element.id}
id={element.id}
title={element.label}
atbd={atbd}
printMode={printMode}
className='pdf-preview-hidden'
>
<AtbdSubSection>
<h3>{fullName}</h3>
<DetailsList type='horizontal'>
<dt>Email</dt>
<dd>{email}</dd>
<dt>Affiliations</dt>
{affiliations.length ? (
<dd>{renderMultipleStringValues(affiliations)}</dd>
) : (
<dd>No affiliations for the reviewer</dd>
)}
</DetailsList>
</AtbdSubSection>
{React.Children.count(children) ? (
children
) : (
<p>There are no reviewers associated with this document</p>
)}
</AtbdSection>
);
}
Expand Down
Loading

0 comments on commit d5c62f8

Please sign in to comment.