From 25b77adaa0cefdbb9b8869f88b86dfa6b80b9946 Mon Sep 17 00:00:00 2001 From: Arnei Date: Thu, 22 Jan 2026 16:33:58 +0100 Subject: [PATCH] Put metadata in its own formik field in event/series create dialog Instead of putting the metadata field directly alongside other values in formik, put them in their field. This makes our code more explicit and allows us to avoid overly general typescript typings. --- .../ModalTabsAndPages/NewMetadataPage.tsx | 4 ++-- .../events/partials/wizards/NewEventSummary.tsx | 8 ++++---- .../events/partials/wizards/NewEventWizard.tsx | 17 ++++++----------- .../partials/wizards/NewSeriesSummary.tsx | 6 +++--- .../events/partials/wizards/NewSeriesWizard.tsx | 6 +++--- src/configs/modalConfig.ts | 7 +++++-- src/slices/eventSlice.ts | 14 +++++++------- src/slices/seriesSlice.ts | 6 +++--- src/utils/validate.ts | 5 ++++- 9 files changed, 37 insertions(+), 36 deletions(-) diff --git a/src/components/events/partials/ModalTabsAndPages/NewMetadataPage.tsx b/src/components/events/partials/ModalTabsAndPages/NewMetadataPage.tsx index 064bea4495..fbe3467f8e 100644 --- a/src/components/events/partials/ModalTabsAndPages/NewMetadataPage.tsx +++ b/src/components/events/partials/ModalTabsAndPages/NewMetadataPage.tsx @@ -57,13 +57,13 @@ const NewMetadataPage = ({ {field.type === "mixed_text" && field.collection?.length !== 0 ? ( ) : ( ({ @@ -75,7 +75,7 @@ const NewEventSummary = ({ value: File, }[] = []; for (let i = 0; uploadAssetOptions.length > i; i++) { - const fieldValue = formik.values[uploadAssetOptions[i].id] as File; + const fieldValue = formik.values.metadata[uploadAssetOptions[i].id] as File; if (fieldValue) { const displayOverride = uploadAssetOptions[i].displayOverride as ParseKeys; setUploadAssetsNonTrack(uploadAssetsNonTrack.concat({ @@ -104,7 +104,7 @@ const NewEventSummary = ({ @@ -113,7 +113,7 @@ const NewEventSummary = ({ )} diff --git a/src/components/events/partials/wizards/NewEventWizard.tsx b/src/components/events/partials/wizards/NewEventWizard.tsx index 98c9bc3173..c4c8af6be9 100644 --- a/src/components/events/partials/wizards/NewEventWizard.tsx +++ b/src/components/events/partials/wizards/NewEventWizard.tsx @@ -269,15 +269,15 @@ const getInitialValues = ( aclDefaultActions?: string[], aclDefaultTemplate?: AclTemplate, ) => { - let initialValues = initialFormValuesNewEvents; + const initialValues = initialFormValuesNewEvents; // Transform metadata fields provided by backend (saved in redux) - initialValues = { ...initialValues, ...getInitialMetadataFieldValues( + initialValues.metadata = { ...initialValues.metadata, ...getInitialMetadataFieldValues( metadataFields, ) }; for (const catalog of extendedMetadata) { - initialValues = { ...initialValues, ...getInitialMetadataFieldValues( + initialValues.metadata = { ...initialValues.metadata, ...getInitialMetadataFieldValues( catalog, ) }; } @@ -290,17 +290,17 @@ const getInitialValues = ( // Transform additional metadata for source (provided by constant in newEventConfig) if (sourceMetadata.UPLOAD) { sourceMetadata.UPLOAD.metadata.forEach(field => { - initialValues[field.id] = field.value; + initialValues.metadata[field.id] = field.value; }); } if (sourceMetadata.SCHEDULE_SINGLE) { sourceMetadata.SCHEDULE_SINGLE.metadata.forEach(field => { - initialValues[field.id] = field.value; + initialValues.metadata[field.id] = field.value; }); } if (sourceMetadata.SCHEDULE_MULTIPLE) { sourceMetadata.SCHEDULE_MULTIPLE.metadata.forEach(field => { - initialValues[field.id] = field.value; + initialValues.metadata[field.id] = field.value; }); } @@ -318,11 +318,6 @@ const getInitialValues = ( }; } - // Add all initial form values known upfront listed in newEventsConfig - for (const [key, value] of Object.entries(initialFormValuesNewEvents)) { - initialValues[key] = value; - } - const defaultDate = new Date(); // fill times with some default values diff --git a/src/components/events/partials/wizards/NewSeriesSummary.tsx b/src/components/events/partials/wizards/NewSeriesSummary.tsx index a785d63805..1c940eb4df 100644 --- a/src/components/events/partials/wizards/NewSeriesSummary.tsx +++ b/src/components/events/partials/wizards/NewSeriesSummary.tsx @@ -20,6 +20,7 @@ interface RequiredFormProps { theme: string, policies: TransformedAcl[], selectedPage?: TobiraPage, + metadata: { [key: string]: unknown } } const NewSeriesSummary = ({ @@ -47,7 +48,7 @@ const NewSeriesSummary = ({ @@ -56,8 +57,7 @@ const NewSeriesSummary = ({ ) : null} diff --git a/src/components/events/partials/wizards/NewSeriesWizard.tsx b/src/components/events/partials/wizards/NewSeriesWizard.tsx index 67a6e131f7..1879fe6071 100644 --- a/src/components/events/partials/wizards/NewSeriesWizard.tsx +++ b/src/components/events/partials/wizards/NewSeriesWizard.tsx @@ -142,7 +142,7 @@ const NewSeriesWizard = ({ const handleSubmit = ( values: { - [key: string]: any; + metadata: { [key: string]: unknown } policies: TransformedAcl[]; theme: string; }, @@ -247,7 +247,7 @@ const getInitialValues = ( aclDefaultActions: string[], aclDefaultTemplate?: AclTemplate, ) => { - let initialValues = initialFormValuesNewSeries; + const initialValues = initialFormValuesNewSeries; // Transform metadata fields provided by backend (saved in redux) let metadataInitialValues = getInitialMetadataFieldValues( @@ -260,7 +260,7 @@ const getInitialValues = ( ) }; } - initialValues = { ...initialValues, ...metadataInitialValues }; + initialValues.metadata = { ...initialValues, ...metadataInitialValues }; initialValues["policies"] = [ { diff --git a/src/configs/modalConfig.ts b/src/configs/modalConfig.ts index d31ae4a1bd..b1c9cf6ed9 100644 --- a/src/configs/modalConfig.ts +++ b/src/configs/modalConfig.ts @@ -34,7 +34,7 @@ export const initialFormValuesNewEvents: { aclTemplate: string, policies: TransformedAcl[], uploadAssetsTrack?: UploadAssetsTrack[] - [key: string]: unknown, // Metadata fields that are getting added later + metadata: { [key: string]: unknown } } = { sourceMode: "UPLOAD", scheduleStartDate: new Date().toISOString(), @@ -52,6 +52,7 @@ export const initialFormValuesNewEvents: { configuration: {}, aclTemplate: "", policies: [], + metadata: {}, }; // constants for hours and minutes (used in selection for start/end time and duration) @@ -104,7 +105,8 @@ export const initialFormValuesNewSeries: { breadcrumbs: TobiraPage[], selectedPage?: TobiraPage, - [key: string]: unknown, // Metadata fields that are getting added later + aclTemplate?: string, + metadata: { [key: string]: unknown } } = { policies: [ { @@ -117,6 +119,7 @@ export const initialFormValuesNewSeries: { theme: "", breadcrumbs: [], selectedPage: undefined, + metadata: {}, }; // All fields for new theme form that are fix and not depending on response of backend diff --git a/src/slices/eventSlice.ts b/src/slices/eventSlice.ts index baa4a318bc..c9dea803a8 100644 --- a/src/slices/eventSlice.ts +++ b/src/slices/eventSlice.ts @@ -450,7 +450,7 @@ export const postNewEvent = (params: { scheduleStartMinute: string, sourceMode: string, uploadAssetsTrack?: UploadAssetsTrack[], - [key: string]: unknown, + metadata: { [key: string]: unknown }, }, metadataInfo: MetadataCatalog, extendedMetadata: MetadataCatalog[], @@ -477,11 +477,11 @@ export const postNewEvent = (params: { // prepare metadata provided by user const metadata = prepareMetadataFieldsForPost( [metadataInfo], - values, + values.metadata, ); const extendedMetadataCatalogs = prepareMetadataFieldsForPost( extendedMetadata, - values, + values.metadata, ); // if source mode is UPLOAD than also put metadata fields of that in metadataFields @@ -494,7 +494,7 @@ export const postNewEvent = (params: { for (const smetadata of sourceMetadata.UPLOAD.metadata) { metadata[0].fields = metadata[0].fields.concat({ id: smetadata.id, - value: values[smetadata.id], + value: values.metadata[smetadata.id], type: smetadata.type, }); } @@ -542,7 +542,7 @@ export const postNewEvent = (params: { type: values.sourceMode, metadata: { start: startDate, - device: values.location, + device: values.metadata.location, inputs: values.inputs ? values.inputs.join(",") : "", end: endDate, duration: duration.toString(), @@ -596,12 +596,12 @@ export const postNewEvent = (params: { } for (let i = 0; uploadAssetOptions.length > i; i++) { if ( - !!values[uploadAssetOptions[i].id] && + !!values.metadata[uploadAssetOptions[i].id] && values.sourceMode === "UPLOAD" ) { formData.append( uploadAssetOptions[i].id + ".0", - values[uploadAssetOptions[i].id] as File, + values.metadata[uploadAssetOptions[i].id] as File, ); assets.options = assets.options.concat(uploadAssetOptions[i]); } diff --git a/src/slices/seriesSlice.ts b/src/slices/seriesSlice.ts index aaeeb5b544..9d5725c624 100644 --- a/src/slices/seriesSlice.ts +++ b/src/slices/seriesSlice.ts @@ -184,7 +184,6 @@ export const fetchSeriesThemes = createAppAsyncThunk("series/fetchSeriesThemes", // post new series to backend export const postNewSeries = (params: { values: { - [key: string]: any; policies: TransformedAcl[], // contributor: string[], // creator: string[], @@ -198,6 +197,7 @@ export const postNewSeries = (params: { // title: string, selectedPage?: TobiraPage, breadcrumbs?: TobiraPage[], + metadata: { [key: string]: unknown } }, metadataInfo: MetadataCatalog, extendedMetadata: MetadataCatalog[] @@ -207,11 +207,11 @@ export const postNewSeries = (params: { // prepare metadata provided by user const metadata = prepareMetadataFieldsForPost( [metadataInfo], - values, + values.metadata, ); const extendedMetadataCatalogs = prepareMetadataFieldsForPost( extendedMetadata, - values, + values.metadata, ); // metadata for post request diff --git a/src/utils/validate.ts b/src/utils/validate.ts index 15ce8cbdf6..9ef13471b9 100644 --- a/src/utils/validate.ts +++ b/src/utils/validate.ts @@ -68,7 +68,10 @@ export const MetadataSchema = (catalog: MetadataCatalog) => { for (const [key, value] of Object.entries(schema)) { schemaKeyReplace[catalog.flavor + "_" + key] = value; } - const validateSchema = Yup.object().shape(schemaKeyReplace); + + const validateSchema = Yup.object({ + metadata: Yup.object(schemaKeyReplace), + }); return validateSchema; };