diff --git a/client/src/components/LocationModal.js b/client/src/components/LocationModal.js index 526c15f..1e83bd4 100644 --- a/client/src/components/LocationModal.js +++ b/client/src/components/LocationModal.js @@ -1,6 +1,6 @@ // @flow -import React from 'react'; +import React, { useCallback } from 'react'; import { AssociatedDropdown } from '@performant-software/semantic-components'; import { withTranslation } from 'react-i18next'; import { Form, Modal } from 'semantic-ui-react'; @@ -30,125 +30,135 @@ const LocationTypes = { place: 2 }; -const LocationModal = (props: Props) => ( - - - - { props.type === LocationTypes.place && ( - - Places.save(place).then(({ data }) => data.place) - }} - onSearch={(search) => Places.fetchAll({ search, sort_by: 'name' })} - onSelection={props.onAssociationInputChange.bind(this, 'place_id', 'place')} - renderOption={Place.toDropdown.bind(this)} - searchQuery={props.item.place && props.item.place.name} - value={props.item.place_id || ''} - /> - - )} - { props.type === LocationTypes.artwork && ( - - Artworks.fetchAll({ search, sort_by: 'artwork_titles.title' })} - onSelection={props.onAssociationInputChange.bind(this, 'locateable_id', 'locateable')} - renderOption={Artwork.toDropdown.bind(this)} - searchQuery={( - props.item.locateable - && props.item.locateable.primary_title - && props.item.locateable.primary_title.title - )} - value={props.item.locateable_id || ''} - /> - - )} - { props.type === LocationTypes.person && ( - - People.save(person).then(({ data }) => data.person) - }} - onSearch={(search) => People.fetchAll({ search, sort_by: 'display_name' })} - onSelection={props.onAssociationInputChange.bind(this, 'locateable_id', 'locateable')} - renderOption={Person.toDropdown.bind(this)} - searchQuery={props.item.locateable && props.item.locateable.display_name} - value={props.item.locateable_id || ''} - /> - - )} - - - - - - { + /** + * Memo-izes the search function. + * + * @type {function(): function(*): *} + */ + const onSearch = useCallback(() => (search) => Places.fetchAll({ search, sort_by: 'name' }), []); + + return ( + + - - { props.children } - -); + + { props.type === LocationTypes.place && ( + + Places.save(place).then(({ data }) => data.place) + }} + onSearch={onSearch} + onSelection={props.onAssociationInputChange.bind(this, 'place_id', 'place')} + renderOption={Place.toDropdown.bind(this)} + searchQuery={props.item.place && props.item.place.name} + value={props.item.place_id || ''} + /> + + )} + { props.type === LocationTypes.artwork && ( + + Artworks.fetchAll({ search, sort_by: 'artwork_titles.title' })} + onSelection={props.onAssociationInputChange.bind(this, 'locateable_id', 'locateable')} + renderOption={Artwork.toDropdown.bind(this)} + searchQuery={( + props.item.locateable + && props.item.locateable.primary_title + && props.item.locateable.primary_title.title + )} + value={props.item.locateable_id || ''} + /> + + )} + { props.type === LocationTypes.person && ( + + People.save(person).then(({ data }) => data.person) + }} + onSearch={(search) => People.fetchAll({ search, sort_by: 'display_name' })} + onSelection={props.onAssociationInputChange.bind(this, 'locateable_id', 'locateable')} + renderOption={Person.toDropdown.bind(this)} + searchQuery={props.item.locateable && props.item.locateable.display_name} + value={props.item.locateable_id || ''} + /> + + )} + + + + + + + + { props.children } + + ); +}; export default withTranslation()(LocationModal); diff --git a/client/src/components/ParticipationModal.js b/client/src/components/ParticipationModal.js index 3354dcf..0302779 100644 --- a/client/src/components/ParticipationModal.js +++ b/client/src/components/ParticipationModal.js @@ -1,6 +1,6 @@ // @flow -import React from 'react'; +import React, { useCallback } from 'react'; import { AssociatedDropdown } from '@performant-software/semantic-components'; import { withTranslation } from 'react-i18next'; import { Form, Modal } from 'semantic-ui-react'; @@ -26,102 +26,108 @@ const ParticipationTypes = { person: 1 }; -const ParticipationModal = (props: Props) => ( - - - - { props.type === ParticipationTypes.person && ( - - People.save(person).then(({ data }) => data.person) - }} - onSearch={(search) => People.fetchAll({ - search, - sort_by: 'display_name', - per_page: 25 - })} - onSelection={props.onAssociationInputChange.bind(this, 'person_id', 'person')} - renderOption={Person.toDropdown.bind(this)} - searchQuery={props.item.person && props.item.person.display_name} - value={props.item.person_id || ''} - /> - - )} - { props.type === ParticipationTypes.artwork && ( - - Artworks.fetchAll({ search, sort_by: 'artwork_titles.title' })} - onSelection={props.onAssociationInputChange.bind(this, 'participateable_id', 'participateable')} - renderOption={Artwork.toDropdown.bind(this)} - searchQuery={( - props.item.participateable - && props.item.participateable.primary_title - && props.item.participateable.primary_title.title - )} - value={props.item.participateable_id || ''} - /> - - )} - - - - - { + /** + * Memo-izes the search function. + * + * @type {function(*): Promise>} + */ + const onSearch = useCallback((search) => People.fetchAll({ search, sort_by: 'display_name', per_page: 25 }), []); + + return ( + + - - { props.children } - -); + + { props.type === ParticipationTypes.person && ( + + People.save(person).then(({ data }) => data.person) + }} + onSearch={onSearch} + onSelection={props.onAssociationInputChange.bind(this, 'person_id', 'person')} + renderOption={Person.toDropdown.bind(this)} + searchQuery={props.item.person && props.item.person.display_name} + value={props.item.person_id || ''} + /> + + )} + { props.type === ParticipationTypes.artwork && ( + + Artworks.fetchAll({ search, sort_by: 'artwork_titles.title' })} + onSelection={props.onAssociationInputChange.bind(this, 'participateable_id', 'participateable')} + renderOption={Artwork.toDropdown.bind(this)} + searchQuery={( + props.item.participateable + && props.item.participateable.primary_title + && props.item.participateable.primary_title.title + )} + value={props.item.participateable_id || ''} + /> + + )} + + + + + + + { props.children } + + ); +}; export default withTranslation()(ParticipationModal);