diff --git a/api/src/services/contentMapper.service.ts b/api/src/services/contentMapper.service.ts index 8febbd8e..7534a193 100644 --- a/api/src/services/contentMapper.service.ts +++ b/api/src/services/contentMapper.service.ts @@ -292,19 +292,12 @@ const getExistingContentTypes = async (req: Request) => { headers, }) ); - - if (err) { - throw new Error( - `Error fetching selected content type: ${ - err.response?.data || err.message - }` - ); - } + selectedContentType = { - title: res.data.content_type?.title, - uid: res.data.content_type?.uid, - schema: res.data.content_type?.schema, + title: res?.data?.content_type?.title, + uid: res?.data?.content_type?.uid, + schema: res?.data?.content_type?.schema, }; } return { @@ -314,7 +307,7 @@ const getExistingContentTypes = async (req: Request) => { } catch (error: any) { return { data: error.message, - status: 500, + status: error.status || 500, }; } }; diff --git a/ui/src/components/ContentMapper/index.tsx b/ui/src/components/ContentMapper/index.tsx index 2e871c55..15c1fceb 100644 --- a/ui/src/components/ContentMapper/index.tsx +++ b/ui/src/components/ContentMapper/index.tsx @@ -266,12 +266,10 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R //Check for null if (!data) { dispatch(updateMigrationData({ contentMappingData: DEFAULT_CONTENT_MAPPING_DATA })); - setIsLoading(false); return; } dispatch(updateMigrationData({ contentMappingData: data})); - setIsLoading(false); }) .catch((err) => { console.error(err); @@ -455,6 +453,17 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R [key]: { label: `${item?.display_name} > ${schemaItem?.display_name}`, value: schemaItem }, })); } + else if(! item?.schema?.some( + (schema) => schema?.uid === existingField[key]?.value?.uid) ){ + + setExistingField((prevOptions: ExistingFieldType) => { + const { [key]: _, ...rest } = prevOptions; // Destructure to exclude the key to remove + return { + ...rest + }; + }); + + } }); } } @@ -541,6 +550,7 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R // Method to fetch content types const fetchContentTypes = async (searchText: string) => { try { + setIsLoading(true); const { data } = await getContentTypes(projectId || '', 0, 5000, searchContentType || ''); //org id will always present setContentTypes(data?.contentTypes); @@ -588,21 +598,19 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R setItemStatusMap(itemStatusMap); - setLoading(true); for (let index = 0; index <= 30; index++) { itemStatusMap[index] = 'loaded'; } setItemStatusMap({ ...itemStatusMap }); - setLoading(false); const newTableData = data?.fieldMapping?.filter((field: FieldMapType) => field !== null) setTableData(newTableData || []); setTotalCounts(data?.count); setInitialRowSelectedData(newTableData.filter((item: FieldMapType) => !item.isDeleted)) - + setIsLoading(false); generateSourceGroupSchema(data?.fieldMapping); } catch (error) { console.error('fetchData -> error', error); @@ -636,10 +644,10 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R } setItemStatusMap({ ...updateditemStatusMapCopy }); - setLoading(false); // eslint-disable-next-line no-unsafe-optional-chaining setTableData([...tableData, ...data?.fieldMapping ?? tableData]); setTotalCounts(data?.count); + setIsLoading(false) } catch (error) { console.log('loadMoreItems -> error', error); } @@ -1686,6 +1694,97 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R } }; + const handleCTDeleted = async(isContentType:boolean) => { + const updatedContentTypeMapping = Object.fromEntries( + Object.entries(newMigrationData?.content_mapping?.content_type_mapping || {}).filter( + ([key]) => !selectedContentType?.contentstackUid.includes(key) + ) + ); + + const orgId = selectedOrganisation?.value; + const projectID = projectId; + setIsDropDownChanged(false); + + const updatedRows: FieldMapType[] = tableData.map((row) => { + return { ...row, contentstackFieldType: row?.backupFieldType }; + }); + setTableData(updatedRows); + setSelectedEntries(updatedRows); + + const dataCs = { + contentTypeData: { + status: selectedContentType?.status, + id: selectedContentType?.id, + projectId:projectId, + otherCmsTitle: otherCmsTitle, + otherCmsUid: selectedContentType?.otherCmsUid, + isUpdated: true, + updateAt: new Date(), + contentstackTitle: selectedContentType?.contentstackTitle, + contentstackUid: selectedContentType?.contentstackUid, + fieldMapping: updatedRows + } + }; + let newstate = {} ; + setContentTypeMapped((prevState: ContentTypeMap) => { + const newState = { ...prevState }; + + delete newState[selectedContentType?.contentstackUid ?? '']; + newstate = newState; + + return newstate; + }); + + if (orgId && selectedContentType) { + try { + const { data, status } = await resetToInitialMapping( + orgId, + projectID, + selectedContentType?.id ?? '', + dataCs + ); + + setExistingField({}); + setContentTypeSchema([]); + setOtherContentType({ + label: `Select ${isContentType ? 'Content Type' : 'Global Field'} from Existing Stack`, + value: `Select ${isContentType ? 'Content Type' : 'Global Field'} from Existing Stack` + }); + + if (status === 200) { + const resetCT = filteredContentTypes?.map(ct => + ct?.id === selectedContentType?.id ? { ...ct, status: data?.data?.status } : ct + ); + setFilteredContentTypes(resetCT); + setContentTypes(resetCT); + + try { + await updateContentMapper(orgId, projectID, {...newstate} ); + } catch (err) { + console.log(err); + return err; + } + + } + } catch (error) { + console.log(error); + return error; + } + } + + const newMigrationDataObj : INewMigration = { + ...newMigrationData, + content_mapping:{ + ...newMigrationData?.content_mapping, + content_type_mapping : updatedContentTypeMapping + + } + + } + dispatch(updateNewMigrationData(newMigrationDataObj)); + + } + /** * Retrieves existing content types for a given project. * @returns An array containing the retrieved content types or global fields based on condition if itContentType true and if existing content type or global field id is passed then returns an object containing title, uid and schema of that particular content type or global field. @@ -1694,7 +1793,7 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R if (isContentType) { try { const { data , status} = await getExistingContentTypes(projectId, otherContentType?.id ?? ''); - if (status == 201 && data?.contentTypes?.length > 0) { + if (status == 201 && data?.contentTypes?.length > 0 && data?.selectedContentType) { (otherContentType?.id === data?.selectedContentType?.uid) && setsCsCTypeUpdated(false); (otherContentType?.id && otherContentType?.label !== data?.selectedContentType?.title) @@ -1725,6 +1824,8 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R setContentTypeSchema(data?.selectedContentType?.schema); } } else { + + await handleCTDeleted(isContentType); Notification({ notificationContent: { text: "No content found in the stack" }, notificationProps: { @@ -1742,7 +1843,7 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R try { const { data, status } = await getExistingGlobalFields(projectId, otherContentType?.id ?? ''); - if (status == 201 && data?.globalFields?.length > 0) { + if (status == 201 && data?.globalFields?.length > 0 && data?.selectedGlobalField) { (otherContentType?.id === data?.selectedGlobalField?.uid) && setsCsCTypeUpdated(false); (otherContentType?.id && otherContentType?.label !== data?.selectedGlobalField?.title) @@ -1772,6 +1873,9 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R type: 'success' }); } else { + + await handleCTDeleted(isContentType); + Notification({ notificationContent: { text: "No Global Fields found in the stack" }, notificationProps: { @@ -1789,7 +1893,7 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R const contentField = contentModels?.find((item: ContentTypeList)=>item?.title === otherContentType?.label); const contentFieldKey = Object.keys(contentTypeMapped).find(key => contentTypeMapped[key] === otherContentType?.label); - + if(! contentField && contentFieldKey) { const updatedState = { ...contentTypeMapped }; delete updatedState[contentFieldKey]; @@ -1855,7 +1959,7 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R isDisabled: (contentTypeMapped && Object.values(contentTypeMapped).includes(item?.uid)) }; }); - + const adjustedOption = options?.map((option) => ({ @@ -2161,7 +2265,7 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R testId="no-results-found-page" />} - + ); }); diff --git a/ui/src/components/Stepper/HorizontalStepper/HorizontalStepper.scss b/ui/src/components/Stepper/HorizontalStepper/HorizontalStepper.scss index 0e950ab6..ef135821 100644 --- a/ui/src/components/Stepper/HorizontalStepper/HorizontalStepper.scss +++ b/ui/src/components/Stepper/HorizontalStepper/HorizontalStepper.scss @@ -138,4 +138,12 @@ fill: $color-brand-white-base; } } +} +.stepper-loader{ + align-items: center; + display: flex; + flex-direction: column; + height: 100%; + justify-content: center; + width: 100%; } \ No newline at end of file diff --git a/ui/src/components/Stepper/HorizontalStepper/HorizontalStepper.tsx b/ui/src/components/Stepper/HorizontalStepper/HorizontalStepper.tsx index 7128821c..f838a844 100644 --- a/ui/src/components/Stepper/HorizontalStepper/HorizontalStepper.tsx +++ b/ui/src/components/Stepper/HorizontalStepper/HorizontalStepper.tsx @@ -2,7 +2,7 @@ import React, { useState, useImperativeHandle, forwardRef, useEffect } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; import './HorizontalStepper.scss'; -import { cbModal, Notification,Button } from '@contentstack/venus-components'; +import { cbModal, Notification,Button, CircularLoader } from '@contentstack/venus-components'; import { useSelector } from 'react-redux'; @@ -240,10 +240,15 @@ const HorizontalStepper = forwardRef(