From c0f9228c0c114f8b07ed807f4daaba52343ac718 Mon Sep 17 00:00:00 2001 From: Sayali Joshi Date: Tue, 6 Aug 2024 12:38:17 +0530 Subject: [PATCH 1/4] SNYK errors resolved --- .../components/DestinationStack/Actions/LoadStacks.tsx | 10 ++++++---- ui/src/components/Modal/index.tsx | 5 ++++- .../Stepper/HorizontalStepper/HorizontalStepper.tsx | 10 ++++++---- ui/src/context/app/app.interface.ts | 2 +- ui/src/reportWebVitals.js | 3 +++ uplaode-api/package.json | 4 ++-- uplaode-api/src/services/fileProcessing.ts | 4 ++-- uplaode-api/tsconfig.json | 4 ++-- 8 files changed, 26 insertions(+), 16 deletions(-) diff --git a/ui/src/components/DestinationStack/Actions/LoadStacks.tsx b/ui/src/components/DestinationStack/Actions/LoadStacks.tsx index a04c876e3..a0936a025 100644 --- a/ui/src/components/DestinationStack/Actions/LoadStacks.tsx +++ b/ui/src/components/DestinationStack/Actions/LoadStacks.tsx @@ -74,12 +74,12 @@ const LoadStacks = (props: LoadFileFormatProps) => { //Handle new stack details const handleOnSave = async (data: Stack) => { - if (isSaving) return false; + // if (isSaving) return false; setIsSaving(true); if (isEmptyString(data?.name) || isEmptyString(data?.locale)) { setIsSaving(false); - return false; + // return false; } // Post data to backend @@ -129,8 +129,10 @@ const LoadStacks = (props: LoadFileFormatProps) => { props.handleStepChange(props?.currentStep, true); return true; - } - return false; + } + // else { + // return false; + // } }; /**** ALL METHODS HERE ****/ diff --git a/ui/src/components/Modal/index.tsx b/ui/src/components/Modal/index.tsx index 5144e6f89..cdc8d3176 100644 --- a/ui/src/components/Modal/index.tsx +++ b/ui/src/components/Modal/index.tsx @@ -44,11 +44,14 @@ const Modal = (props: ProjectModalProps) => { // const payload = {name: values?.name, description: values?.description || ''} const res = await createProject(selectedOrg?.uid || '', values); + if (res?.error) { + return res?.error; + } if (res?.status === 201) { const projectId = res?.data?.project?.id window.location.href = `/projects/${projectId}/migration/steps/1`; } - return res?.error ? false : res; + return res; }; const nameValidation = (value: string) => { diff --git a/ui/src/components/Stepper/HorizontalStepper/HorizontalStepper.tsx b/ui/src/components/Stepper/HorizontalStepper/HorizontalStepper.tsx index 49c6981ef..d1d68f478 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 { Icon, cbModal, Notification,Button } from '@contentstack/venus-components'; +import { cbModal, Notification,Button } from '@contentstack/venus-components'; import { useSelector } from 'react-redux'; @@ -83,7 +83,7 @@ const HorizontalStepper = forwardRef( const [stepsCompleted, setStepsCompleted] = useState([]); const [isModalOpen, setIsModalOpen] = useState(false); - const { stepId } = useParams<{ stepId: any }>(); + const { stepId } = useParams<{ stepId: string }>(); const navigate = useNavigate(); const { projectId = '' } = useParams(); @@ -95,8 +95,9 @@ const HorizontalStepper = forwardRef( useBlockNavigation(isModalOpen); useEffect(() => { - const stepIndex = parseInt(stepId, 10) - 1; - if (!isNaN(stepIndex) && stepIndex >= 0 && stepIndex < steps?.length) { + const stepIndex = parseInt(stepId || '', 10) - 1; + + if (!Number.isNaN(stepIndex) && stepIndex >= 0 && stepIndex < steps?.length) { setShowStep(stepIndex); setStepsCompleted(prev => { const updatedStepsCompleted = [...prev]; @@ -222,5 +223,6 @@ const HorizontalStepper = forwardRef( ); } ); + HorizontalStepper.displayName = 'HorizontalStepper'; export default HorizontalStepper; diff --git a/ui/src/context/app/app.interface.ts b/ui/src/context/app/app.interface.ts index f041d293d..749bbbf3a 100644 --- a/ui/src/context/app/app.interface.ts +++ b/ui/src/context/app/app.interface.ts @@ -190,7 +190,7 @@ export interface IMigrationData { testmigrationData: ITestMigration; } -export interface IDropDown { +export interface IDropDown { uid?: string; label: string; value: string; diff --git a/ui/src/reportWebVitals.js b/ui/src/reportWebVitals.js index 532f29b0b..cf1a21212 100644 --- a/ui/src/reportWebVitals.js +++ b/ui/src/reportWebVitals.js @@ -6,6 +6,9 @@ const reportWebVitals = (onPerfEntry) => { getFCP(onPerfEntry); getLCP(onPerfEntry); getTTFB(onPerfEntry); + }) + .catch(error => { + console.error('Error:', error); }); } }; diff --git a/uplaode-api/package.json b/uplaode-api/package.json index 382b021b6..17a4b39f2 100644 --- a/uplaode-api/package.json +++ b/uplaode-api/package.json @@ -31,7 +31,7 @@ "typescript": "^5.3.3" }, "dependencies": { - "@aws-sdk/client-s3": "^3.490.0", + "@aws-sdk/client-s3": "^3.529.0", "@contentstack/cli-utilities": "^1.5.12", "@typescript-eslint/parser": "^7.7.1", "axios": "^1.6.8", @@ -52,4 +52,4 @@ "node-fetch": "^2.7.0", "prettier": "^2.7.1" } -} \ No newline at end of file +} diff --git a/uplaode-api/src/services/fileProcessing.ts b/uplaode-api/src/services/fileProcessing.ts index 4a92b700b..5df0fe6bf 100644 --- a/uplaode-api/src/services/fileProcessing.ts +++ b/uplaode-api/src/services/fileProcessing.ts @@ -10,7 +10,7 @@ const handleFileProcessing = async (fileExt: string, zipBuffer: any, cmsType: st if (fileExt === 'zip') { const zip = new JSZip(); await zip.loadAsync(zipBuffer); - if (await validator({ data: zip, type: cmsType, extension: fileExt })) { + if (validator({ data: zip, type: cmsType, extension: fileExt })) { const isSaved = await saveZip(zip); if (isSaved) { logger.info('Validation success:', { @@ -38,7 +38,7 @@ const handleFileProcessing = async (fileExt: string, zipBuffer: any, cmsType: st // if file is not zip // Convert the buffer to a string assuming it's UTF-8 encoded const jsonString = Buffer?.from?.(zipBuffer)?.toString?.('utf8'); - if (await validator({ data: jsonString, type: cmsType, extension: fileExt })) { + if (validator({ data: jsonString, type: cmsType, extension: fileExt })) { logger.info('Validation success:', { status: HTTP_CODES?.OK, message: HTTP_TEXTS?.VALIDATION_SUCCESSFULL, diff --git a/uplaode-api/tsconfig.json b/uplaode-api/tsconfig.json index 51793fe2b..dbb6d8bba 100644 --- a/uplaode-api/tsconfig.json +++ b/uplaode-api/tsconfig.json @@ -32,7 +32,7 @@ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ - // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + "typeRoots": ["./node_modules/@types", "./expree.d.ts"], /* Specify multiple folders that act like './node_modules/@types'. */ // "types": [], /* Specify type package names to be included without being referenced in a source file. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ @@ -107,6 +107,6 @@ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ "skipLibCheck": true /* Skip type checking all .d.ts files. */ }, - "include": ["src/**/*.ts"], + "include": ["src/**/*.ts", "express.d.ts"], "exclude": ["node_modules", "build"] } From a569671172603703e99fad927cc8ec2b27d6cead Mon Sep 17 00:00:00 2001 From: Sayali Joshi Date: Tue, 6 Aug 2024 12:41:47 +0530 Subject: [PATCH 2/4] [CMG-281] - Content Mapper | When an existing stack is chosen or a new stack is selected, the changes do not appear on the content mapper page until you refresh it. --- ui/src/components/ContentMapper/index.tsx | 25 ++++++++--------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/ui/src/components/ContentMapper/index.tsx b/ui/src/components/ContentMapper/index.tsx index dac1c1c23..f806f9a25 100644 --- a/ui/src/components/ContentMapper/index.tsx +++ b/ui/src/components/ContentMapper/index.tsx @@ -296,10 +296,16 @@ const ContentMapper = forwardRef(({projectData}: ContentMapperComponentProps, re .catch((err) => { console.error(err); }); - stackStatus(); + fetchExistingContentTypes(); }, []); + useEffect(() => { + if (newMigrationData?.destination_stack?.selectedStack?.value || projectData?.destination_stack_id) { + stackStatus(); + } + }, [newMigrationData?.destination_stack?.selectedStack?.value || projectData?.destination_stack_id]) + // Make title and url field non editable useEffect(() => { tableData?.forEach((field) => { @@ -390,7 +396,7 @@ const ContentMapper = forwardRef(({projectData}: ContentMapperComponentProps, re const stackStatus = async () => { const contentTypeCount = await getStackStatus( projectData?.org_id || selectedOrganisation?.value, - projectData?.destination_stack_id || newMigrationData?.destination_stack?.selectedStack?.value + newMigrationData?.destination_stack?.selectedStack?.value || projectData?.destination_stack_id ); if (contentTypeCount?.data?.contenttype_count > 0) { @@ -1142,21 +1148,6 @@ const ContentMapper = forwardRef(({projectData}: ContentMapperComponentProps, re ); }; - - useEffect(() => { - if (isUpdated) { - setTableData(updatedRows as FieldMapType[]); - setexsitingField(updatedExstingField); - setSelectedOptions(updatedSelectedOptions); - setIsUpdated(false); - } - else{ - setexsitingField({}); - setSelectedOptions([]); - - } - }, [isUpdated, OtherContentType]); - const handleSaveContentType = async () => { const orgId = selectedOrganisation?.uid; const projectID = projectId; From be715099dd8a269e5044b6afec3d2ad804032e79 Mon Sep 17 00:00:00 2001 From: Sayali Joshi Date: Tue, 6 Aug 2024 14:57:50 +0530 Subject: [PATCH 3/4] [CMG-282] - Content Mapper | LHS | On hover of Content type and Global fields icon, it shows 'content_type' and 'global_field instead of 'Content type' and 'Global field' --- .../ContentMapper/contentMapper.interface.ts | 1 + ui/src/components/ContentMapper/index.scss | 66 +++++++------ ui/src/components/ContentMapper/index.tsx | 94 +++++++++++-------- ui/src/scss/App.scss | 3 + 4 files changed, 96 insertions(+), 68 deletions(-) diff --git a/ui/src/components/ContentMapper/contentMapper.interface.ts b/ui/src/components/ContentMapper/contentMapper.interface.ts index e28d77e97..e8ec2c26c 100644 --- a/ui/src/components/ContentMapper/contentMapper.interface.ts +++ b/ui/src/components/ContentMapper/contentMapper.interface.ts @@ -138,5 +138,6 @@ export interface ContentTypeMap { export interface ContentTypeSaveHandles { handleSaveContentType: () => void; } +export type MouseOrKeyboardEvent = React.MouseEvent | React.KeyboardEvent; diff --git a/ui/src/components/ContentMapper/index.scss b/ui/src/components/ContentMapper/index.scss index 3d635b4bd..4949e1995 100644 --- a/ui/src/components/ContentMapper/index.scss +++ b/ui/src/components/ContentMapper/index.scss @@ -63,43 +63,47 @@ list-style-type: none; padding: 15px 0 15px 0; li { - align-items: center; - cursor: pointer; - display: flex; - font-size: $size-font-xl; - justify-content: space-between; - line-height: normal; - min-height: 42px; - padding: $px-8 $px-10 $px-8 $px-12; - &:hover, &.active-ct { - background-color: $color-brand-white-base; - .cms-title { - span { - color: $color-brand-primary-base; - } - } - } - .cms-title { + .list-button { align-items: center; + background: none; + cursor: pointer; display: flex; - margin-right: $px-12; - max-height: 24px; - white-space: nowrap; - width: 80%; - .tippy-wrapper { + font-size: $size-font-xl; + justify-content: space-between; + line-height: normal; + min-height: 42px; + padding: $px-8 $px-10 $px-8 $px-12; + width: 100%; + &:hover, &.active-ct { + background-color: $color-brand-white-base; + .cms-title { + span { + color: $color-brand-primary-base; + } + } + } + .cms-title { + align-items: center; display: flex; + margin-right: $px-12; + max-height: 24px; + white-space: nowrap; + width: 70%; + .tippy-wrapper { + display: flex; + } + span { + color: $color-font-base; + margin-left: $px-10; + overflow: hidden; + text-overflow: ellipsis; + } } - span { - color: $color-font-base; - margin-left: $px-10; - overflow: hidden; - text-overflow: ellipsis; + .ct-options { + justify-content: flex-end; } } - .ct-options { - justify-content: flex-end; - } - } + } } .mapped-icon { circle { diff --git a/ui/src/components/ContentMapper/index.tsx b/ui/src/components/ContentMapper/index.tsx index f806f9a25..a02a2ae3f 100644 --- a/ui/src/components/ContentMapper/index.tsx +++ b/ui/src/components/ContentMapper/index.tsx @@ -49,7 +49,8 @@ import { UidMap, ContentTypeMap, Advanced, - ContentTypeSaveHandles + ContentTypeSaveHandles, + MouseOrKeyboardEvent } from './contentMapper.interface'; import { ItemStatusMapProp } from '@contentstack/venus-components/build/components/Table/types'; import { ModalObj } from '../Modal/modal.interface'; @@ -1355,7 +1356,7 @@ const ContentMapper = forwardRef(({projectData}: ContentMapperComponentProps, re } // Function to filter content types as per the status - const handleContentTypeFilter = (value: string, e: React.MouseEvent) => { + const handleContentTypeFilter = (value: string, e: MouseOrKeyboardEvent) => { const li_list = document.querySelectorAll('.filter-wrapper li'); if(li_list) { li_list.forEach((ele) => { @@ -1425,12 +1426,18 @@ const ContentMapper = forwardRef(({projectData}: ContentMapperComponentProps, re
    {Object.keys(CONTENT_MAPPING_STATUS).map((key, keyInd) => ( - <> -
  • handleContentTypeFilter(CONTENT_MAPPING_STATUS[key], e)}> - {CONTENT_MAPPING_STATUS[key] && {CONTENT_MAPPING_STATUS[key]} } - {STATUS_ICON_Mapping[key] && } -
  • - +
  • + +
  • ))}
