From 2405c2c40a6377a2169b63d3b5e786ccee3a27e2 Mon Sep 17 00:00:00 2001 From: umeshmore45 Date: Wed, 9 Oct 2024 19:25:16 +0530 Subject: [PATCH 01/16] intial code --- ui/src/pages/Migration/index.tsx | 255 ++++++++++++----------- ui/src/services/api/migration.service.ts | 9 + 2 files changed, 140 insertions(+), 124 deletions(-) diff --git a/ui/src/pages/Migration/index.tsx b/ui/src/pages/Migration/index.tsx index e1d46747..ee78ee11 100644 --- a/ui/src/pages/Migration/index.tsx +++ b/ui/src/pages/Migration/index.tsx @@ -6,10 +6,10 @@ import { cbModal, Notification } from '@contentstack/venus-components'; // Redux files import { RootState } from '../../store'; -import { updateMigrationData, updateNewMigrationData } from '../../store/slice/migrationDataSlice'; +import { updateMigrationData, updateNewMigrationData } from '../../store/slice/migrationDataSlice'; // Services -import { getMigrationData, updateCurrentStepData, updateLegacyCMSData, updateDestinationStack, updateAffixData, fileformatConfirmation, updateFileFormatData, affixConfirmation, updateStackDetails, getExistingContentTypes, getExistingGlobalFields } from '../../services/api/migration.service'; +import { getMigrationData, updateCurrentStepData, updateLegacyCMSData, updateDestinationStack, updateAffixData, fileformatConfirmation, updateFileFormatData, affixConfirmation, updateStackDetails, getExistingContentTypes, getExistingGlobalFields, startMigration } from '../../services/api/migration.service'; import { getCMSDataFromFile } from '../../cmsData/cmsSelector'; // Utilities @@ -59,9 +59,9 @@ const Migration = () => { const stepperRef = useRef(null); const legacyCMSRef = useRef(null); - const selectedOrganisation = useSelector((state: RootState)=>state?.authentication?.selectedOrganisation); - const newMigrationData = useSelector((state:RootState)=> state?.migration?.newMigrationData); - const organisationsList = useSelector((state:RootState)=>state?.authentication?.organisationsList); + const selectedOrganisation = useSelector((state: RootState) => state?.authentication?.selectedOrganisation); + const newMigrationData = useSelector((state: RootState) => state?.migration?.newMigrationData); + const organisationsList = useSelector((state: RootState) => state?.authentication?.organisationsList); const saveRef = useRef(null); @@ -69,17 +69,17 @@ const Migration = () => { fetchData(); }, [params?.stepId, params?.projectId, selectedOrganisation?.value]); - useEffect(()=> { + useEffect(() => { dispatch(updateNewMigrationData({ ...newMigrationData, - isprojectMapped : isProjectMapper - + isprojectMapped: isProjectMapper + })); - - },[isProjectMapper]); - // Function to get exisiting content types list - const fetchExistingContentTypes = async () => { + }, [isProjectMapper]); + + // Function to get exisiting content types list + const fetchExistingContentTypes = async () => { const { data, status } = await getExistingContentTypes(projectId); if (status === 201) { return data?.contentTypes; @@ -121,7 +121,7 @@ const Migration = () => { migration_steps_heading: data?.migration_steps_heading, settings: data?.settings })); - + await fetchProjectData(); const stepIndex = data?.all_steps?.findIndex((step: IFlowStep) => `${step?.name}` === params?.stepId); setCurrentStepIndex(stepIndex !== -1 ? stepIndex : 0); @@ -129,60 +129,60 @@ const Migration = () => { //Fetch project data const fetchProjectData = async () => { - if (isEmptyString(selectedOrganisation?.value) || isEmptyString(params?.projectId)) return; + if (isEmptyString(selectedOrganisation?.value) || isEmptyString(params?.projectId)) return; - const data = await getMigrationData(selectedOrganisation?.value, params?.projectId || ''); - if (data) { - setIsLoading(false); - setProjectData(data?.data); - } - setIsProjectMapper(true); - const projectData = data?.data; + const data = await getMigrationData(selectedOrganisation?.value, params?.projectId || ''); + if (data) { + setIsLoading(false); + setProjectData(data?.data); + } + setIsProjectMapper(true); + const projectData = data?.data; - const legacyCmsData:ILegacyCMSComponent = await getCMSDataFromFile(CS_ENTRIES.LEGACY_CMS); + const legacyCmsData: ILegacyCMSComponent = await getCMSDataFromFile(CS_ENTRIES.LEGACY_CMS); - const selectedCmsData: ICMSType = validateArray(legacyCmsData?.all_cms) - ? legacyCmsData?.all_cms?.find((cms: ICMSType) => cms?.cms_id === projectData?.legacy_cms?.cms) ?? DEFAULT_CMS_TYPE - : DEFAULT_CMS_TYPE; + const selectedCmsData: ICMSType = validateArray(legacyCmsData?.all_cms) + ? legacyCmsData?.all_cms?.find((cms: ICMSType) => cms?.cms_id === projectData?.legacy_cms?.cms) ?? DEFAULT_CMS_TYPE + : DEFAULT_CMS_TYPE; - const selectedFileFormatData: ICardType | undefined = validateArray( - selectedCmsData?.allowed_file_formats - ) - ? selectedCmsData.allowed_file_formats?.find( + const selectedFileFormatData: ICardType | undefined = validateArray( + selectedCmsData?.allowed_file_formats + ) + ? selectedCmsData.allowed_file_formats?.find( (cms: ICardType) => cms?.fileformat_id === projectData?.legacy_cms?.file_format ) - : defaultCardType; - - - const selectedOrganisationData = validateArray(organisationsList) - ? organisationsList?.find((org: IDropDown) => org?.value === projectData?.org_id) - : selectedOrganisation; - - let selectedStackData: IDropDown = { - value: projectData?.destination_stack_id, - label: '', - master_locale: '', - locales: [], - created_at: '', - isNewStack: false - }; - - selectedStackData = { - label: projectData?.stackDetails?.label, - value: projectData?.stackDetails?.value, - master_locale: projectData?.stackDetails?. master_locale, - created_at: projectData?.stackDetails?.created_at, - locales:[], - isNewStack: projectData?.stackDetails?.isNewStack - }; + : defaultCardType; + + + const selectedOrganisationData = validateArray(organisationsList) + ? organisationsList?.find((org: IDropDown) => org?.value === projectData?.org_id) + : selectedOrganisation; + + let selectedStackData: IDropDown = { + value: projectData?.destination_stack_id, + label: '', + master_locale: '', + locales: [], + created_at: '', + isNewStack: false + }; - const existingContentTypes = await fetchExistingContentTypes(); - const existingGlobalFields = await fetchExistingGlobalFields(); - - const stackLink = `${CS_URL[projectData?.region]}/stack/${projectData?.current_test_stack_id}/dashboard`; - - const projectMapper = { - ...newMigrationData, + selectedStackData = { + label: projectData?.stackDetails?.label, + value: projectData?.stackDetails?.value, + master_locale: projectData?.stackDetails?.master_locale, + created_at: projectData?.stackDetails?.created_at, + locales: [], + isNewStack: projectData?.stackDetails?.isNewStack + }; + + const existingContentTypes = await fetchExistingContentTypes(); + const existingGlobalFields = await fetchExistingGlobalFields(); + + const stackLink = `${CS_URL[projectData?.region]}/stack/${projectData?.current_test_stack_id}/dashboard`; + + const projectMapper = { + ...newMigrationData, legacy_cms: { ...newMigrationData?.legacy_cms, selectedCms: selectedCmsData, @@ -200,7 +200,7 @@ const Migration = () => { }, isValidated: projectData?.legacy_cms?.is_fileValid }, - isFileFormatCheckboxChecked: true, + isFileFormatCheckboxChecked: true, isRestictedKeywordCheckboxChecked: true, projectStatus: projectData?.status, currentStep: -1, @@ -208,7 +208,7 @@ const Migration = () => { destination_stack: { selectedOrg: selectedOrganisationData, selectedStack: selectedStackData, - stackArray:[] + stackArray: [] }, content_mapping: { isDropDownChanged: false, @@ -231,58 +231,58 @@ const Migration = () => { }; - const createStepper = (projectData: MigrationResponse,handleStepChange: (currentStep: number) => void) => { + const createStepper = (projectData: MigrationResponse, handleStepChange: (currentStep: number) => void) => { const steps = [ { data: , - id:'1', - title:'Legacy CMS' + ref={legacyCMSRef} + legacyCMSData={projectData?.legacy_cms} + handleStepChange={handleStepChange} + isCompleted={isCompleted} + handleOnAllStepsComplete={handleOnAllStepsComplete} />, + id: '1', + title: 'Legacy CMS' }, { data: , - id:'2', - title:'Destination Stack' + destination_stack={projectData?.destination_stack_id} + org_id={projectData?.org_id} + projectData={projectData} + handleStepChange={handleStepChange} + isCompleted={isCompleted} + handleOnAllStepsComplete={handleOnAllStepsComplete} />, + id: '2', + title: 'Destination Stack' }, { data: , - id:'3', - title:'Content Mapping' + id: '3', + title: 'Content Mapping' }, { data: , - id:'4', - title:'Test Migration' + id: '4', + title: 'Test Migration' }, { data: , - id:'5', - title:'Migration Execution' + id: '5', + title: 'Migration Execution' } - ] - return steps; + ] + return steps; } const handleClick = () => { // Call handleStepChange function - const x : string | undefined= params.stepId - const currentStep : number = parseInt(x || ''); - stepperRef?.current?.handleStepChange(currentStep-1); + const x: string | undefined = params.stepId + const currentStep: number = parseInt(x || ''); + stepperRef?.current?.handleStepChange(currentStep - 1); }; - const handleStepChange = (currentStep: number) => { + const handleStepChange = (currentStep: number) => { if (stepperRef?.current) { - stepperRef.current.handleStepChange(currentStep-1); + stepperRef.current.handleStepChange(currentStep - 1); } }; @@ -292,7 +292,7 @@ const Migration = () => { }; // handle on proceed to destination stack - const handleOnClickLegacyCms = async (event: MouseEvent ) => { + const handleOnClickLegacyCms = async (event: MouseEvent) => { setIsLoading(true); if (isCompleted) { @@ -305,17 +305,17 @@ const Migration = () => { await updateAffixData(selectedOrganisation?.value, projectId, { affix: newMigrationData?.legacy_cms?.affix }); await fileformatConfirmation(selectedOrganisation?.value, projectId, { fileformat_confirmation: true - }); + }); await affixConfirmation(selectedOrganisation?.value, projectId, { affix_confirmation: true }); await updateFileFormatData(selectedOrganisation?.value, projectId, { - file_format: newMigrationData?.legacy_cms?.selectedCms?.allowed_file_formats[0]?.fileformat_id?.toString() , + file_format: newMigrationData?.legacy_cms?.selectedCms?.allowed_file_formats[0]?.fileformat_id?.toString(), file_path: newMigrationData?.legacy_cms?.uploadedFile?.file_details?.localPath, is_fileValid: newMigrationData?.legacy_cms?.uploadedFile?.isValidated, is_localPath: newMigrationData?.legacy_cms?.uploadedFile?.file_details?.isLocalPath, - awsDetails:{ + awsDetails: { awsRegion: newMigrationData?.legacy_cms?.uploadedFile?.file_details?.awsData?.awsRegion, bucketName: newMigrationData?.legacy_cms?.uploadedFile?.file_details?.awsData?.bucketName, buketKey: newMigrationData?.legacy_cms?.uploadedFile?.file_details?.awsData?.buketKey @@ -334,9 +334,9 @@ const Migration = () => { setIsLoading(false); if (legacyCMSRef?.current) { - const currentIndex = legacyCMSRef?.current?.getInternalActiveStepIndex() + 1; + const currentIndex = legacyCMSRef?.current?.getInternalActiveStepIndex() + 1; let result; - switch (currentIndex ) { + switch (currentIndex) { case 0: result = 'CMS'; break; @@ -356,25 +356,25 @@ const Migration = () => { } } - + }; // handle on proceed to content mapping const handleOnClickDestinationStack = async (event: MouseEvent) => { setIsLoading(true); - if(isCompleted && !isEmptyString(newMigrationData?.destination_stack?.selectedStack?.value)){ + if (isCompleted && !isEmptyString(newMigrationData?.destination_stack?.selectedStack?.value)) { event?.preventDefault(); //Update Data in backend await updateDestinationStack(selectedOrganisation?.value, projectId, { stack_api_key: newMigrationData?.destination_stack?.selectedStack?.value }); - await updateStackDetails(selectedOrganisation?.value, projectId,{ - label:newMigrationData?.destination_stack?.selectedStack?.label, - value:newMigrationData?.destination_stack?.selectedStack?.value, - master_locale:newMigrationData?.destination_stack?.selectedStack?.master_locale, - created_at:newMigrationData?.destination_stack?.selectedStack?.created_at, + await updateStackDetails(selectedOrganisation?.value, projectId, { + label: newMigrationData?.destination_stack?.selectedStack?.label, + value: newMigrationData?.destination_stack?.selectedStack?.value, + master_locale: newMigrationData?.destination_stack?.selectedStack?.master_locale, + created_at: newMigrationData?.destination_stack?.selectedStack?.created_at, isNewStack: newMigrationData?.destination_stack?.selectedStack?.isNewStack }) handleStepChange(2); @@ -384,7 +384,7 @@ const Migration = () => { const url = `/projects/${projectId}/migration/steps/3`; navigate(url, { replace: true }); } - } else{ + } else { setIsLoading(false); Notification({ notificationContent: { text: 'Please select a stack to proceed further' }, @@ -396,32 +396,32 @@ const Migration = () => { const handleOnClickContentMapper = async (event: MouseEvent) => { setIsModalOpen(true); - if(newMigrationData?.content_mapping?.isDropDownChanged) { + if (newMigrationData?.content_mapping?.isDropDownChanged) { return cbModal({ component: (props: ModalObj) => ( - { - const url = `/projects/${projectId}/migration/steps/4`; - navigate(url, { replace: true }); - - await updateCurrentStepData(selectedOrganisation.value, projectId); - handleStepChange(3); - }} + const url = `/projects/${projectId}/migration/steps/4`; + navigate(url, { replace: true }); + + await updateCurrentStepData(selectedOrganisation.value, projectId); + handleStepChange(3); + }} dropdownStateChange={changeDropdownState} - /> + /> ), modalProps: { - size: 'xsmall', - shouldCloseOnOverlayClick: false + size: 'xsmall', + shouldCloseOnOverlayClick: false } - }); + }); } - else{ + else { event.preventDefault(); const url = `/projects/${projectId}/migration/steps/4`; navigate(url, { replace: true }); @@ -442,7 +442,7 @@ const Migration = () => { handleStepChange(4); } - const changeDropdownState = () =>{ + const changeDropdownState = () => { const newMigrationDataObj: INewMigration = { ...newMigrationData, content_mapping: { ...newMigrationData?.content_mapping, isDropDownChanged: false } @@ -451,17 +451,24 @@ const Migration = () => { dispatch(updateNewMigrationData((newMigrationDataObj))); } + const handleOnClickExecutionMigration = async () => { + setIsLoading(false); + + await startMigration(selectedOrganisation.value, projectId) + } + const handleOnClickFunctions = [ - handleOnClickLegacyCms, + handleOnClickLegacyCms, handleOnClickDestinationStack, handleOnClickContentMapper, - handleOnClickTestMigration + handleOnClickTestMigration, + handleOnClickExecutionMigration ]; - + return (
- {projectData && - + {projectData && + }
diff --git a/ui/src/services/api/migration.service.ts b/ui/src/services/api/migration.service.ts index f13ee155..ea164008 100644 --- a/ui/src/services/api/migration.service.ts +++ b/ui/src/services/api/migration.service.ts @@ -311,4 +311,13 @@ export const createTestMigration = async (orgId: string, projectId: string) => { } catch (error) { return error; } +}; + +export const startMigration = async (orgId: string, projectId: string) => { + try { + return await postCall( + `${API_VERSION}/migration/start/${orgId}/${projectId}`, {}, options); + } catch (error) { + return error; + } }; \ No newline at end of file From 600178824b752f221cb0142ad18883d3f58e3ee6 Mon Sep 17 00:00:00 2001 From: umeshmore45 Date: Fri, 11 Oct 2024 15:14:47 +0530 Subject: [PATCH 02/16] intial code --- api/src/services/sitecore.service.ts | 147 ++++++++++++++----- api/src/utils/content-type-creator.utils.ts | 18 +++ api/src/utils/entries-field-creator.utils.ts | 2 +- 3 files changed, 129 insertions(+), 38 deletions(-) diff --git a/api/src/services/sitecore.service.ts b/api/src/services/sitecore.service.ts index 4fe9fa45..0a36e98d 100644 --- a/api/src/services/sitecore.service.ts +++ b/api/src/services/sitecore.service.ts @@ -6,6 +6,9 @@ import _ from 'lodash'; import { LOCALE_MAPPER } from '../constants/index.js'; import { entriesFieldCreator, unflatten } from '../utils/entries-field-creator.utils.js'; import { orgService } from './org.service.js'; +import { getLogMessage } from '../utils/index.js'; +import logger from '../utils/logger.js'; + const append = "a"; @@ -78,6 +81,7 @@ const uidCorrector = ({ uid }: any) => { } const cretaeAssets = async ({ packagePath, baseDir }: any) => { + const srcFunc = 'cretaeAssets'; const assetsSave = path.join(baseDir, 'assets'); const allAssetJSON: any = {}; const folderName: any = path.join(packagePath, 'items', 'master', 'sitecore', 'media library'); @@ -121,6 +125,14 @@ const cretaeAssets = async ({ packagePath, baseDir }: any) => { , assets) } catch (err) { console.error("🚀 ~ file: assets.js:52 ~ xml_folder?.forEach ~ err:", err) + logger.error( + getLogMessage( + srcFunc, + `Not able to read the asset"${jsonAsset?.item?.$?.name}(${mestaData?.uid})".`, + {}, + err + ) + ) } allAssetJSON[mestaData?.uid] = { urlPath: `/assets/${mestaData?.uid}`, @@ -135,9 +147,22 @@ const cretaeAssets = async ({ packagePath, baseDir }: any) => { publish_details: [], assetPath } + logger.info( + getLogMessage( + srcFunc, + `Asset "${jsonAsset?.item?.$?.name}" has been successfully transformed.`, + {} + ) + ) allAssetJSON[mestaData?.uid].parent_uid = '2146b0cee522cc3a38d' } else { - console.info('blob is not there for this asstes', mestaData?.uid, '.') + logger.error( + getLogMessage( + srcFunc, + `Asset "${jsonAsset?.item?.$?.name}" blob is not there for this asstes.`, + {} + ) + ) } } } @@ -164,6 +189,7 @@ const cretaeAssets = async ({ packagePath, baseDir }: any) => { const createEntry = async ({ packagePath, contentTypes, master_locale = 'en-us', destinationStackId }: { packagePath: any; contentTypes: any; master_locale?: string, destinationStackId: string }) => { try { + const srcFunc = 'createEntry'; const baseDir = path.join('sitecoreMigrationData', destinationStackId); const entrySave = path.join(baseDir, 'entries'); const allAssetJSON: any = await cretaeAssets({ packagePath, baseDir }); @@ -192,6 +218,13 @@ const createEntry = async ({ packagePath, contentTypes, master_locale = 'en-us', } } for await (const ctType of contentTypes) { + logger.info( + getLogMessage( + srcFunc, + `Transforming entries of Content Type ${ctType?.contentstackUid} has begun.`, + {} + ) + ) const entryPresent: any = entriesData?.find((item: any) => uidCorrector({ uid: item?.template }) === ctType?.contentstackUid) if (entryPresent) { const locales: any = Object?.keys(entryPresent?.locale); @@ -221,6 +254,13 @@ const createEntry = async ({ packagePath, contentTypes, master_locale = 'en-us', } if (Object.keys?.(entryObj)?.length > 1) { entryLocale[uid] = unflatten(entryObj) ?? {}; + logger.info( + getLogMessage( + srcFunc, + `Entry title "${entryObj?.title}"(${ctType?.contentstackUid}) in the ${newLocale} locale has been successfully transformed.`, + {} + ) + ) } }); } @@ -234,6 +274,13 @@ const createEntry = async ({ packagePath, contentTypes, master_locale = 'en-us', await writeFiles(entryPath, fileMeta, entryLocale, newLocale) } } else { + logger.error( + getLogMessage( + srcFunc, + `No entries found for the content type ${ctType?.contentstackUid}.`, + {} + ) + ) console.info('Entries missing for', ctType?.contentstackUid) } } @@ -244,45 +291,71 @@ const createEntry = async ({ packagePath, contentTypes, master_locale = 'en-us', } const createLocale = async (req: any, destinationStackId: string) => { - const baseDir = path.join('sitecoreMigrationData', destinationStackId); - const localeSave = path.join(baseDir, 'locale'); - const allLocalesResp = await orgService.getLocales(req) - const masterLocale = Object?.keys?.(LOCALE_MAPPER?.masterLocale)?.[0]; - const msLocale: any = {}; - const uid = uuidv4(); - msLocale[uid] = { - "code": masterLocale, - "fallback_locale": null, - "uid": uid, - "name": allLocalesResp?.data?.locales?.[masterLocale] ?? '' - } - const allLocales: any = {}; - for (const [key, value] of Object.entries(LOCALE_MAPPER)) { - const localeUid = uuidv4(); - if (key !== 'masterLocale' && typeof value === 'string') { - allLocales[localeUid] = { - "code": value, - "fallback_locale": masterLocale, - "uid": localeUid, - "name": allLocalesResp?.data?.locales?.[value] ?? '' - } + const srcFunc = 'createLocale'; + try { + const baseDir = path.join('sitecoreMigrationData', destinationStackId); + const localeSave = path.join(baseDir, 'locale'); + const allLocalesResp = await orgService.getLocales(req) + const masterLocale = Object?.keys?.(LOCALE_MAPPER?.masterLocale)?.[0]; + const msLocale: any = {}; + const uid = uuidv4(); + msLocale[uid] = { + "code": masterLocale, + "fallback_locale": null, + "uid": uid, + "name": allLocalesResp?.data?.locales?.[masterLocale] ?? '' } - } - const masterPath = path.join(localeSave, 'master-locale.json'); - const allLocalePath = path.join(localeSave, 'locales.json'); - fs.access(localeSave, async (err) => { - if (err) { - fs.mkdir(localeSave, { recursive: true }, async (err) => { - if (!err) { - await writeOneFile(masterPath, msLocale); - await writeOneFile(allLocalePath, allLocales); + logger.info( + getLogMessage( + srcFunc, + `Master locale ${masterLocale} has been successfully transformed.`, + {} + ) + ) + const allLocales: any = {}; + for (const [key, value] of Object.entries(LOCALE_MAPPER)) { + const localeUid = uuidv4(); + if (key !== 'masterLocale' && typeof value === 'string') { + allLocales[localeUid] = { + "code": value, + "fallback_locale": masterLocale, + "uid": localeUid, + "name": allLocalesResp?.data?.locales?.[value] ?? '' } - }) - } else { - await writeOneFile(masterPath, msLocale); - await writeOneFile(allLocalePath, allLocales); + logger.info( + getLogMessage( + srcFunc, + `locale ${value} has been successfully transformed.`, + {} + ) + ) + } } - }) + const masterPath = path.join(localeSave, 'master-locale.json'); + const allLocalePath = path.join(localeSave, 'locales.json'); + fs.access(localeSave, async (err) => { + if (err) { + fs.mkdir(localeSave, { recursive: true }, async (err) => { + if (!err) { + await writeOneFile(masterPath, msLocale); + await writeOneFile(allLocalePath, allLocales); + } + }) + } else { + await writeOneFile(masterPath, msLocale); + await writeOneFile(allLocalePath, allLocales); + } + }) + } catch (err) { + logger.error( + getLogMessage( + srcFunc, + `error while Createing the locales.`, + {}, + err + ) + ) + } } const createVersionFile = async (destinationStackId: string) => { diff --git a/api/src/utils/content-type-creator.utils.ts b/api/src/utils/content-type-creator.utils.ts index 1e0ffce4..d76c3432 100644 --- a/api/src/utils/content-type-creator.utils.ts +++ b/api/src/utils/content-type-creator.utils.ts @@ -1,5 +1,8 @@ import fs from 'fs'; import path from 'path'; +import logger from './logger.js'; +import { getLogMessage } from './index.js'; + interface Group { data_type: string; display_name?: string; // Assuming item?.contentstackField might be undefined @@ -406,6 +409,7 @@ const writeGlobalField = async (schema: any, globalSave: string) => { }; export const contenTypeMaker = async ({ contentType, destinationStackId }: any) => { + const srcFunc = 'contenTypeMaker'; const ct: ContentType = { title: contentType?.contentstackTitle, uid: contentType?.contentstackUid, @@ -451,9 +455,23 @@ export const contenTypeMaker = async ({ contentType, destinationStackId }: any) if (ct?.uid) { if (contentType?.type === 'global_field') { const globalSave = path.join('sitecoreMigrationData', destinationStackId, 'global_fields'); + logger.info( + getLogMessage( + srcFunc, + `Global Field ${ct?.uid} has been successfully Transformed.`, + {} + ) + ) await writeGlobalField(ct, globalSave); } else { const contentSave = path.join('sitecoreMigrationData', destinationStackId, 'content_types'); + logger.info( + getLogMessage( + srcFunc, + `ContentType ${ct?.uid} has been successfully Transformed.`, + {} + ) + ) await saveContent(ct, contentSave); } } else { diff --git a/api/src/utils/entries-field-creator.utils.ts b/api/src/utils/entries-field-creator.utils.ts index 7f0cb287..68098ebb 100644 --- a/api/src/utils/entries-field-creator.utils.ts +++ b/api/src/utils/entries-field-creator.utils.ts @@ -324,7 +324,7 @@ export const entriesFieldCreator = async ({ field, content, idCorrector, allAsse } default: { - console.info(field?.ContentstackFieldType, 'umesh'); + console.info(field?.ContentstackFieldType, 'field missing'); return content; } } From 81130af4d261c56fa39ae3468450adbd71427dfe Mon Sep 17 00:00:00 2001 From: Sayali Joshi Date: Tue, 15 Oct 2024 18:29:18 +0530 Subject: [PATCH 03/16] [CMG-347] - Test Migration | when started test migration and when its completed, 'Start test migration' button should be disabled --- ui/src/cmsData/test_migration.json | 17 +++++-- ui/src/components/TestMigration/index.tsx | 46 ++++++++++++++----- .../TestMigration/testMigration.interface.ts | 3 +- 3 files changed, 49 insertions(+), 17 deletions(-) diff --git a/ui/src/cmsData/test_migration.json b/ui/src/cmsData/test_migration.json index faeaea63..2ade9b92 100644 --- a/ui/src/cmsData/test_migration.json +++ b/ui/src/cmsData/test_migration.json @@ -1,12 +1,19 @@ { "title": "Test Migration", - "subtitle": "Link to the Demo Stack", "locale": "en-us", - "cta": { + "create_stack_cta": { "open_in_new_tab": false, "theme": "primary", - "title": "Start Migration", - "url": "/projects/${projectId}/migration/steps/5", + "title": "Create Test Stack", + "url": "", "with_icon": false - } + }, + "start_migration_cta": { + "open_in_new_tab": false, + "theme": "primary", + "title": "Start Test Migration", + "url": "", + "with_icon": false + }, + "subtitle": "Test Migration is a step where some content types are migrated in a test stack for review. A user can verify the stack and data. If the data is migrated properly then it can proceed with the final Migration Execution process." } diff --git a/ui/src/components/TestMigration/index.tsx b/ui/src/components/TestMigration/index.tsx index ae1b08ec..de17c70d 100644 --- a/ui/src/components/TestMigration/index.tsx +++ b/ui/src/components/TestMigration/index.tsx @@ -34,12 +34,16 @@ const TestMigration = () => { const [data, setData] = useState({}); const [isLoading, setIsLoading] = useState(newMigrationData?.isprojectMapped); const [isStackLoading, setIsStackLoading] = useState(false); - const [isMigrationStarted, setIsMigrationStarted] = useState(false); + const [disableTestMigration, setdisableTestMigration] = useState(false); + + const [disableCreateStack, setDisableCreateStack] = useState(false); const { projectId = '' } = useParams(); const dispatch = useDispatch(); + const { create_stack_cta: createStackCta, subtitle, start_migration_cta: startMigrationCta } = data + /********** ALL USEEFFECT HERE *************/ useEffect(() => { //check if offline CMS data field is set to true, if then read data from cms data file. @@ -54,6 +58,18 @@ const TestMigration = () => { }); }, []); + // to disable buttons as per isMigrated state + useEffect(() => { + if (newMigrationData?.testStacks.find((stack) => stack?.stackUid === newMigrationData?.test_migration?.stack_api_key)?.isMigrated === false) { + setDisableCreateStack(true); + } + + if (newMigrationData?.testStacks.find((stack) => stack?.stackUid === newMigrationData?.test_migration?.stack_api_key)?.isMigrated === true) { + setdisableTestMigration(true); + } + }, [newMigrationData]); + + // Method to create test stack const handleCreateTestStack = async () => { setIsStackLoading(true); @@ -91,6 +107,8 @@ const TestMigration = () => { if (res?.status === 200) { setIsStackLoading(false); + setDisableCreateStack(true); + setdisableTestMigration(false) Notification({ notificationContent: { text: 'Test Stack created successfully' }, notificationProps: { @@ -110,15 +128,13 @@ const TestMigration = () => { } } + // Method to start test migration const handleTestMigration = async () => { const testRes = await createTestMigration( newMigrationData?.destination_stack?.selectedOrg?.value, projectId ); - console.log("testRes", testRes); - - if (testRes?.status === 200) { handleMigrationState(true); Notification({ @@ -130,11 +146,19 @@ const TestMigration = () => { type: 'message' }); } + + const newMigrationDataObj: INewMigration = { + ...newMigrationData, + testStacks: [...newMigrationData?.testStacks ?? [], {isMigrated: true, stackUid: newMigrationData?.test_migration?.stack_api_key} ] + }; + + dispatch(updateNewMigrationData((newMigrationDataObj))); } // Function to update the parent state const handleMigrationState = (newState: boolean) => { - setIsMigrationStarted(newState); + setDisableCreateStack(newState); + setdisableTestMigration(!newState) const newMigrationDataObj: INewMigration = { ...newMigrationData, @@ -151,17 +175,17 @@ const TestMigration = () => { :
-

Test Migration is a step where some content types are migrated in a test stack for review. A user can verify the stack and data. If the data is migrated properly then it can proceed with the final Migration Execution process.

+ {subtitle &&

{subtitle}

} - {newMigrationData?.test_migration?.stack_api_key && + {newMigrationData?.test_migration?.stack_api_key && { className="ml-8" onClick={handleTestMigration} version="v2" - disabled={isMigrationStarted} + disabled={disableTestMigration} > - Start Test Migration + {startMigrationCta?.title}
diff --git a/ui/src/components/TestMigration/testMigration.interface.ts b/ui/src/components/TestMigration/testMigration.interface.ts index cfc3427f..e73bb62a 100644 --- a/ui/src/components/TestMigration/testMigration.interface.ts +++ b/ui/src/components/TestMigration/testMigration.interface.ts @@ -1,6 +1,7 @@ export interface MigrationType { - cta?: CTA; + create_stack_cta?: CTA; subtitle?: string; + start_migration_cta?: CTA; } export interface CTA { From 374f7438de24d0cdd65584d2d8cfd72ceee9c6d2 Mon Sep 17 00:00:00 2001 From: AishDani Date: Wed, 16 Oct 2024 12:30:09 +0530 Subject: [PATCH 04/16] refactor:added try-catch block for error handling --- ui/src/components/AdvancePropertise/index.tsx | 10 +- .../DestinationStack/Actions/LoadStacks.tsx | 112 +++++----- ui/src/components/DestinationStack/index.tsx | 74 ++++--- .../LegacyCms/Actions/LoadFileFormat.tsx | 85 ++++---- .../LegacyCms/Actions/LoadSelectCms.tsx | 7 + .../LegacyCms/Actions/LoadUploadFile.tsx | 206 ++++++++++-------- ui/src/pages/Migration/index.tsx | 26 ++- ui/src/pages/Projects/index.tsx | 16 +- 8 files changed, 305 insertions(+), 231 deletions(-) diff --git a/ui/src/components/AdvancePropertise/index.tsx b/ui/src/components/AdvancePropertise/index.tsx index 3e9631f8..e49d2e59 100644 --- a/ui/src/components/AdvancePropertise/index.tsx +++ b/ui/src/components/AdvancePropertise/index.tsx @@ -90,9 +90,15 @@ const AdvancePropertise = (props: SchemaProps) => { * @param searchText - The search text. */ const fetchContentTypes = async (searchText: string) => { - const { data } = await getContentTypes(props?.projectId ?? '', 0, 10, searchText || ''); //org id will always present + try { + const { data } = await getContentTypes(props?.projectId ?? '', 0, 10, searchText || ''); //org id will always present - setContentTypes(data?.contentTypes); + setContentTypes(data?.contentTypes); + } catch (error) { + return error; + + } + }; /** diff --git a/ui/src/components/DestinationStack/Actions/LoadStacks.tsx b/ui/src/components/DestinationStack/Actions/LoadStacks.tsx index 157f1b48..531a2a23 100644 --- a/ui/src/components/DestinationStack/Actions/LoadStacks.tsx +++ b/ui/src/components/DestinationStack/Actions/LoadStacks.tsx @@ -87,8 +87,8 @@ const LoadStacks = (props: LoadFileFormatProps) => { //Handle new stack details const handleOnSave = async (data: Stack) => { - - // Post data to backend + try { + // Post data to backend const resp = await createStacksInOrg(selectedOrganisation?.value, { ...data, master_locale: data?.locale @@ -135,6 +135,13 @@ const LoadStacks = (props: LoadFileFormatProps) => { return true; } + + } catch (error) { + return error; + + } + + }; /**** ALL METHODS HERE ****/ @@ -172,57 +179,64 @@ const LoadStacks = (props: LoadFileFormatProps) => { }; const fetchData = async () => { - if (allStack?.length <= 0) { - setAllStack(loadingOption); - const stackData = await getAllStacksInOrg(selectedOrganisation?.value, ''); // org id will always be there + try { + if (allStack?.length <= 0) { + setAllStack(loadingOption); + const stackData = await getAllStacksInOrg(selectedOrganisation?.value, ''); // org id will always be there + + const stackArray = validateArray(stackData?.data?.stacks) + ? stackData?.data?.stacks?.map((stack: StackResponse) => ({ + label: stack?.name, + value: stack?.api_key, + uid: stack?.api_key, + master_locale: stack?.master_locale, + locales: stack?.locales, + created_at: stack?.created_at, + isNewStack: newStackCreated + })) + : []; + + stackArray.sort( + (a: IDropDown, b: IDropDown) => + new Date(b?.created_at)?.getTime() - new Date(a?.created_at)?.getTime() + ); - const stackArray = validateArray(stackData?.data?.stacks) - ? stackData?.data?.stacks?.map((stack: StackResponse) => ({ - label: stack?.name, - value: stack?.api_key, - uid: stack?.api_key, - master_locale: stack?.master_locale, - locales: stack?.locales, - created_at: stack?.created_at, - isNewStack: newStackCreated - })) - : []; - - stackArray.sort( - (a: IDropDown, b: IDropDown) => - new Date(b?.created_at)?.getTime() - new Date(a?.created_at)?.getTime() - ); - - setAllStack(stackArray); - //Set selected Stack - const selectedStackData = validateArray(stackArray) - ? stackArray.find( - (stack: IDropDown) => - { - return stack?.value === newMigrationData?.destination_stack?.selectedStack?.value + setAllStack(stackArray); + //Set selected Stack + const selectedStackData = validateArray(stackArray) + ? stackArray.find( + (stack: IDropDown) => + { + return stack?.value === newMigrationData?.destination_stack?.selectedStack?.value + } + ) + : DEFAULT_DROPDOWN; + if (stackData?.data?.stacks?.length === 0 && (!stackData?.data?.stack)) { + setIsError(true); + setErrorMessage("Please create new stack there is no stack available"); + } + if(selectedStackData){ + setSelectedStack(selectedStackData); + setNewStackCreated(false); + const newMigrationDataObj: INewMigration = { + ...newMigrationDataRef?.current, + destination_stack: { + ...newMigrationDataRef?.current?.destination_stack, + selectedStack: selectedStackData, + stackArray: stackArray } - ) - : DEFAULT_DROPDOWN; - if (stackData?.data?.stacks?.length === 0 && (!stackData?.data?.stack)) { - setIsError(true); - setErrorMessage("Please create new stack there is no stack available"); - } - if(selectedStackData){ - setSelectedStack(selectedStackData); - setNewStackCreated(false); - const newMigrationDataObj: INewMigration = { - ...newMigrationDataRef?.current, - destination_stack: { - ...newMigrationDataRef?.current?.destination_stack, - selectedStack: selectedStackData, - stackArray: stackArray - } - }; - // Dispatch the updated migration data to Redux - dispatch(updateNewMigrationData(newMigrationDataObj)); - + }; + // Dispatch the updated migration data to Redux + dispatch(updateNewMigrationData(newMigrationDataObj)); + + } } + + } catch (error) { + return error; + } + }; diff --git a/ui/src/components/DestinationStack/index.tsx b/ui/src/components/DestinationStack/index.tsx index f42078bb..f92db8e2 100644 --- a/ui/src/components/DestinationStack/index.tsx +++ b/ui/src/components/DestinationStack/index.tsx @@ -89,48 +89,54 @@ const DestinationStackComponent = ({ //If stack is already selected and exist in backend, then fetch all stack list and filter selected stack. if (!isEmptyString(destination_stack)) { - const stackData: any = await getAllStacksInOrg( - selectedOrganisationData?.value || selectedOrganisation?.value,'' - ); - const stackArray = validateArray(stackData?.data?.stacks) - ? stackData?.data?.stacks?.map((stack: StackResponse) => ({ + try { + const stackData: any = await getAllStacksInOrg( + selectedOrganisationData?.value || selectedOrganisation?.value,'' + ); + const stackArray = validateArray(stackData?.data?.stacks) + ? stackData?.data?.stacks?.map((stack: StackResponse) => ({ + label: stack?.name, + value: stack?.api_key, + uid: stack?.api_key, + master_locale: stack?.master_locale, + locales: stack?.locales, + created_at: stack?.created_at + })) + : []; + + stackArray.sort( + (a: IDropDown, b: IDropDown) => + new Date(b?.created_at)?.getTime() - new Date(a?.created_at)?.getTime() + ); + const stack = + validateArray(stackData?.data?.stacks) && + stackData?.data?.stacks?.find( + (stack: StackResponse) => stack?.api_key === destination_stack + ); + + if (stack) { + selectedStackData = { label: stack?.name, value: stack?.api_key, - uid: stack?.api_key, master_locale: stack?.master_locale, locales: stack?.locales, created_at: stack?.created_at - })) - : []; - - stackArray.sort( - (a: IDropDown, b: IDropDown) => - new Date(b?.created_at)?.getTime() - new Date(a?.created_at)?.getTime() - ); - const stack = - validateArray(stackData?.data?.stacks) && - stackData?.data?.stacks?.find( - (stack: StackResponse) => stack?.api_key === destination_stack - ); - - if (stack) { - selectedStackData = { - label: stack?.name, - value: stack?.api_key, - master_locale: stack?.master_locale, - locales: stack?.locales, - created_at: stack?.created_at + }; + } + const newMigData: IDestinationStack = { + ...newMigrationData?.destination_stack, + selectedOrg: selectedOrganisationData || selectedOrganisation, + selectedStack: selectedStackData, + stackArray: stackArray }; + + } catch (error) { + return error; + } - const newMigData: IDestinationStack = { - ...newMigrationData?.destination_stack, - selectedOrg: selectedOrganisationData || selectedOrganisation, - selectedStack: selectedStackData, - stackArray: stackArray - }; - //dispatch(updateNewMigrationData({ destination_stack: newMigData })); + + } - //Update newMigration Data for destination stack diff --git a/ui/src/components/LegacyCms/Actions/LoadFileFormat.tsx b/ui/src/components/LegacyCms/Actions/LoadFileFormat.tsx index efe596d0..f710e4e5 100644 --- a/ui/src/components/LegacyCms/Actions/LoadFileFormat.tsx +++ b/ui/src/components/LegacyCms/Actions/LoadFileFormat.tsx @@ -74,51 +74,58 @@ const LoadFileFormat = (props: LoadFileFormatProps) => { }; const handleFileFormat = async() =>{ - const {data} = await getConfig(); + try { + const {data} = await getConfig(); - const cmsType = !isEmptyString(newMigrationData?.legacy_cms?.selectedCms?.parent) ? newMigrationData?.legacy_cms?.selectedCms?.parent : data?.cmsType?.toLowerCase(); - const filePath = data?.localPath?.toLowerCase(); - const fileFormat = getFileExtension(filePath); - if(! isEmptyString(selectedCard?.fileformat_id)){ - setFileIcon(selectedCard?.title); - } - else{ - const { all_cms = [] } = migrationData?.legacyCMSData || {}; - let filteredCmsData:ICMSType[] = all_cms; - if (cmsType) { - filteredCmsData = all_cms?.filter((cms) => cms?.parent?.toLowerCase() === cmsType?.toLowerCase()); - } - - const isFormatValid = filteredCmsData[0]?.allowed_file_formats?.find((format:ICardType)=>{ - const isValid = format?.fileformat_id?.toLowerCase() === fileFormat?.toLowerCase(); - return isValid; - }); - - if(!isFormatValid){ - setIsError(true); - setError('File format does not support, please add the correct file format.'); + const cmsType = !isEmptyString(newMigrationData?.legacy_cms?.selectedCms?.parent) ? newMigrationData?.legacy_cms?.selectedCms?.parent : data?.cmsType?.toLowerCase(); + const filePath = data?.localPath?.toLowerCase(); + const fileFormat = getFileExtension(filePath); + if(! isEmptyString(selectedCard?.fileformat_id)){ + setFileIcon(selectedCard?.title); } + else{ + const { all_cms = [] } = migrationData?.legacyCMSData || {}; + let filteredCmsData:ICMSType[] = all_cms; + if (cmsType) { + filteredCmsData = all_cms?.filter((cms) => cms?.parent?.toLowerCase() === cmsType?.toLowerCase()); + } + + const isFormatValid = filteredCmsData[0]?.allowed_file_formats?.find((format:ICardType)=>{ + const isValid = format?.fileformat_id?.toLowerCase() === fileFormat?.toLowerCase(); + return isValid; + }); + + if(!isFormatValid){ + setIsError(true); + setError('File format does not support, please add the correct file format.'); + } + + const selectedFileFormatObj = { + description: "", + fileformat_id: fileFormat, + group_name: fileFormat, + isactive: true, + title: fileFormat === 'zip' ? fileFormat?.charAt(0)?.toUpperCase() + fileFormat?.slice(1) : fileFormat?.toUpperCase() + } + + const newMigrationDataObj = { + ...newMigrationData, + legacy_cms: { + ...newMigrationData?.legacy_cms, + selectedFileFormat: selectedFileFormatObj + } + }; + + setFileIcon(fileFormat === 'zip' ? fileFormat?.charAt(0).toUpperCase() + fileFormat.slice(1) : fileFormat?.toUpperCase()); + dispatch(updateNewMigrationData(newMigrationDataObj)); - const selectedFileFormatObj = { - description: "", - fileformat_id: fileFormat, - group_name: fileFormat, - isactive: true, - title: fileFormat === 'zip' ? fileFormat?.charAt(0)?.toUpperCase() + fileFormat?.slice(1) : fileFormat?.toUpperCase() } - const newMigrationDataObj = { - ...newMigrationData, - legacy_cms: { - ...newMigrationData?.legacy_cms, - selectedFileFormat: selectedFileFormatObj - } - }; - - setFileIcon(fileFormat === 'zip' ? fileFormat?.charAt(0).toUpperCase() + fileFormat.slice(1) : fileFormat?.toUpperCase()); - dispatch(updateNewMigrationData(newMigrationDataObj)); - + } catch (error) { + return error; + } + } /**** ALL USEEffects HERE ****/ diff --git a/ui/src/components/LegacyCms/Actions/LoadSelectCms.tsx b/ui/src/components/LegacyCms/Actions/LoadSelectCms.tsx index 44c918a0..59b1e42e 100644 --- a/ui/src/components/LegacyCms/Actions/LoadSelectCms.tsx +++ b/ui/src/components/LegacyCms/Actions/LoadSelectCms.tsx @@ -86,6 +86,8 @@ const LoadSelectCms = (props: LoadSelectCmsProps) => { // Filter CMS Data const filterCMSData = async (searchText: string) => { + try { + const { all_cms = [] } = migrationData?.legacyCMSData || {}; setSelectedCard(cmsType); setIsLoading(true); @@ -154,6 +156,11 @@ const LoadSelectCms = (props: LoadSelectCmsProps) => { dispatch(updateNewMigrationData(newMigrationDataObj)); props?.handleStepChange(props?.currentStep); } + + } catch (error) { + return error; + + } }; diff --git a/ui/src/components/LegacyCms/Actions/LoadUploadFile.tsx b/ui/src/components/LegacyCms/Actions/LoadUploadFile.tsx index 803eeb2b..1fdcdc8b 100644 --- a/ui/src/components/LegacyCms/Actions/LoadUploadFile.tsx +++ b/ui/src/components/LegacyCms/Actions/LoadUploadFile.tsx @@ -94,109 +94,116 @@ const LoadUploadFile = (props: LoadUploadFileProps) => { //Handle further action on file is uploaded to server const handleOnFileUploadCompletion = async () => { - setIsValidationAttempted(false); - setValidationMessage(''); - setIsLoading(true); - setProgressPercentage(30); - setShowProgress(true); - setProcessing('Processing...30%'); - - await new Promise(resolve => setTimeout(resolve, 1000)); - - const {data, status} = await fileValidation(projectId); - - - setProgressPercentage(70); - setProcessing('Processing...70%'); - - - await new Promise(resolve => setTimeout(resolve, 1000)); - - - const newMigrationDataObj: INewMigration = { - ...newMigrationDataRef?.current, - legacy_cms: { - ...newMigrationDataRef?.current?.legacy_cms, - uploadedFile: { - name: data?.file_details?.localPath || '', - url: data?.file_details?.localPath, - validation: data?.message, - isValidated: status == 200 ? true : false, - file_details: { - isLocalPath: data?.file_details?.isLocalPath, - cmsType: data?.file_details?.cmsType, - localPath: data?.file_details?.localPath, - awsData: { - awsRegion: data?.file_details?.awsData?.awsRegion, - bucketName: data?.file_details?.awsData?.bucketName, - buketKey: data?.file_details?.awsData?.buketKey + try { + setIsValidationAttempted(false); + setValidationMessage(''); + setIsLoading(true); + setProgressPercentage(30); + setShowProgress(true); + setProcessing('Processing...30%'); + + await new Promise(resolve => setTimeout(resolve, 1000)); + + const {data, status} = await fileValidation(projectId); + + + setProgressPercentage(70); + setProcessing('Processing...70%'); + + + await new Promise(resolve => setTimeout(resolve, 1000)); + + + const newMigrationDataObj: INewMigration = { + ...newMigrationDataRef?.current, + legacy_cms: { + ...newMigrationDataRef?.current?.legacy_cms, + uploadedFile: { + name: data?.file_details?.localPath || '', + url: data?.file_details?.localPath, + validation: data?.message, + isValidated: status == 200 ? true : false, + file_details: { + isLocalPath: data?.file_details?.isLocalPath, + cmsType: data?.file_details?.cmsType, + localPath: data?.file_details?.localPath, + awsData: { + awsRegion: data?.file_details?.awsData?.awsRegion, + bucketName: data?.file_details?.awsData?.bucketName, + buketKey: data?.file_details?.awsData?.buketKey + } } + } - } + }; + + dispatch(updateNewMigrationData(newMigrationDataObj)); + + if(status === 200){ + setIsValidated(true); + setValidationMessage('Validation is successful'); + + setIsDisabled(true); + + if(! isEmptyString(newMigrationData?.legacy_cms?.affix) && ! isEmptyString(newMigrationData?.legacy_cms?.selectedCms?.cms_id) && ! isEmptyString(newMigrationData?.legacy_cms?.selectedFileFormat?.fileformat_id)){ + props.handleStepChange(props?.currentStep, true); + } + } - }; - - dispatch(updateNewMigrationData(newMigrationDataObj)); - - if(status === 200){ - setIsValidated(true); - setValidationMessage('Validation is successful'); - - setIsDisabled(true); + else if(status === 500){ + setIsValidated(false); + setValidationMessage('File not found'); + setIsValidationAttempted(true); + setProgressPercentage(100); - if(! isEmptyString(newMigrationData?.legacy_cms?.affix) && ! isEmptyString(newMigrationData?.legacy_cms?.selectedCms?.cms_id) && ! isEmptyString(newMigrationData?.legacy_cms?.selectedFileFormat?.fileformat_id)){ - props.handleStepChange(props?.currentStep, true); } - - } - else if(status === 500){ - setIsValidated(false); - setValidationMessage('File not found'); - setIsValidationAttempted(true); - setProgressPercentage(100); - - } - else if(status === 429){ - setIsValidated(false); - setValidationMessage('Rate limit exceeded. Please wait and try again.'); - setIsValidationAttempted(true); - setProgressPercentage(100); - - } - else{ - setIsValidated(false); - setValidationMessage('Validation is failed'); - setIsValidationAttempted(true); + else if(status === 429){ + setIsValidated(false); + setValidationMessage('Rate limit exceeded. Please wait and try again.'); + setIsValidationAttempted(true); + setProgressPercentage(100); + + } + else{ + setIsValidated(false); + setValidationMessage('Validation is failed'); + setIsValidationAttempted(true); + setProgressPercentage(100); + + } + setProgressPercentage(100); - + setProcessing('Processing...100%'); + + await new Promise(resolve => setTimeout(resolve, 1000)); + + setTimeout(() => { + setShowProgress(false); + setShowMessage(true); + }, 1000); + + setIsLoading(false); + saveStateToLocalStorage({ + isLoading, + isConfigLoading, + isValidated, + validationMessgae, + isDisabled, + cmsType, + fileDetails, + fileExtension, + progressPercentage, + showProgress, + fileFormat, + processing + }, projectId); + + } catch (error) { + return error; + } - - setProgressPercentage(100); - setProcessing('Processing...100%'); - - await new Promise(resolve => setTimeout(resolve, 1000)); - - setTimeout(() => { - setShowProgress(false); - setShowMessage(true); - }, 1000); - - setIsLoading(false); - saveStateToLocalStorage({ - isLoading, - isConfigLoading, - isValidated, - validationMessgae, - isDisabled, - cmsType, - fileDetails, - fileExtension, - progressPercentage, - showProgress, - fileFormat, - processing - }, projectId); + @@ -211,7 +218,8 @@ const LoadUploadFile = (props: LoadUploadFileProps) => { //function to get config details const getConfigDetails = async () =>{ - setIsConfigLoading(true); + try { + setIsConfigLoading(true); const {data, status} = await getConfig(); if (!isEmptyString(fileDetails?.localPath) && data?.localPath !== fileDetails?.localPath) { @@ -296,6 +304,12 @@ const LoadUploadFile = (props: LoadUploadFileProps) => { setIsDisabled(true); } setIsConfigLoading(false); + + } catch (error) { + return error; + + } + } diff --git a/ui/src/pages/Migration/index.tsx b/ui/src/pages/Migration/index.tsx index e1d46747..2028ea0d 100644 --- a/ui/src/pages/Migration/index.tsx +++ b/ui/src/pages/Migration/index.tsx @@ -80,19 +80,33 @@ const Migration = () => { // Function to get exisiting content types list const fetchExistingContentTypes = async () => { - const { data, status } = await getExistingContentTypes(projectId); - if (status === 201) { - return data?.contentTypes; + try { + const { data, status } = await getExistingContentTypes(projectId); + if (status === 201) { + return data?.contentTypes; + } + + } catch (error) { + return error; + } + }; // Function to get exisiting global fields list const fetchExistingGlobalFields = async () => { - const { data, status } = await getExistingGlobalFields(projectId); + try { + const { data, status } = await getExistingGlobalFields(projectId); - if (status === 201) { - return data?.globalFields; + if (status === 201) { + return data?.globalFields; + } + + } catch (error) { + return error; + } + } const fetchData = async () => { diff --git a/ui/src/pages/Projects/index.tsx b/ui/src/pages/Projects/index.tsx index 76979842..62cbc3d4 100644 --- a/ui/src/pages/Projects/index.tsx +++ b/ui/src/pages/Projects/index.tsx @@ -62,12 +62,18 @@ const Projects = () => { const fetchProjects = async () => { setLoadStatus(true); if (selectedOrganisation?.value) { - const { data, status } = await getAllProjects(selectedOrganisation?.value || ''); //org id will always present - if (status === 200) { - setLoadStatus(false); - setProjects(data); - setAllProjects(data); + try { + const { data, status } = await getAllProjects(selectedOrganisation?.value || ''); //org id will always present + if (status === 200) { + setLoadStatus(false); + setProjects(data); + setAllProjects(data); + } + + } catch (error) { + return error } + } }; From e17c202768a06ad1b9ab61336d66cd74c12721d3 Mon Sep 17 00:00:00 2001 From: AishDani Date: Wed, 16 Oct 2024 15:26:25 +0530 Subject: [PATCH 05/16] refactor:resolved sonarlint warnings --- .../advanceProperties.interface.ts | 6 ++ ui/src/components/AdvancePropertise/index.tsx | 23 ++-- ui/src/components/Card/index.tsx | 7 -- ui/src/components/ContentMapper/index.tsx | 100 +++++++++--------- .../Actions/LoadOrganisation.tsx | 14 +-- .../DestinationStack/Actions/LoadStacks.tsx | 2 +- ui/src/components/DestinationStack/index.tsx | 5 +- .../LegacyCms/Actions/LoadFileFormat.tsx | 8 -- .../LegacyCms/Actions/LoadSelectCms.tsx | 1 - ui/src/components/LegacyCms/index.tsx | 2 +- ui/src/store/slice/authSlice.tsx | 11 +- 11 files changed, 80 insertions(+), 99 deletions(-) diff --git a/ui/src/components/AdvancePropertise/advanceProperties.interface.ts b/ui/src/components/AdvancePropertise/advanceProperties.interface.ts index 8919f1a3..5dd24e3c 100644 --- a/ui/src/components/AdvancePropertise/advanceProperties.interface.ts +++ b/ui/src/components/AdvancePropertise/advanceProperties.interface.ts @@ -234,4 +234,10 @@ export interface StateType { * Indicates if the assets should be embedded. */ embedAssests?: boolean; +} + +export interface optionsType{ + label?:string; + key?:string; + value:string } \ No newline at end of file diff --git a/ui/src/components/AdvancePropertise/index.tsx b/ui/src/components/AdvancePropertise/index.tsx index e49d2e59..ab8068e3 100644 --- a/ui/src/components/AdvancePropertise/index.tsx +++ b/ui/src/components/AdvancePropertise/index.tsx @@ -18,7 +18,7 @@ import { import { getContentTypes } from '../../services/api/migration.service'; // Interfaces -import { SchemaProps } from './advanceProperties.interface'; +import { optionsType, SchemaProps } from './advanceProperties.interface'; import { ContentType } from '../ContentMapper/contentMapper.interface'; // Styles @@ -74,7 +74,7 @@ const AdvancePropertise = (props: SchemaProps) => { useEffect(()=>{ const defaultIndex = toggleStates?.option?.findIndex( - (item: any) => toggleStates?.Default_value === item?.key + (item: optionsType) => toggleStates?.Default_value === item?.key ); if (defaultIndex !== -1) { @@ -219,9 +219,9 @@ const AdvancePropertise = (props: SchemaProps) => { })); } - const handleDefalutValue = (index:number, option:any) => { + const handleDefalutValue = (index:number, option:optionsType) => { setShowIcon(index); - setShowOptions((prev) => ({ + setShowOptions(() => ({ [index]: false, })); @@ -250,7 +250,7 @@ const AdvancePropertise = (props: SchemaProps) => { ); } - const handleRemoveDefalutValue = (index:number, option:any)=>{ + const handleRemoveDefalutValue = (index:number)=>{ setShowIcon(-1); setShowOptions((prev) => ({ @@ -290,7 +290,7 @@ const AdvancePropertise = (props: SchemaProps) => { }); }; - const handleDragOver = (e:any, index:number) => { + const handleDragOver = (e:React.DragEvent, index:number) => { e.preventDefault(); document.querySelectorAll('.element-wrapper').forEach((el, i) => { if (i === index) { @@ -301,7 +301,7 @@ const AdvancePropertise = (props: SchemaProps) => { }); }; - const handleDrop = (index:any) => { + const handleDrop = (index:number) => { if (draggedIndex === null) return; const updatedOptions = [...options]; @@ -369,7 +369,7 @@ const AdvancePropertise = (props: SchemaProps) => { (read only)
- {options?.map((option:any,index)=>( + {options?.map((option: optionsType,index)=>( <>
handleDragStart(index)} @@ -403,7 +403,7 @@ const AdvancePropertise = (props: SchemaProps) => { onClick={()=>handleDefalutValue(index,option)} >Mark as Default : + onClick={()=>handleRemoveDefalutValue(index)} >Remove as Default } @@ -616,9 +616,10 @@ const AdvancePropertise = (props: SchemaProps) => { { - return; - }} - value={selectedStack} - isSearchable={true} - isClearable={true} - placeholder={'Stacks'} - /> -
-
-
- -
-
-
- {selectedStack?.master_locale} -
-
-
-
- -
-
- ); -}; - -export default StacksSummary; diff --git a/ui/src/components/DestinationStack/Summary/summary.scss b/ui/src/components/DestinationStack/Summary/summary.scss deleted file mode 100644 index 43f3cb92..00000000 --- a/ui/src/components/DestinationStack/Summary/summary.scss +++ /dev/null @@ -1,30 +0,0 @@ -@import '../../../scss/variables'; - -.summary-title { - font-family: $font-family-primary; - font-style: normal; - font-weight: 700; - font-size: $size-font-medium; - line-height: 135%; - letter-spacing: 0.02em; - color: $color-font-black; - margin-top: 3px; -} - -#Step2 .action-summary-wrapper { - background-color: rgb(247, 249, 252); - border: none; - padding: 0 10px !important; - margin-bottom: 0; - margin-left: 0; - top: 50%; -} - -#Step2 .StepperWrapper__step { - padding: 0 !important; -} - -.col-12 { - text-align: left; - padding: 0; -} diff --git a/ui/src/components/LegacyCms/Actions/LoadFileFormat.tsx b/ui/src/components/LegacyCms/Actions/LoadFileFormat.tsx index 42ab6683..34fcf736 100644 --- a/ui/src/components/LegacyCms/Actions/LoadFileFormat.tsx +++ b/ui/src/components/LegacyCms/Actions/LoadFileFormat.tsx @@ -18,7 +18,7 @@ import { getConfig } from '../../../services/api/upload.service'; import { ICMSType } from '../../../context/app/app.interface'; interface LoadFileFormatProps { - stepComponentProps: ()=>{}; + stepComponentProps?: ()=>{}; currentStep: number; handleStepChange: (stepIndex: number, closeStep?: boolean) => void; } diff --git a/ui/src/components/LegacyCms/Actions/LoadPrefix.tsx b/ui/src/components/LegacyCms/Actions/LoadPrefix.tsx index 1371ceeb..12de7d9a 100644 --- a/ui/src/components/LegacyCms/Actions/LoadPrefix.tsx +++ b/ui/src/components/LegacyCms/Actions/LoadPrefix.tsx @@ -21,7 +21,7 @@ import { updateNewMigrationData } from '../../../store/slice/migrationDataSlice' import restrictedKeywords from '../restrictedKeywords.json'; interface LoadSelectCmsProps { - stepComponentProps: ()=>{}; + stepComponentProps?: ()=>{}; currentStep: number; handleStepChange: (stepIndex: number, closeStep?: boolean) => void; } diff --git a/ui/src/components/LegacyCms/Actions/LoadSelectCms.tsx b/ui/src/components/LegacyCms/Actions/LoadSelectCms.tsx index 28dea4ac..dbc11d7e 100644 --- a/ui/src/components/LegacyCms/Actions/LoadSelectCms.tsx +++ b/ui/src/components/LegacyCms/Actions/LoadSelectCms.tsx @@ -26,7 +26,7 @@ import { RootState } from '../../../store'; import { updateNewMigrationData } from '../../../store/slice/migrationDataSlice'; interface LoadSelectCmsProps { - stepComponentProps: ()=>{}; + stepComponentProps?: ()=>{}; currentStep: number; handleStepChange: (stepIndex: number, closeStep?: boolean) => void; } diff --git a/ui/src/components/LegacyCms/Actions/LoadUploadFile.tsx b/ui/src/components/LegacyCms/Actions/LoadUploadFile.tsx index 80b6469b..4dc09df7 100644 --- a/ui/src/components/LegacyCms/Actions/LoadUploadFile.tsx +++ b/ui/src/components/LegacyCms/Actions/LoadUploadFile.tsx @@ -12,7 +12,7 @@ import { ICardType } from '../../../components/Common/Card/card.interface'; //import progressbar import ProgressBar from '../../../components/Common/ProgressBar'; interface LoadUploadFileProps { - stepComponentProps: ()=>{}; + stepComponentProps?: ()=>{}; currentStep: number; handleStepChange: (stepIndex: number, closeStep: boolean) => void; } diff --git a/ui/src/components/LegacyCms/StepperSteps.ts b/ui/src/components/LegacyCms/StepperSteps.ts index 423bc0ce..e5a470ef 100644 --- a/ui/src/components/LegacyCms/StepperSteps.ts +++ b/ui/src/components/LegacyCms/StepperSteps.ts @@ -4,11 +4,7 @@ import { StepStatus } from '../Stepper/VerticalStepper/AutoVerticalStepper'; import LoadFileFormat from './Actions/LoadFileFormat'; import LoadSelectCms from './Actions/LoadSelectCms'; import LoadUploadFile from './Actions/LoadUploadFile'; -import FileFormatSummary from './Summary/FileFormatSummary'; -import SelectCmsSummary from './Summary/SelectCmsSummary'; -import UploadFileSummary from './Summary/UploadFileSummary'; import LoadPreFix from './Actions/LoadPrefix'; -import PreFixSummary from './Summary/PreFixSummary'; const getComponentObject = ( step: IStep, @@ -22,7 +18,6 @@ const getComponentObject = ( updatedStep = { ...updatedStep, data: LoadSelectCms, - summery: SelectCmsSummary, status: isCompleted ? StepStatus.COMPLETED : StepStatus.ACTIVE, }; break; @@ -33,7 +28,6 @@ const getComponentObject = ( updatedStep = { ...updatedStep, data: LoadPreFix, - summery: PreFixSummary, status: isCompleted ? StepStatus.COMPLETED : StepStatus.DISABLED, }; break; @@ -44,7 +38,6 @@ const getComponentObject = ( updatedStep = { ...updatedStep, data: LoadFileFormat, - summery: FileFormatSummary, status: isCompleted ? StepStatus.COMPLETED : StepStatus.DISABLED, }; break; @@ -55,7 +48,6 @@ const getComponentObject = ( updatedStep = { ...updatedStep, data: LoadUploadFile, - summery: UploadFileSummary, status: isCompleted ? StepStatus.COMPLETED : StepStatus.DISABLED, }; break; diff --git a/ui/src/components/LegacyCms/Summary/FileFormatSummary.tsx b/ui/src/components/LegacyCms/Summary/FileFormatSummary.tsx deleted file mode 100644 index fe7311c2..00000000 --- a/ui/src/components/LegacyCms/Summary/FileFormatSummary.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { useContext } from 'react'; -import { useDispatch,useSelector } from 'react-redux'; -import StepIcon from '../../../components/Stepper/FlowStepper/StepIcon'; -import { AppContext } from '../../../context/app/app.context'; -import { isEmptyString } from '../../../utilities/functions'; -import { IStep } from '../../../context/app/app.interface'; - -import './summary.scss'; -import DocLink from '../../../components/Common/DocLink/DocLink'; -import { ICardType } from '../../Common/Card/card.interface'; -import { RootState } from '../../../store'; - -interface FileFormatSummaryProps { - stepData: IStep; -} - -const FileFormatSummary = ({ stepData }: FileFormatSummaryProps): JSX.Element => { - - const newMigrationData = useSelector((state:RootState)=>state?.migration?.newMigrationData); - const migrationData = useSelector((state:RootState)=>state?.migration?.migrationData); - const { doc_url = { href: '', title: '' }, allowed_file_formats = [] } = - newMigrationData?.legacy_cms?.selectedCms || {}; - - const { file_format_checkbox_text = '' } = migrationData.legacyCMSData; - - return ( -
-
- -
- {!isEmptyString(newMigrationData?.legacy_cms?.selectedFileFormat?.group_name) && - !isEmptyString(newMigrationData?.legacy_cms?.selectedFileFormat?.title) ? ( -
- {allowed_file_formats.map((format: ICardType, index) => ( - <> - {' '} - - {format?.title} - - {' '} - - ))} -
- ) : ( -
- {stepData?.empty_step_placeholder} -
- )} -
- ); -}; - -export default FileFormatSummary; diff --git a/ui/src/components/LegacyCms/Summary/PreFixSummary.tsx b/ui/src/components/LegacyCms/Summary/PreFixSummary.tsx deleted file mode 100644 index de15eebe..00000000 --- a/ui/src/components/LegacyCms/Summary/PreFixSummary.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { useContext } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -import StepIcon from '../../../components/Stepper/FlowStepper/StepIcon'; -import { AppContext } from '../../../context/app/app.context'; -import { isEmptyString } from '../../../utilities/functions'; -import { DEFAULT_URL_TYPE, IStep } from '../../../context/app/app.interface'; -import DocLink from '../../../components/Common/DocLink/DocLink'; - -import './summary.scss'; -import { RootState } from '../../../store'; - -interface PreFixSummaryProps { - stepData: IStep; -} - -const PreFixSummary = (props: PreFixSummaryProps): JSX.Element => { - - const newMigrationData = useSelector((state:RootState)=>state?.migration?.newMigrationData); - const migrationData = useSelector((state:RootState)=>state?.migration?.migrationData); - const { restricted_keyword_link = DEFAULT_URL_TYPE, restricted_keyword_checkbox_text = '' } = - migrationData.legacyCMSData; - - return ( -
- - {!isEmptyString(newMigrationData?.legacy_cms?.affix) ? ( -
-
- {newMigrationData?.legacy_cms?.affix || ''} -
-
- ) : ( -
- {props?.stepData?.empty_step_placeholder} -
- )} -
- ); -}; - -export default PreFixSummary; diff --git a/ui/src/components/LegacyCms/Summary/SelectCmsSummary.tsx b/ui/src/components/LegacyCms/Summary/SelectCmsSummary.tsx deleted file mode 100644 index 9d8d4beb..00000000 --- a/ui/src/components/LegacyCms/Summary/SelectCmsSummary.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { useContext } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -import StepIcon from '../../../components/Stepper/FlowStepper/StepIcon'; -import { AppContext } from '../../../context/app/app.context'; -import './summary.scss'; -import { isEmptyString } from '../../../utilities/functions'; -import { IStep } from '../../../context/app/app.interface'; -import { RootState } from '../../../store'; - - -interface SelectCmsSummaryProps { - stepData: IStep; -} - -const SelectCmsSummary = (props: SelectCmsSummaryProps): JSX.Element => { - - const newMigrationData = useSelector((state:RootState)=>state?.migration?.newMigrationData); - - return ( -
- {!isEmptyString(newMigrationData?.legacy_cms?.selectedCms?.group_name) && - !isEmptyString(newMigrationData?.legacy_cms?.selectedCms?.title) ? ( -
- {' '} - - {newMigrationData?.legacy_cms?.selectedCms?.title || ''} - -
- ) : ( -
- {props?.stepData?.empty_step_placeholder} -
- )} -
- ); -}; - -export default SelectCmsSummary; diff --git a/ui/src/components/LegacyCms/Summary/UploadFileSummary.tsx b/ui/src/components/LegacyCms/Summary/UploadFileSummary.tsx deleted file mode 100644 index 11a16035..00000000 --- a/ui/src/components/LegacyCms/Summary/UploadFileSummary.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import { useContext, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -import { AppContext } from '../../../context/app/app.context'; -import './summary.scss'; -import { isEmptyString } from '../../../utilities/functions'; -import { IStep } from '../../../context/app/app.interface'; - -interface UploadFileSummaryProps { - stepComponentProps: any; - stepData: IStep; -} - -import { FileDetails } from '../../../context/app/app.interface'; -import { RootState } from '../../../store'; -import { Paragraph } from '@contentstack/venus-components'; - -interface Props { - fileDetails: FileDetails; -} - -export const FileComponent: React.FC = ({ fileDetails }) => { - - return ( -
- {fileDetails?.isLocalPath ? ( -
- - -
- ) : ( -
-

AWS Region: {fileDetails?.awsData?.awsRegion}

-

Bucket Name: {fileDetails?.awsData?.bucketName}

-

Bucket Key: {fileDetails?.awsData?.buketKey}

-
- )} -
- ); -}; - -const UploadFileSummary = ({ - stepComponentProps, - stepData -}: UploadFileSummaryProps): JSX.Element => { - - const newMigrationData = useSelector((state:RootState)=>state?.migration?.newMigrationData); - const [isLoading, setIsLoading] = useState(false); - return ( -
- {!isEmptyString(newMigrationData?.legacy_cms?.uploadedFile?.name) ? ( -
- -

- - {newMigrationData?.legacy_cms?.uploadedFile?.validation} - - - {!newMigrationData?.legacy_cms?.uploadedFile?.isValidated ? ( -

Please upload the correct file

- ) : ( - <> - )} -
- ) : ( -
- {stepData?.empty_step_placeholder} - {!newMigrationData?.legacy_cms?.uploadedFile?.isValidated ? ( -

Please upload the correct file

- ) : ( - <> - )} -
- )} -
- ); -}; - -export default UploadFileSummary; diff --git a/ui/src/components/LegacyCms/Summary/summary.scss b/ui/src/components/LegacyCms/Summary/summary.scss deleted file mode 100644 index bb9cb6e9..00000000 --- a/ui/src/components/LegacyCms/Summary/summary.scss +++ /dev/null @@ -1,47 +0,0 @@ -@import '../../../scss/variables'; -.summary-title { - //font-family: $font-family-primary; - font-style: normal; - font-weight: 700; - font-size: 13px; - line-height: 135%; - letter-spacing: 0.02em; - //color: $color-font-black; - margin-top: 3px; -} - -.Checkbox input:disabled ~ .Checkbox__label { - opacity: 1; -} -.Checkbox.Checkbox--state-checked { - display: flex; -} -.Checkbox .Checkbox__tick svg { - display: block; -} -.Checkbox.Checkbox--state-checked.Checkbox--state-disabled { - color: #212121; - opacity: 1; -} -.Checkbox-wrapper .Checkbox { - display: flex; -} -.Checkbox-wrapper .Checkbox .Checkbox__label { - margin-top: -2px; -} -.Checkbox input:disabled:checked ~ .Checkbox__label, -.Checkbox input:disabled:indeterminate ~ .Checkbox__label { - color: #212121; - opacity: 1; -} -.affix-container { - display: flex; - background-color: $color-base-white-5; - height: $px-40; - width: $px-435; - align-items: center; - text-align: center; - padding: 0 !important; - border: 1px solid #dde3ee; - border-radius: var(--TermCount, 5px); -} diff --git a/ui/src/components/LegacyCms/index.tsx b/ui/src/components/LegacyCms/index.tsx index 85a3e117..b9a04d8d 100644 --- a/ui/src/components/LegacyCms/index.tsx +++ b/ui/src/components/LegacyCms/index.tsx @@ -282,9 +282,6 @@ const LegacyCMSComponent = forwardRef(({ legacyCMSData, isCompleted, handleOnAll isEdit={!isMigrationLocked} isRequired={true} handleOnAllStepsComplete={handleAllStepsComplete} - stepComponentProps={{ - handleDeleteFile: handleOnClickDeleteUploadedFile - }} /> diff --git a/ui/src/components/LegacyCms/legacyCms.scss b/ui/src/components/LegacyCms/legacyCms.scss index 6edc8410..2aade71a 100644 --- a/ui/src/components/LegacyCms/legacyCms.scss +++ b/ui/src/components/LegacyCms/legacyCms.scss @@ -71,7 +71,7 @@ background-color: $color-base-white-5; min-height: 72px; width: 560px; - margin-left: 20px !important; + margin-left: 10px !important; border: 1px solid $color-brand-secondary-lightest; border-radius: var(--TermCount, 5px); @@ -104,7 +104,7 @@ font-size: 12px; } .validation-cta{ - margin: $space-24 $space-20 0; + margin: $space-24 $space-12 0; line-height: 24px; } .success{ diff --git a/ui/src/components/Stepper/VerticalStepper/AutoVerticalStepper.scss b/ui/src/components/Stepper/VerticalStepper/AutoVerticalStepper.scss index 6e0dc967..5b9c65cc 100644 --- a/ui/src/components/Stepper/VerticalStepper/AutoVerticalStepper.scss +++ b/ui/src/components/Stepper/VerticalStepper/AutoVerticalStepper.scss @@ -83,11 +83,11 @@ } .action-summary-wrapper { - padding: $space-4 $space-24; - align-items: center; - border: 1px solid $color-base-gray-40; - border-radius: var(--TermCount, 5px); - background: $color-brand-white-base; + padding: $space-4 $space-24; + align-items: center; + //border: 1px solid $color-base-gray-40; + //border-radius: var(--TermCount, 5px); + //background: $color-brand-white-base; } .action-content-wrapper { diff --git a/ui/src/components/Stepper/VerticalStepper/AutoVerticalStepper.tsx b/ui/src/components/Stepper/VerticalStepper/AutoVerticalStepper.tsx index 27eab15d..50e3be90 100644 --- a/ui/src/components/Stepper/VerticalStepper/AutoVerticalStepper.tsx +++ b/ui/src/components/Stepper/VerticalStepper/AutoVerticalStepper.tsx @@ -1,6 +1,7 @@ -import React, { useEffect, useImperativeHandle, useMemo, useState } from 'react'; +import React, { useImperativeHandle, useMemo, useState } from 'react'; import './AutoVerticalStepper.scss'; -import { Heading, Paragraph } from '@contentstack/venus-components'; +import { Heading } from '@contentstack/venus-components'; +import { IStep } from '../../../context/app/app.interface'; export enum StepStatus { @@ -10,10 +11,10 @@ export enum StepStatus { } type AutoVerticalStepperProps = { - steps: any[]; + steps: IStep[]; className?: string; description?: string; - stepComponentProps?: any; + stepComponentProps?: ()=>{}; isEdit: boolean; isRequired:boolean; handleOnAllStepsComplete: (flag: boolean) => void; @@ -34,7 +35,6 @@ const AutoVerticalStepper = React.forwardRef< const { steps, className = '', - description='', stepComponentProps, isEdit = false, handleOnAllStepsComplete = () => { @@ -42,18 +42,13 @@ const AutoVerticalStepper = React.forwardRef< } } = props; - const [stepStatus, setStepStatus] = useState(steps?.map((s: any) => s.status)); - - useEffect(() => { - if (!stepComponentProps?.step?.step_id && !stepComponentProps?.connector?.group_name) { - setStepStatus(steps?.map((s: any) => s.status)); - } - }, [stepComponentProps?.step?.step_id, stepComponentProps?.connector?.group_name]); + const [stepStatus, setStepStatus] = useState(steps?.map((s: IStep) => s.status)); + const handleStepChange = (stepIndex: number, closeStep = false) => { if (closeStep) { - const data = stepStatus.map((s: any, i: number) => { + const data = stepStatus.map((s: string | undefined, i: number) => { if (i === stepIndex) { return StepStatus.COMPLETED; } @@ -63,7 +58,7 @@ const AutoVerticalStepper = React.forwardRef< handleOnAllStepsComplete(true); } else { - const data: string[] = stepStatus.map((s: any, i: number) => { + const data: string[] = stepStatus.map((s: string | undefined, i: number) => { if (i <= stepIndex) { return StepStatus.COMPLETED; } else if (i === stepIndex + 1) { @@ -76,8 +71,8 @@ const AutoVerticalStepper = React.forwardRef< } }; - const StepperStepTitleCreator: (data: any,isRequired:boolean) => JSX.Element = (data: any, isRequired:boolean) => { - const showSpan = data?.title == 'Orgnization' ? (read only) : '' + const StepperStepTitleCreator: (data: IStep,isRequired:boolean) => JSX.Element = (data: IStep, isRequired:boolean) => { + return ( <>
@@ -103,7 +98,7 @@ const AutoVerticalStepper = React.forwardRef< }; const goToStep = (stepIndex: number) => { - const data: string[] = stepStatus.map((s: any, i: number) => { + const data: string[] = stepStatus.map((s: string | undefined, i: number) => { if (s === StepStatus.ACTIVE && i !== stepIndex) { return StepStatus.DISABLED; } @@ -113,19 +108,22 @@ const AutoVerticalStepper = React.forwardRef< if (i === stepIndex) { return StepStatus.ACTIVE; } - return s; + return s !== undefined ? s : '' ; }); setStepStatus(data); }; - const summaryActivateStep = (e: any) => { - const index = e.currentTarget.getAttribute('data-step-index'); + const summaryActivateStep = (e: React.MouseEvent) => { + const index = e?.currentTarget?.getAttribute('data-step-index'); + if(! index) return; handleOnAllStepsComplete(false); + if (!index) return; + const stepIndex = parseInt(index, 10); if (isEdit) { - goToStep(+index); + goToStep(stepIndex); } else { - handleStepChange(index - 1); + handleStepChange(stepIndex - 1); } }; @@ -136,35 +134,13 @@ const AutoVerticalStepper = React.forwardRef< })); return useMemo(() => { - const stepClassNameObject: any = { - [StepStatus.ACTIVE]: 'active', - [StepStatus.COMPLETED]: 'completed', - [StepStatus.DISABLED]: 'disabled', - [`${StepStatus.ACTIVE}__${StepStatus.COMPLETED}`]: 'active__to__completed', - [`${StepStatus.ACTIVE}__${StepStatus.ACTIVE}`]: 'active__to__active', - [`${StepStatus.ACTIVE}__${StepStatus.DISABLED}`]: 'active__to__disabled', - [`${StepStatus.DISABLED}__${StepStatus.COMPLETED}`]: 'disabled__to__completed', - [`${StepStatus.DISABLED}__${StepStatus.ACTIVE}`]: 'disabled__to__active', - [`${StepStatus.DISABLED}__${StepStatus.DISABLED}`]: 'disabled__to__disabled', - [`${StepStatus.COMPLETED}__${StepStatus.COMPLETED}`]: 'completed__to__completed', - [`${StepStatus.COMPLETED}__${StepStatus.ACTIVE}`]: 'completed__to__active', - [`${StepStatus.COMPLETED}__${StepStatus.DISABLED}`]: 'completed__to__disabled' - }; - const getStepStatus = (idx: number) => { - return stepStatus[idx]; - }; return (
{props?.description &&
{props?.description}
}
    - {steps?.map((step: any, index: number) => { - - let stepClassName = stepClassNameObject[getStepStatus(index)]; - if (step?.lock) stepClassName = 'completed'; - const getGridientClass = - stepClassNameObject[`${getStepStatus(index)}__${getStepStatus(index + 1)}`]; - + {steps?.map((step: IStep, index: number) => { + return (
  1. {}; + stepComponentProps?: ()=>{}; currentStep: number; handleStepChange: (step: number) => void; }; @@ -86,6 +86,9 @@ export interface IStep { data?: (props:DataProps) => JSX.Element; summery?: (props: SummaryProps) => JSX.Element; empty_step_placeholder?: string; + ifReadonly?:boolean; + isRequired?: boolean; + titleNote?: string; } export interface IURLType { From 3f48eac88f792992ebacb541e5d1392805e9d074 Mon Sep 17 00:00:00 2001 From: AishDani Date: Tue, 22 Oct 2024 18:46:37 +0530 Subject: [PATCH 14/16] refactor:resolved css of progressBar of upload file --- ui/src/components/LegacyCms/legacyCms.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/src/components/LegacyCms/legacyCms.scss b/ui/src/components/LegacyCms/legacyCms.scss index 2aade71a..fe9f8f9f 100644 --- a/ui/src/components/LegacyCms/legacyCms.scss +++ b/ui/src/components/LegacyCms/legacyCms.scss @@ -104,7 +104,7 @@ font-size: 12px; } .validation-cta{ - margin: $space-24 $space-12 0; + margin: $space-16 $space-12 0; line-height: 24px; } .success{ @@ -128,7 +128,7 @@ height: 10px; width: 560px; align-items: center; - margin-left: 20px !important; + margin-left: 10px !important; margin-top: 10px; } .file-icon-group{ From e2fd621729139cdc4fd99faa8d605cb11872db85 Mon Sep 17 00:00:00 2001 From: Sayali Joshi Date: Thu, 24 Oct 2024 13:17:31 +0530 Subject: [PATCH 15/16] Start button disabled after migration started --- api/src/models/project-lowdb.ts | 1 + api/src/services/migration.service.ts | 8 ++++++++ api/src/services/projects.service.ts | 3 ++- ui/src/components/LogScreen/index.tsx | 3 --- ui/src/components/MigrationExecution/index.tsx | 3 ++- ui/src/components/MigrationFlowHeader/index.tsx | 11 ++++++----- upload-api/src/controllers/sitecore/index.ts | 2 +- 7 files changed, 20 insertions(+), 11 deletions(-) diff --git a/api/src/models/project-lowdb.ts b/api/src/models/project-lowdb.ts index 6279d4c8..f2fb6d81 100644 --- a/api/src/models/project-lowdb.ts +++ b/api/src/models/project-lowdb.ts @@ -73,6 +73,7 @@ interface Project { stackDetails: []; mapperKeys: {}; extract_path: string; + isMigrationStarted: boolean; } interface ProjectDocument { diff --git a/api/src/services/migration.service.ts b/api/src/services/migration.service.ts index c886b213..b53c0054 100644 --- a/api/src/services/migration.service.ts +++ b/api/src/services/migration.service.ts @@ -236,6 +236,14 @@ const startMigration = async (req: Request): Promise => { const { region, user_id } = req?.body?.token_payload ?? {}; await ProjectModelLowdb.read(); const project = ProjectModelLowdb.chain.get("projects").find({ id: projectId }).value(); + + const index = ProjectModelLowdb.chain.get("projects").findIndex({ id: projectId }).value(); + if (index > -1) { + ProjectModelLowdb.update((data: any) => { + data.projects[index].isMigrationStarted = true; + }); + } + const packagePath = project?.extract_path; if (packagePath && project?.destination_stack_id) { const loggerPath = path.join(process.cwd(), 'logs', projectId, `${project?.destination_stack_id}.log`); diff --git a/api/src/services/projects.service.ts b/api/src/services/projects.service.ts index db644bf0..3fc39673 100644 --- a/api/src/services/projects.service.ts +++ b/api/src/services/projects.service.ts @@ -125,7 +125,8 @@ const createProject = async (req: Request) => { created_at: '', isNewStack: false }, - mapperKeys: {} + mapperKeys: {}, + isMigrationStarted: false }; try { diff --git a/ui/src/components/LogScreen/index.tsx b/ui/src/components/LogScreen/index.tsx index 3715398d..b1da010e 100644 --- a/ui/src/components/LogScreen/index.tsx +++ b/ui/src/components/LogScreen/index.tsx @@ -25,7 +25,6 @@ const logStyles: { [key: string]: React.CSSProperties } = { type LogsType = { serverPath: string; - isMigrationStarted?: boolean; sendDataToParent?: (isMigrationStarted: boolean) => void | undefined; } @@ -35,7 +34,6 @@ type LogsType = { */ const LogViewer = ({ serverPath, sendDataToParent }: LogsType) => { const [logs, setLogs] = useState(["Loading logs..."]); - const [isMigrationComplete, setIsMigrationComplete] = useState(false); const newMigrationData = useSelector((state: RootState) => state?.migration?.newMigrationData); @@ -147,7 +145,6 @@ const LogViewer = ({ serverPath, sendDataToParent }: LogsType) => { type: 'success' }); sendDataToParent?.(false); - setIsMigrationComplete(true); const newMigrationDataObj: INewMigration = { ...newMigrationData, diff --git a/ui/src/components/MigrationExecution/index.tsx b/ui/src/components/MigrationExecution/index.tsx index e31031ab..a8f19803 100644 --- a/ui/src/components/MigrationExecution/index.tsx +++ b/ui/src/components/MigrationExecution/index.tsx @@ -7,7 +7,7 @@ import { getCMSDataFromFile } from '../../cmsData/cmsSelector'; // Redux import { RootState } from '../../store'; -import { setMigrationData, updateMigrationData } from '../../store/slice/migrationDataSlice'; +import { updateMigrationData } from '../../store/slice/migrationDataSlice'; // Utilities import { CS_ENTRIES } from '../../utilities/constants'; @@ -22,6 +22,7 @@ import LogViewer from '../LogScreen'; //stylesheet import './index.scss'; + const MigrationExecution = () => { const dispatch = useDispatch(); diff --git a/ui/src/components/MigrationFlowHeader/index.tsx b/ui/src/components/MigrationFlowHeader/index.tsx index f8be059e..df1a773d 100644 --- a/ui/src/components/MigrationFlowHeader/index.tsx +++ b/ui/src/components/MigrationFlowHeader/index.tsx @@ -17,10 +17,11 @@ type MigrationFlowHeaderProps = { isLoading: boolean; isCompleted: boolean; legacyCMSRef: React.MutableRefObject; - projectData:MigrationResponse + projectData:MigrationResponse; + finalExecutionStarted?: boolean; }; -const MigrationFlowHeader = ({projectData, handleOnClick, isLoading }: MigrationFlowHeaderProps) => { +const MigrationFlowHeader = ({projectData, handleOnClick, isLoading, finalExecutionStarted }: MigrationFlowHeaderProps) => { const [projectName, setProjectName] = useState(''); const [currentStep, setCurrentStep] = useState(0); @@ -53,7 +54,7 @@ const MigrationFlowHeader = ({projectData, handleOnClick, isLoading }: Migration } else { stepValue = 'Save and Continue'; } - + return (
    @@ -69,9 +70,9 @@ const MigrationFlowHeader = ({projectData, handleOnClick, isLoading }: Migration onClick={handleOnClick} version="v2" aria-label='Save and Continue' - isLoading={isLoading} + isLoading={isLoading || newMigrationData?.isprojectMapped} disabled={(params?.stepId === '4' && !newMigrationData?.test_migration?.isMigrationComplete) || - (params?.stepId && params?.stepId <= '2' && currentStep.toString() !== params?.stepId) || newMigrationData?.migration_execution?.migrationStarted + (params?.stepId && params?.stepId <= '2' && newMigrationData?.project_current_step?.toString() !== params?.stepId) || finalExecutionStarted } > {stepValue} diff --git a/upload-api/src/controllers/sitecore/index.ts b/upload-api/src/controllers/sitecore/index.ts index 2e4b5ac3..c78bdd37 100644 --- a/upload-api/src/controllers/sitecore/index.ts +++ b/upload-api/src/controllers/sitecore/index.ts @@ -32,7 +32,7 @@ const createSitecoreMapper = async (filePath: string = "", projectId: string | s fieldMapping.contentTypes.push(element); } } - console.log("🚀 ~ createSitecoreMapper ~ fieldMapping:", fieldMapping) + // console.log("🚀 ~ createSitecoreMapper ~ fieldMapping:", fieldMapping) const config = { method: 'post', maxBodyLength: Infinity, From eb708ec329c3f259cb0e5b32c1e4e697a313e894 Mon Sep 17 00:00:00 2001 From: AishDani Date: Fri, 25 Oct 2024 17:35:27 +0530 Subject: [PATCH 16/16] refactor:resolved steps rendering issue when there is loader and getting migration data using projectId,added API to get logs --- api/src/constants/index.ts | 2 + api/src/controllers/migration.controller.ts | 8 ++- api/src/routes/migration.routes.ts | 6 ++ api/src/services/migration.service.ts | 58 ++++++++++++++++++- api/src/services/runCli.service.ts | 3 +- api/src/utils/field-attacher.utils.ts | 4 +- cli/packages/contentstack/.gitignore | 4 +- .../HorizontalStepper/HorizontalStepper.tsx | 8 ++- 8 files changed, 83 insertions(+), 10 deletions(-) diff --git a/api/src/constants/index.ts b/api/src/constants/index.ts index ac316320..fe978ac3 100644 --- a/api/src/constants/index.ts +++ b/api/src/constants/index.ts @@ -82,6 +82,8 @@ export const HTTP_TEXTS = { "Project Deleted Successfully", PROJECT_REVERT: "Project Reverted Successfully", + LOGS_NOT_FOUND: + "Sorry, no logs found for requested stack migration." }; export const HTTP_RESPONSE_HEADERS = { diff --git a/api/src/controllers/migration.controller.ts b/api/src/controllers/migration.controller.ts index ce5d6d18..9f46dc4a 100644 --- a/api/src/controllers/migration.controller.ts +++ b/api/src/controllers/migration.controller.ts @@ -50,9 +50,15 @@ const deleteTestStack = async (req: Request, res: Response): Promise => { res.status(200).json(resp); }; +const getLogs = async (req: Request, res: Response): Promise => { + const resp = await migrationService.getLogs(req); + res.status(200).json(resp); +}; + export const migrationController = { createTestStack, deleteTestStack, startTestMigration, - startMigration + startMigration, + getLogs, }; diff --git a/api/src/routes/migration.routes.ts b/api/src/routes/migration.routes.ts index 7e4c29d9..e22a87cf 100644 --- a/api/src/routes/migration.routes.ts +++ b/api/src/routes/migration.routes.ts @@ -59,5 +59,11 @@ router.post( asyncRouter(migrationController.startMigration) ); +router.get( + "/get_migration_logs/:orgId/:projectId/:stackId", + asyncRouter(migrationController.getLogs) + +) + export default router; diff --git a/api/src/services/migration.service.ts b/api/src/services/migration.service.ts index c886b213..12ccd7f7 100644 --- a/api/src/services/migration.service.ts +++ b/api/src/services/migration.service.ts @@ -8,13 +8,14 @@ import { LoginServiceType } from "../models/types.js" import getAuthtoken from "../utils/auth.utils.js"; import logger from "../utils/logger.js"; import { HTTP_TEXTS, HTTP_CODES, LOCALE_MAPPER, STEPPER_STEPS } from "../constants/index.js"; -import { ExceptionFunction } from "../utils/custom-errors.utils.js"; +import { BadRequestError, ExceptionFunction } from "../utils/custom-errors.utils.js"; import { fieldAttacher } from "../utils/field-attacher.utils.js"; import { siteCoreService } from "./sitecore.service.js"; import { testFolderCreator } from "../utils/test-folder-creator.utils.js"; import { utilsCli } from './runCli.service.js'; import customLogger from "../utils/custom-logger.utils.js"; import { setLogFilePath } from "../server.js"; +import fs from 'fs'; @@ -250,9 +251,62 @@ const startMigration = async (req: Request): Promise => { } } +const getLogs = async (req: Request): Promise => { + const orgId = req?.params?.orgId; + const projectId = req?.params?.projectId; + const stackId = req?.params?.stackId; + const srcFunc = "getLogs"; + const { region, user_id } = req?.body?.token_payload ?? {}; + try { + const loggerPath = path.join(process.cwd(), 'logs', projectId, `${stackId}.log`); + if(fs.existsSync(loggerPath)){ + const logs = fs.readFileSync(loggerPath,'utf-8'); + const logEntries = logs + .split('\n') + .map(line => { + try { + return JSON.parse(line); + } catch (error) { + return null; + } + }) + .filter(entry => entry !== null); + return logEntries + + } + else{ + logger.error( + getLogMessage( + srcFunc, + HTTP_TEXTS.LOGS_NOT_FOUND, + + ) + ); + throw new BadRequestError(HTTP_TEXTS.LOGS_NOT_FOUND); + + } + + } catch (error:any) { + logger.error( + getLogMessage( + srcFunc, + HTTP_TEXTS.LOGS_NOT_FOUND, + error + ) + ); + throw new ExceptionFunction( + error?.message || HTTP_TEXTS.INTERNAL_ERROR, + error?.statusCode || error?.status || HTTP_CODES.SERVER_ERROR + ); + + } + +} + export const migrationService = { createTestStack, deleteTestStack, startTestMigration, - startMigration + startMigration, + getLogs, }; diff --git a/api/src/services/runCli.service.ts b/api/src/services/runCli.service.ts index 93959845..61cd8222 100644 --- a/api/src/services/runCli.service.ts +++ b/api/src/services/runCli.service.ts @@ -25,6 +25,7 @@ const addCustomMessageInCliLogs = async (loggerPath: string, level: string = 'in export const runCli = async (rg: string, user_id: string, stack_uid: any, projectId: string, isTest = false, transformePath: string) => { try { + const message: string = isTest ? 'Test Migration Process Completed' : 'Migration Process Completed' const regionPresent = CS_REGIONS?.find((item: string) => item === rg) ?? 'NA'; await AuthenticationModel.read(); const userData = AuthenticationModel.chain @@ -56,7 +57,7 @@ export const runCli = async (rg: string, user_id: string, stack_uid: any, projec }) ProjectModelLowdb.write(); } - await addCustomMessageInCliLogs(loggerPath, 'info', 'Test Migration Process Completed'); + await addCustomMessageInCliLogs(loggerPath, 'info', message); } }); diff --git a/api/src/utils/field-attacher.utils.ts b/api/src/utils/field-attacher.utils.ts index 41c48ca5..3977c625 100644 --- a/api/src/utils/field-attacher.utils.ts +++ b/api/src/utils/field-attacher.utils.ts @@ -16,13 +16,13 @@ export const fieldAttacher = async ({ projectId, orgId, destinationStackId }: an for await (const contentId of projectData?.content_mapper ?? []) { const contentType: any = ContentTypesMapperModelLowdb.chain .get("ContentTypesMappers") - .find({ id: contentId }) + .find({ id: contentId, projectId: projectId }) .value(); if (contentType?.fieldMapping?.length) { contentType.fieldMapping = contentType?.fieldMapping?.map((fieldUid: any) => { const field = FieldMapperModel.chain .get("field_mapper") - .find({ id: fieldUid }) + .find({ id: fieldUid, projectId: projectId }) .value() return field; }) diff --git a/cli/packages/contentstack/.gitignore b/cli/packages/contentstack/.gitignore index 2bf7d18b..9306742c 100644 --- a/cli/packages/contentstack/.gitignore +++ b/cli/packages/contentstack/.gitignore @@ -11,4 +11,6 @@ coverage tsconfig.tsbuildinfo /merge_scripts /merge-summary.json -!bin \ No newline at end of file +!bin +/sitecoreMigrationData +/migration-data \ 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 5da5b88a..33ed4955 100644 --- a/ui/src/components/Stepper/HorizontalStepper/HorizontalStepper.tsx +++ b/ui/src/components/Stepper/HorizontalStepper/HorizontalStepper.tsx @@ -99,7 +99,7 @@ const HorizontalStepper = forwardRef( const stepIndex = parseInt(stepId || '', 10) - 1; if (!Number.isNaN(stepIndex) && stepIndex >= 0 && stepIndex < steps?.length) { - setShowStep(stepIndex); + !newMigrationData?.isprojectMapped && setShowStep(stepIndex); setStepsCompleted(prev => { const updatedStepsCompleted = [...prev]; for (let i = 0; i < stepIndex; i++) { @@ -171,7 +171,7 @@ const HorizontalStepper = forwardRef( }; const setTabStep = (idx: number) => { - if (stepsCompleted?.includes(idx) || stepsCompleted?.length === idx) { + if ((stepsCompleted?.includes(idx) || stepsCompleted?.length === idx) && !newMigrationData?.isprojectMapped) { setShowStep(idx); const url = `/projects/${projectId}/migration/steps/${idx + 1}`; navigate(url, { replace: true }); @@ -190,6 +190,8 @@ const HorizontalStepper = forwardRef( !stepsCompleted.includes(idx) && idx !== showStep && !stepsCompleted?.includes(idx - 1) ? 'disableEvents' : ''; + const disableStep = newMigrationData?.isprojectMapped && stepsCompleted.includes(idx) && idx !== showStep ? 'disableEvents' + : ''; const completeDisable = stepsCompleted?.includes(idx) && idx < stepIndex - 1 && newMigrationData?.test_migration?.isMigrationStarted ? 'disableEvents' : ''; @@ -199,7 +201,7 @@ const HorizontalStepper = forwardRef(
    handleTabStep(idx)} >