1- import React , { useRef , useState } from "react" ;
1+ import React , { useEffect , useRef , useState } from "react" ;
22import { useTranslation } from "react-i18next" ;
33import DatePicker from "react-datepicker" ;
44import cn from "classnames" ;
5- import { getMetadataCollectionFieldName } from "../../../utils/resourceUtils" ;
5+ import { getMetadataCollectionFieldName , transformListProvider } from "../../../utils/resourceUtils" ;
66import { getCurrentLanguageInformation } from "../../../utils/utils" ;
77import DropDown from "../DropDown" ;
88import { parseISO } from "date-fns" ;
99import { FieldProps } from "formik" ;
1010import { MetadataField } from "../../../slices/eventSlice" ;
1111import { GroupBase , SelectInstance } from "react-select" ;
1212import TextareaAutosize from "react-textarea-autosize" ;
13+ import axios from "axios" ;
1314
1415/**
1516 * This component renders an editable field for single values depending on the type of the corresponding metadata
@@ -65,7 +66,7 @@ const RenderField = ({
6566) }
6667{ metadataField . type === "text" &&
6768! ! metadataField . collection &&
68- metadataField . collection . length > 0 && (
69+ (
6970< EditableSingleSelect
7071metadataField = { metadataField }
7172field = { field }
@@ -91,7 +92,7 @@ const RenderField = ({
9192) }
9293{ metadataField . type === "text" &&
9394! (
94- ! ! metadataField . collection && metadataField . collection . length !== 0
95+ metadataField . collection
9596) && (
9697< EditableSingleValue
9798field = { field }
@@ -195,16 +196,7 @@ const EditableDateValue = ({
195196} ;
196197
197198// renders editable field for selecting value via dropdown
198- const EditableSingleSelect = ( {
199- field,
200- metadataField,
201- text,
202- form : { setFieldValue } ,
203- isFirstField,
204- focused,
205- setFocused,
206- ref,
207- } : {
199+ type EditableSingleSelectProps = ( {
208200field : FieldProps [ "field" ]
209201metadataField : MetadataField
210202text : string
@@ -213,9 +205,25 @@ const EditableSingleSelect = ({
213205focused : boolean ,
214206setFocused : ( open : boolean ) => void
215207ref : React . RefObject < SelectInstance < any , boolean , GroupBase < any > > >
216- } ) => {
208+ } )
209+ const EditableSingleSelect = ( props : EditableSingleSelectProps ) => {
217210const { t } = useTranslation ( ) ;
218211
212+ const {
213+ field,
214+ metadataField,
215+ text,
216+ form : { setFieldValue } ,
217+ isFirstField,
218+ focused,
219+ setFocused,
220+ ref,
221+ } = props ;
222+
223+ if ( metadataField . id === "isPartOf" ) {
224+ return < EditableSingleSelectSeries { ...props } /> ;
225+ }
226+
219227return (
220228< DropDown
221229ref = { ref }
@@ -321,4 +329,67 @@ const EditableSingleValueTime = ({
321329) ;
322330} ;
323331
332+ /**
333+ * Special case for series. Uses an async selector to fetch options.
334+ *
335+ * Ideally we could generalize this for all metadata fields with listproviders,
336+ * but other listproviders do not offer the required filtering capabilities.
337+ */
338+ const EditableSingleSelectSeries = ( {
339+ field,
340+ metadataField,
341+ text,
342+ form : { setFieldValue } ,
343+ isFirstField,
344+ focused,
345+ setFocused,
346+ ref,
347+ } : EditableSingleSelectProps ) => {
348+ const { t } = useTranslation ( ) ;
349+
350+ const [ label , setLabel ] = useState ( "" ) ;
351+
352+ useEffect ( ( ) => {
353+ // The metadata catalog only contains the field value, so we need to fetch the label ourselves
354+ const fetchLabelById = async ( ) => {
355+ if ( field . value ) {
356+ const res = await axios . get < { [ key : string ] : string } > ( `/admin-ng/resources/SERIES.WRITE_ONLY.json?limit=1&filter=textFilter:${ field . value } ` ) ;
357+ const data = res . data ;
358+ const transformedData = transformListProvider ( data ) ;
359+ if ( transformedData . length > 0 ) {
360+ setLabel ( transformedData [ 0 ] . label ) ;
361+ }
362+ }
363+ } ;
364+ fetchLabelById ( ) ;
365+ } , [ field . value ] ) ;
366+
367+ // Fetch collection
368+ const fetchOptions = async ( inputValue : string ) => {
369+ const res = await axios . get < { [ key : string ] : string } > ( `/admin-ng/resources/SERIES.WRITE_ONLY.json?filter=textFilter:${ inputValue } ` ) ;
370+ const data = res . data ;
371+ return transformListProvider ( data ) ;
372+ } ;
373+
374+ return (
375+ < DropDown
376+ ref = { ref }
377+ value = { field . value as string }
378+ text = { label }
379+ fetchOptions = { fetchOptions }
380+ required = { metadataField . required }
381+ handleChange = { element => element && setFieldValue ( field . name , element . value ) }
382+ placeholder = { focused
383+ ? `-- ${ t ( "SELECT_NO_OPTION_SELECTED" ) } --`
384+ : `${ t ( "SELECT_NO_OPTION_SELECTED" ) } `
385+ }
386+ customCSS = { { isMetadataStyle : focused ? false : true } }
387+ handleMenuIsOpen = { ( open : boolean ) => setFocused ( open ) }
388+ openMenuOnFocus
389+ autoFocus = { isFirstField }
390+ skipTranslate = { ! metadataField . translatable }
391+ />
392+ ) ;
393+ } ;
394+
324395export default RenderField ;
0 commit comments