@@ -1443,38 +1450,51 @@ const ContentMapper = forwardRef(({projectData}: ContentMapperComponentProps, re
    {filteredContentTypes?.map((content: ContentType, index: number) => { const icon = STATUS_ICON_Mapping[content?.status] || ''; - + + const format = (str: string) => { + const frags = str.split('_'); + for (let i = 0; i < frags?.length; i++) { + frags[i] = frags[i].charAt(0).toUpperCase() + frags[i].slice(1); + } + return frags.join(' '); + } return ( -
  • handleOpenContentType(index)} - onKeyDown={() => handleOpenContentType(index)} - > -
    - - {content?.type === "content_type" - ? - : +
  • +
  • ) })} @@ -1492,7 +1512,7 @@ const ContentMapper = forwardRef(({projectData}: ContentMapperComponentProps, re canSearch={true} data={tableData?.length ? [...tableData] : []} columns={columns} - uniqueKey={'id' || ''} + uniqueKey={'id'} isRowSelect // fullRowSelect itemStatusMap={itemStatusMap} diff --git a/ui/src/scss/App.scss b/ui/src/scss/App.scss index 4e749a23a..4dc2f6cc5 100644 --- a/ui/src/scss/App.scss +++ b/ui/src/scss/App.scss @@ -419,6 +419,9 @@ h2 { border-top: 1px solid $color-brand-secondary-lightest; } } +.list-button { + border: 0 none; +} ::-webkit-input-placeholder { color: $color-stepper-title !important; } From b82bfa5be2dd3dd911b35301d9d71bc5f2fc34d7 Mon Sep 17 00:00:00 2001 From: Sayali Joshi Date: Tue, 6 Aug 2024 17:24:23 +0530 Subject: [PATCH 4/4] [CMG-283], [CMG-284] --- ui/src/components/ContentMapper/index.scss | 36 ++++++++++++---------- ui/src/components/ContentMapper/index.tsx | 15 +++++++-- ui/src/scss/App.scss | 2 ++ 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/ui/src/components/ContentMapper/index.scss b/ui/src/components/ContentMapper/index.scss index 4949e1995..612843a89 100644 --- a/ui/src/components/ContentMapper/index.scss +++ b/ui/src/components/ContentMapper/index.scss @@ -65,23 +65,13 @@ li { .list-button { align-items: center; - background: none; - cursor: pointer; display: flex; font-size: $size-font-xl; justify-content: space-between; line-height: normal; min-height: 42px; padding: $px-8 $px-10 $px-8 $px-12; - width: 100%; - &:hover, &.active-ct { - background-color: $color-brand-white-base; - .cms-title { - span { - color: $color-brand-primary-base; - } - } - } + .cms-title { align-items: center; display: flex; @@ -103,6 +93,16 @@ justify-content: flex-end; } } + &:hover, &.active-ct { + button { + background-color: $color-brand-white-base; + } + .cms-title { + span { + color: $color-brand-primary-base; + } + } + } } } .mapped-icon { @@ -247,12 +247,14 @@ div .table-row { top: $px-50; z-index: 1; li { - align-items: center; - cursor: pointer; - display: flex; - font-size: $size-font-medium; - justify-content: space-between; - padding: $px-8 $px-12; + button { + align-items: center; + display: flex; + justify-content: space-between; + font-size: $size-font-medium; + padding: $px-8 $px-12; + } + &:hover { background-color: $color-base-white-10; color: $color-brand-primary-base; diff --git a/ui/src/components/ContentMapper/index.tsx b/ui/src/components/ContentMapper/index.tsx index a02a2ae3f..838940c5d 100644 --- a/ui/src/components/ContentMapper/index.tsx +++ b/ui/src/components/ContentMapper/index.tsx @@ -1211,9 +1211,12 @@ const ContentMapper = forwardRef(({projectData}: ContentMapperComponentProps, re setisContentTypeMapped(true); setisContentTypeSaved(true); - setFilteredContentTypes(filteredContentTypes?.map(ct => + const savedCT = filteredContentTypes?.map(ct => ct?.id === data?.updatedContentType?.id ? { ...ct, status: data?.updatedContentType?.status } : ct - )); + ); + + setFilteredContentTypes(savedCT); + setContentTypes(savedCT); } else { Notification({ notificationContent: { text: data?.error?.message }, @@ -1365,8 +1368,8 @@ const ContentMapper = forwardRef(({projectData}: ContentMapperComponentProps, re } (e?.target as HTMLElement)?.closest('li')?.classList?.add('active-filter'); - const filteredCT = contentTypes?.filter((ct) => {return CONTENT_MAPPING_STATUS[ct?.status] === value}); + const filteredCT = contentTypes?.filter((ct) => {return CONTENT_MAPPING_STATUS[ct?.status] === value}); if (value !== 'All') { setFilteredContentTypes(filteredCT); setCount(filteredCT?.length); @@ -1428,6 +1431,8 @@ const ContentMapper = forwardRef(({projectData}: ContentMapperComponentProps, re {Object.keys(CONTENT_MAPPING_STATUS).map((key, keyInd) => (