From 4cf5d93c0421bce8cd8b910ace52bc17ba5a990a Mon Sep 17 00:00:00 2001 From: AishDani Date: Mon, 10 Jun 2024 00:22:06 +0530 Subject: [PATCH 01/19] refactor:code according to new design --- ui/src/cmsData/legacyCms.json | 158 ++++++++++--- ui/src/components/Common/Card/card.scss | 10 +- ui/src/components/Common/Card/card.tsx | 12 +- .../LegacyCms/Actions/LoadFileFormat.tsx | 60 +++-- .../LegacyCms/Actions/LoadPrefix.tsx | 87 ++++++-- .../LegacyCms/Actions/LoadSelectCms.tsx | 189 +++++++++------- .../LegacyCms/Actions/LoadUploadFile.tsx | 146 +++++++++--- ui/src/components/LegacyCms/StepperSteps.ts | 3 +- .../LegacyCms/Summary/UploadFileSummary.tsx | 15 +- .../components/LegacyCms/Summary/summary.scss | 4 +- ui/src/components/LegacyCms/index.tsx | 207 +++++++++--------- ui/src/components/LegacyCms/legacyCms.scss | 42 +++- .../LegacyCms/restrictedKeywords.json | 47 ++++ .../NewMigration/NewMigrationWrapper.tsx | 7 +- .../Stepper/FlowStepper/FlowBlockItem.tsx | 1 - .../VerticalStepper/AutoVerticalStepper.scss | 12 +- .../VerticalStepper/AutoVerticalStepper.tsx | 4 +- ui/src/context/app/app.interface.ts | 16 +- 18 files changed, 703 insertions(+), 317 deletions(-) create mode 100644 ui/src/components/LegacyCms/restrictedKeywords.json diff --git a/ui/src/cmsData/legacyCms.json b/ui/src/cmsData/legacyCms.json index ad07c4b3..26068635 100644 --- a/ui/src/cmsData/legacyCms.json +++ b/ui/src/cmsData/legacyCms.json @@ -13,7 +13,7 @@ "title": "https://www.contentstack.com/", "href": "https://www.contentstack.com/" }, - "parent": "", + "parent": "Contentstack", "isactive": true, "allowed_file_formats": [ { @@ -50,7 +50,7 @@ "title": "https://www.contentful.com/", "href": "https://www.contentful.com/" }, - "parent": "", + "parent": "Contentful", "isactive": true, "allowed_file_formats": [ { @@ -77,7 +77,7 @@ "title": "https://wordpress.com/", "href": "https://wordpress.com/" }, - "parent": "", + "parent": "Wordpress", "isactive": true, "allowed_file_formats": [ { @@ -85,7 +85,7 @@ "_metadata": { "uid": "csacaafbc5e52ee0ef" }, - "title": "XML", + "title": "Xml", "description": "", "group_name": "xml", "isactive": true @@ -108,17 +108,71 @@ "isactive": true, "allowed_file_formats": [ { - "fileformat_id": "sql", + "fileformat_id": "zip", "_metadata": { "uid": "cs5d9c8914dc21ea80" }, - "title": "SQL", + "title": "Zip", "description": "", - "group_name": "sql", + "group_name": "zip", "isactive": true } ] }, + { + "cms_id": "drupal v7", + "title": "Drupal v7", + "description": "", + "group_name": "lightning", + "doc_url": { + "title": "https://www.drupal.org/", + "href": "https://www.drupal.org/" + }, + "parent": "Drupal", + "isactive": true, + "allowed_file_formats": [ + { + "fileformat_id": "sql", + "title": "Sql", + "description": "", + "group_name": "sql", + "isactive": true, + "_metadata": { + "uid": "csceba83e388748bf1" + } + } + ], + "_metadata": { + "uid": "cs88cc83ef30625782" + } + }, + { + "cms_id": "drupal v8+", + "title": "Drupal v8+", + "description": "", + "group_name": "lightning", + "doc_url": { + "title": "https://www.drupal.org/", + "href": "https://www.drupal.org/" + }, + "parent": "Drupal", + "isactive": true, + "allowed_file_formats": [ + { + "fileformat_id": "sql", + "title": "Sql", + "description": "", + "group_name": "sql", + "isactive": true, + "_metadata": { + "uid": "csce12ba4b8be62108" + } + } + ], + "_metadata": { + "uid": "cs65a0fe53fc587481" + } + }, { "cms_id": "aem", "_metadata": { @@ -135,23 +189,47 @@ "isactive": true, "allowed_file_formats": [ { - "fileformat_id": "json", + "fileformat_id": "zip", "_metadata": { "uid": "cs08dadd206cfa53b4" }, - "title": "JSON", + "title": "Zip", "description": "", - "group_name": "json", + "group_name": "zip", "isactive": true } ] }, { - "cms_id": "sitecore", - "_metadata": { - "uid": "cs1c20c0a62eaf4b89" + "cms_id": "sitecore v8", + "title": "Sitecore v8", + "description": "", + "group_name": "lightning", + "doc_url": { + "title": "https://www.sitecore.com/", + "href": "https://www.sitecore.com/" }, - "title": "Sitecore", + "parent": "Sitecore", + "isactive": true, + "allowed_file_formats": [ + { + "fileformat_id": "zip", + "title": "Zip", + "description": "", + "group_name": "zip", + "isactive": true, + "_metadata": { + "uid": "cs7b44e4f248dbdc92" + } + } + ], + "_metadata": { + "uid": "csef3e4691c7e23a2d" + } + }, + { + "cms_id": "sitecore v9", + "title": "Sitecore v9", "description": "", "group_name": "lightning", "doc_url": { @@ -163,15 +241,45 @@ "allowed_file_formats": [ { "fileformat_id": "zip", + "title": "Zip", + "description": "", + "group_name": "zip", + "isactive": true, "_metadata": { - "uid": "csd2c76964ab6c1fdb" - }, + "uid": "cs47d2095581add21f" + } + } + ], + "_metadata": { + "uid": "cse88f8602ab676db3" + } + }, + { + "cms_id": "sitecore v10", + "title": "Sitecore v10", + "description": "", + "group_name": "lightning", + "doc_url": { + "title": "https://www.sitecore.com/", + "href": "https://www.sitecore.com/" + }, + "parent": "Sitecore", + "isactive": true, + "allowed_file_formats": [ + { + "fileformat_id": "zip", "title": "Zip", "description": "", "group_name": "zip", - "isactive": true + "isactive": true, + "_metadata": { + "uid": "cs882b321665f69cfd" + } } - ] + ], + "_metadata": { + "uid": "cs67770c22aae86b7b" + } }, { "cms_id": "othercms", @@ -189,13 +297,13 @@ "isactive": true, "allowed_file_formats": [ { - "fileformat_id": "json", + "fileformat_id": "zip", "_metadata": { "uid": "cs751db98402e685fe" }, - "title": "JSON", + "title": "Zip", "description": "", - "group_name": "json", + "group_name": "zip", "isactive": true } ] @@ -205,10 +313,10 @@ "locale": "en-us", "uid": "blt1f83a8b93dd822ae", "created_by": "blt7710245564fbf52b", - "updated_by": "blt7710245564fbf52b", + "updated_by": "blt74f496d523384141", "created_at": "2024-01-23T09:41:52.061Z", - "updated_at": "2024-02-22T11:28:29.742Z", - "_version": 24, + "updated_at": "2024-06-07T09:23:01.470Z", + "_version": 25, "_in_progress": false, "cta": "Proceed to Destination Stack", "all_steps": [ @@ -269,4 +377,4 @@ "restricted_keyword_checkbox_text": "Please acknowledge that you have referred to the Contentstack restricted keywords", "affix_cta": "Continue", "file_format_cta": "Continue" -} +} \ No newline at end of file diff --git a/ui/src/components/Common/Card/card.scss b/ui/src/components/Common/Card/card.scss index 9e57a163..6d90f282 100644 --- a/ui/src/components/Common/Card/card.scss +++ b/ui/src/components/Common/Card/card.scss @@ -5,6 +5,8 @@ display: flex; flex-wrap: wrap; gap: $px-12; + margin-left: 10px !important; + margin-bottom: 10px; } .trigger_list { @@ -22,12 +24,15 @@ .connector_list, .action_list, .trigger_list { - border: 1px solid $color-base-gray-40; + //border: 1px solid $color-base-gray-40; + border: 1px solid #6C5CE766; border-radius: $px-6; flex: 0 10%; cursor: pointer; min-width: $px-117; text-align: center; + height: 128px; + gap: 12px; } .connector_list .tippy-box-light #automationConnectorsHelpText { @@ -62,3 +67,6 @@ margin-top: 3.5rem; z-index: 8; } +.centered-card-title{ + margin: 10px; +} diff --git a/ui/src/components/Common/Card/card.tsx b/ui/src/components/Common/Card/card.tsx index 1f536377..cfcb986b 100644 --- a/ui/src/components/Common/Card/card.tsx +++ b/ui/src/components/Common/Card/card.tsx @@ -55,7 +55,7 @@ const Card = ({ data, selectedCard, onCardClick, cardType, idField = 'id' }: Car )} - {/* {isHovered || selectedCard[idField] === data[idField] ? ( - + ) : ( <> )} - */} +
- + /> */}
-
+
diff --git a/ui/src/components/LegacyCms/Actions/LoadFileFormat.tsx b/ui/src/components/LegacyCms/Actions/LoadFileFormat.tsx index c333f9fb..186a335b 100644 --- a/ui/src/components/LegacyCms/Actions/LoadFileFormat.tsx +++ b/ui/src/components/LegacyCms/Actions/LoadFileFormat.tsx @@ -1,7 +1,7 @@ // Libraries import { ChangeEvent, useContext, useEffect, useState } from 'react'; import { useParams } from 'react-router'; -import { Button } from '@contentstack/venus-components'; +import { Button, Icon, TextInput } from '@contentstack/venus-components'; import { useDispatch, useSelector } from 'react-redux'; // Utilities @@ -43,17 +43,18 @@ const LoadFileFormat = (props: LoadFileFormatProps) => { newMigrationData?.legacy_cms?.selectedFileFormat ?? defaultCardType ); const [isCheckedBoxChecked, setIsCheckedBoxChecked] = useState( - newMigrationData?.legacy_cms?.isFileFormatCheckboxChecked || false + newMigrationData?.legacy_cms?.isFileFormatCheckboxChecked || true ); const { projectId = '' } = useParams(); const { allowed_file_formats = [], doc_url = { href: '', title: '' } } = newMigrationData?.legacy_cms?.selectedCms || {}; + /**** ALL METHODS HERE ****/ - const handleBtnClick = async (e: MouseEvent) => { - e.preventDefault(); + const handleBtnClick = async () => { + if (!isEmptyString(selectedCard?.fileformat_id) && isCheckedBoxChecked) { dispatch(updateNewMigrationData({ ...newMigrationData, @@ -72,7 +73,7 @@ const LoadFileFormat = (props: LoadFileFormatProps) => { }); //call for Step Change - props.handleStepChange(props?.currentStep); + props.handleStepChange(props?.currentStep, true); } }; @@ -100,6 +101,7 @@ const LoadFileFormat = (props: LoadFileFormatProps) => { } }; dispatch(updateNewMigrationData(newMigrationDataObj)); + handleBtnClick(); } }, [allowed_file_formats]); @@ -107,42 +109,60 @@ const LoadFileFormat = (props: LoadFileFormatProps) => { return (
- -
+ /> */} +
Following is the file format in which data is exported from your current CMS
-
+
{validateArray(allowed_file_formats) ? ( allowed_file_formats?.map((data: ICardType, index: number) => ( - { - return; - }} - /> + + + // { + // return; + // }} + // /> + + +
+ + } + /> + +
)) ) : ( <>No File formats available )}
-
+ {/*
-
+
*/}
); }; diff --git a/ui/src/components/LegacyCms/Actions/LoadPrefix.tsx b/ui/src/components/LegacyCms/Actions/LoadPrefix.tsx index 42f07c68..f602d702 100644 --- a/ui/src/components/LegacyCms/Actions/LoadPrefix.tsx +++ b/ui/src/components/LegacyCms/Actions/LoadPrefix.tsx @@ -1,5 +1,5 @@ // Libraries -import { ChangeEvent, useEffect, useState } from 'react'; +import { ChangeEvent, useState } from 'react'; import { useParams } from 'react-router'; import { useDispatch, useSelector } from 'react-redux'; @@ -9,20 +9,23 @@ import { updateAffixData, affixConfirmation } from '../../../services/api/migrat // Utilities import { isEmptyString, isValidPrefix } from '../../../utilities/functions'; -// Context -import { AppContext } from '../../../context/app/app.context'; // Interface import { DEFAULT_URL_TYPE, INewMigration } from '../../../context/app/app.interface'; // Style import '../legacyCms.scss'; -import { Button, TextInput } from '@contentstack/venus-components'; +import { Icon, TextInput } from '@contentstack/venus-components'; import { useDebouncer } from '../../../hooks'; import DocLink from '../../../components/Common/DocLink/DocLink'; import { RootState } from '../../../store'; import { updateNewMigrationData } from '../../../store/slice/migrationDataSlice'; +//import restricted keywords +import restrictedKeywords from '../restrictedKeywords.json'; +import { set } from 'mongoose'; + + interface LoadSelectCmsProps { stepComponentProps: any; currentStep: number; @@ -40,16 +43,21 @@ const LoadPreFix = (props: LoadSelectCmsProps) => { const [prefix, setPrefix] = useState(newMigrationData?.legacy_cms?.affix || ''); const [isError, setIsError] = useState(false); + const [errorMessage, setErrorMessage] = useState(''); const [isCheckedBoxChecked, setIsCheckedBoxChecked] = useState( newMigrationData?.legacy_cms?.isRestictedKeywordCheckboxChecked || false ); + const [isRestrictedkey, setIsRestrictedKey] = useState(false); const { projectId = '' } = useParams(); + const idArray = restrictedKeywords.idArray; + + /**** ALL METHODS HERE ****/ //Handle Prefix Change - const handleOnBlur = async (e: MouseEvent) => { + const handleOnBlur = async (e: any) => { e.preventDefault(); if (!isEmptyString(prefix) && !isError && isCheckedBoxChecked) { const newMigrationDataObj: INewMigration = { @@ -80,17 +88,49 @@ const LoadPreFix = (props: LoadSelectCmsProps) => { //setIsError(true); }; - const handleOnChange = useDebouncer((e: ChangeEvent) => { + const handleOnChange = useDebouncer(async(e: ChangeEvent) => { e.preventDefault(); - const { value } = e.target; - if (!isEmptyString(value) && isValidPrefix(value)) { - setPrefix(value); - setIsError(false); - return; - } + const value = e.target.value; + if (!isEmptyString(value) && isValidPrefix(value) ) { + if(! idArray?.includes(value)){ + setPrefix(value); + setIsError(false); + setErrorMessage(''); + setIsRestrictedKey(false); + const newMigrationDataObj: INewMigration = { + ...newMigrationData, + legacy_cms: { + ...newMigrationData.legacy_cms, + affix: value, + isRestictedKeywordCheckboxChecked: isCheckedBoxChecked + } + }; + + dispatch(updateNewMigrationData(newMigrationDataObj)); + + setIsError(false); + + //API call for saving Affix + await updateAffixData(selectedOrganisation?.value, projectId, { affix: value }); + await affixConfirmation(selectedOrganisation?.value, projectId, { + affix_confirmation: isCheckedBoxChecked + }); + + //call for Step Change + props.handleStepChange(props.currentStep, true); + return; + } + else{ + setIsError(true); + setErrorMessage('Affix should be valid and not a restricted keyword'); + setIsRestrictedKey(true); + return; + } + } setIsError(true); + setErrorMessage('Affix should not be more than 5 chars'); }); // Toggles checkbox selection @@ -115,18 +155,18 @@ const LoadPreFix = (props: LoadSelectCmsProps) => { migrationData.legacyCMSData; return ( -
- + {/* + /> */}
{handleOnChange(e)}} value={prefix} autoFocus={true} width="large" @@ -134,13 +174,22 @@ const LoadPreFix = (props: LoadSelectCmsProps) => { version="v2" error={isError} /> - {isError &&

Affix should not be more than 5 chars

} + {isError &&

{errorMessage}

} +
-
+ { isRestrictedkey && +
+

Please refer the list of Contentstack restricted keywords

+ + + {restricted_keyword_link?.title} + +
} + {/*
-
+
*/}
); }; diff --git a/ui/src/components/LegacyCms/Actions/LoadSelectCms.tsx b/ui/src/components/LegacyCms/Actions/LoadSelectCms.tsx index 70d926dc..604308b8 100644 --- a/ui/src/components/LegacyCms/Actions/LoadSelectCms.tsx +++ b/ui/src/components/LegacyCms/Actions/LoadSelectCms.tsx @@ -10,8 +10,6 @@ import { fileValidation, getConfig } from '../../../services/api/upload.service' // Utilities import { isEmptyString, validateArray } from '../../../utilities/functions'; -// Context -import { AppContext } from '../../../context/app/app.context'; // Interface import { defaultCardType } from '../../../components/Common/Card/card.interface'; @@ -42,26 +40,56 @@ const LoadSelectCms = (props: LoadSelectCmsProps) => { const selectedOrganisation = useSelector((state:RootState)=>state?.authentication?.selectedOrganisation); const dispatch = useDispatch(); - - const [selectedCard, setSelectedCard] = useState( - newMigrationData?.legacy_cms?.selectedCms || defaultCardType - ); const [cmsData, setCmsData] = useState([]); const [searchText, setSearchText] = useState(''); const [cmsFilterStatus, setCmsFilterStatus] = useState({}); const [cmsFilter, setCmsFilter] = useState([]); - const [cmsType, setCmsType] = useState( - newMigrationData?.legacy_cms?.selectedCms?.title?.toLowerCase() + const [cmsType, setCmsType] = useState( + newMigrationData?.legacy_cms?.selectedCms ); + const [selectedCard, setSelectedCard] = useState( + newMigrationData?.legacy_cms?.selectedCms + ); + const [errorMessage, setErrorMessage] = useState(''); + const [isError, setIsError] = useState(false); + + + const { projectId = '' } = useParams(); /**** ALL METHODS HERE ****/ //Handle Legacy cms selection + const handleCardClick = async(data: ICMSType) => { + + const isSingleMatch = cmsData.length === 1; + + if (isSingleMatch || selectedCard?.title !== data?.title) { + setSelectedCard({ ...data }); + + const newMigrationDataObj: INewMigration = { + ...newMigrationData, + legacy_cms: { + ...newMigrationData.legacy_cms, + selectedCms: { ...data } + } + }; + + dispatch(updateNewMigrationData(newMigrationDataObj)); + + //API call for saving selected CMS + const res = await updateLegacyCMSData(selectedOrganisation.value, projectId, { legacy_cms: data?.cms_id }); + + // Call for Step Change + props.handleStepChange(props.currentStep, true); + } + }; + + const handleDirectSelection = async (cms: any) => { - setSelectedCard(cms); + setSelectedCard(cms); dispatch(updateNewMigrationData({ ...newMigrationData?.legacy_cms, @@ -70,7 +98,7 @@ const LoadSelectCms = (props: LoadSelectCmsProps) => { selectedCms: cms } })) - + const res = await updateLegacyCMSData(selectedOrganisation.value, projectId, { legacy_cms: cms}); if (!isEmptyString(cms?.title)) { props?.handleStepChange(props?.currentStep); @@ -96,24 +124,27 @@ const LoadSelectCms = (props: LoadSelectCmsProps) => { // Filter CMS Data const filterCMSData = async (searchText: string) => { - const { all_cms = [] } = migrationData?.legacyCMSData || {}; + const { all_cms = [] } = migrationData?.legacyCMSData || {}; + setSelectedCard(cmsType); const apiRes: any = await getConfig(); // api call to get cms type from upload service const cms = apiRes?.data?.cmsType?.toLowerCase(); - const cmstype = !isEmptyString(cmsType) ? cmsType : cms; // Fetch the specific CMS type + + if(isEmptyString(cmsType?.cms_id)){ + setCmsType(cms); + } + + const cmstype = !isEmptyString(cmsType?.cms_id) ? cmsType?.parent : cms; // Fetch the specific CMS type - let filteredCmsData: ICMSType[] = []; - if (isEmptyString(searchText) && !validateArray(cmsFilter) && !cmstype) { - filteredCmsData = all_cms; - } else { - if (cmstype) { - filteredCmsData = all_cms?.filter((cms: ICMSType) => cms?.cms_id === cmstype); - } + let filteredCmsData = all_cms; + if (cmstype) { + filteredCmsData = all_cms.filter((cms: ICMSType) => cms?.parent?.toLowerCase() === cmstype?.toLowerCase()); } + - setCmsData(filteredCmsData); + setCmsData(filteredCmsData) //Normal Search const _filterCmsData = validateArray(all_cms) @@ -127,14 +158,20 @@ const LoadSelectCms = (props: LoadSelectCmsProps) => { setCmsData(_filterCmsData); - const newSelectedCard = filteredCmsData?.some((cms) => cms?.cms_id === cmstype) - ? filteredCmsData?.[0] - : DEFAULT_CMS_TYPE; + + + let newSelectedCard: ICMSType | undefined; - setSelectedCard(newSelectedCard); + if (_filterCmsData.length === 1) { + newSelectedCard = filteredCmsData[0]; + } else { + newSelectedCard = filteredCmsData.find((cms: ICMSType) => cms?.parent.toLowerCase() === cmstype.toLowerCase()); + } if (newSelectedCard) { setSelectedCard(newSelectedCard); + setErrorMessage(''); + setIsError(false); const newMigrationDataObj: INewMigration = { ...newMigrationData, @@ -146,6 +183,9 @@ const LoadSelectCms = (props: LoadSelectCmsProps) => { dispatch(updateNewMigrationData(newMigrationDataObj)); + }else{ + setIsError(true); + setErrorMessage('No matching CMS found. Please try a different search term.'); } }; @@ -158,71 +198,56 @@ const LoadSelectCms = (props: LoadSelectCmsProps) => { filterCMSData(searchText); }, [cmsFilter]); - useEffect(() => { - if (selectedCard?.title !== 'Drupal' && selectedCard?.title !== 'Sitecore') { - handleDirectSelection(selectedCard); - } - }, [cmsType, selectedCard]); - + // useEffect(() => { + // if (selectedCard?.title !== 'Drupal' && selectedCard?.title !== 'Sitecore') { + // handleDirectSelection(selectedCard); + // } + // }, [cmsType, selectedCard]); return (
- {(cmsType === 'sitecore' || cmsType === 'drupal') && ( -
-
-
- { - setSearchText(text?.toLowerCase()); - filterCMSData(text?.toLowerCase()); - }} +
+ {/*
+ setSearchText(text?.toLowerCase())} + /> +
+ */} +
+ { isError ? +
+ No matching CMS found!
} + img={SEARCH_ICON} /> -
- -
- -
- {cmsData && validateArray(cmsData) ? ( -
- {cmsData?.map((data: ICMSType) => ( - - ))}
- ) : ( -
- No matching CMS found!
} - img={SEARCH_ICON} - description={ -
- Try changing your search term to find what you are looking for. -
- } + : + ( + cmsData && validateArray(cmsData) && ( +
+ {cmsData.map((data: ICMSType) => ( + -
- )} -
-
- )} - - {isEmptyString(newMigrationData?.legacy_cms?.selectedCms?.title) && ( -
- Please enter the correct CMS + ))} +
+ ) + ) + } +
- )} +
); }; diff --git a/ui/src/components/LegacyCms/Actions/LoadUploadFile.tsx b/ui/src/components/LegacyCms/Actions/LoadUploadFile.tsx index ef347ac9..01a44b0f 100644 --- a/ui/src/components/LegacyCms/Actions/LoadUploadFile.tsx +++ b/ui/src/components/LegacyCms/Actions/LoadUploadFile.tsx @@ -1,48 +1,135 @@ -import { useEffect } from 'react'; +import { useEffect, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import DragAndDropFileUpload from '../../../components/Common/FileUpload'; -import { AppContext } from '../../../context/app/app.context'; -import { DEFAULT_FILE, IFile, INewMigration } from '../../../context/app/app.interface'; -import { validateArray } from '../../../utilities/functions'; +import { DEFAULT_FILE, FileDetails, INewMigration } from '../../../context/app/app.interface'; + import { useParams } from 'react-router'; -import { fileValidation } from '../../../services/api/upload.service'; +import { fileValidation, getConfig } from '../../../services/api/upload.service'; import { RootState } from '../../../store'; import { updateNewMigrationData } from '../../../store/slice/migrationDataSlice'; +//import { FileComponent } from '../Summary/UploadFileSummary'; +import { Button, Paragraph } from '@contentstack/venus-components'; + interface LoadUploadFileProps { stepComponentProps: any; currentStep: number; handleStepChange: (stepIndex: number, closeStep: boolean) => void; } +interface Props { + fileDetails: FileDetails; +} + +const FileComponent = ({fileDetails}:Props ) => { + + return ( +
+ {fileDetails?.isLocalPath ? ( +
+ + +
+ ) : ( +
+

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

+

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

+

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

+
+ )} +
+ ); +}; + const LoadUploadFile = (props: LoadUploadFileProps) => { /**** ALL HOOKS HERE ****/ const newMigrationData = useSelector((state:RootState)=>state?.migration?.newMigrationData); + const dispatch = useDispatch(); + const [isLoading, setIsLoading] = useState(false); + const [isValidated, setIsValidated] = useState(false); + const [showMessage, setShowMessage] = useState(false); + const [validationMessgae, setValidationMessage] = useState(''); + const [isValidationAttempted, setIsValidationAttempted] = useState(false); const { projectId = '' } = useParams(); //Handle further action on file is uploaded to server const handleOnFileUploadCompletion = async () => { + setIsLoading(true); + const res: any = await fileValidation(); + + if(res?.status === 200){ + setIsValidated(true); + setValidationMessage('Validated'); + const newMigrationDataObj: INewMigration = { + ...newMigrationData, + legacy_cms: { + ...newMigrationData.legacy_cms, + uploadedFile: { + name: res?.data?.localPath, + url: res?.data?.localPath, + validation: res?.data?.message, + isValidated: res?.status == 200 ? true : false, + file_details: { + isLocalPath: res?.data?.file_details?.isLocalPath, + cmsType: res?.data?.file_details?.cmsType, + localPath: res?.data?.file_details?.localPath, + awsData: { + awsRegion: res?.data?.file_details?.awsData?.awsRegion, + bucketName: res?.data?.file_details?.awsData?.bucketName, + buketKey: res?.data?.file_details?.awsData?.buketKey + } + } + + } + } + }; + dispatch(updateNewMigrationData(newMigrationDataObj)); + + props.handleStepChange(props?.currentStep, true); + + + } + else{ + setIsValidated(false); + setValidationMessage('Validation Falied'); + setIsValidationAttempted(true) + + } + + setShowMessage(true); + setIsLoading(false); + + + }; + + //function to get config details + const getConfigDetails = async () =>{ + const res: any = await getConfig(); + if(newMigrationData?.legacy_cms?.selectedCms?.parent.toLowerCase() !== res?.data?.cmsType.toLowerCase()){ + setIsValidated(false); + setValidationMessage('Validation Falied'); + setIsValidationAttempted(true); + setShowMessage(true); + setIsLoading(false); + } const newMigrationDataObj: INewMigration = { ...newMigrationData, legacy_cms: { ...newMigrationData.legacy_cms, uploadedFile: { - name: res?.data?.file_details?.localPath, - url: res?.data?.file_details?.localPath, - validation: res?.data?.message, - isValidated: res?.data?.status == 200 ? true : false, + name: res?.data?.localPath, + url: res?.data?.localPath, file_details: { - isLocalPath: res?.data?.file_details?.isLocalPath, - cmsType: res?.data?.file_details?.cmsType, - localPath: res?.data?.file_details?.localPath, + isLocalPath: res?.data?.isLocalPath, + cmsType: res?.data?.cmsType, + localPath: res?.data?.localPath, awsData: { - awsRegion: res?.data?.file_details?.awsData?.awsRegion, - bucketName: res?.data?.file_details?.awsData?.bucketName, - buketKey: res?.data?.file_details?.awsData?.buketKey + awsRegion: res?.data?.awsData?.awsRegion, + bucketName: res?.data?.awsData?.bucketName, + buketKey: res?.data?.awsData?.buketKey } } } @@ -50,28 +137,35 @@ const LoadUploadFile = (props: LoadUploadFileProps) => { }; dispatch(updateNewMigrationData(newMigrationDataObj)); - props.handleStepChange(props?.currentStep, true); - }; + } const allowedFileExtentions = `.${ newMigrationData?.legacy_cms?.selectedFileFormat?.title || 'zip' }`; + useEffect(() => { - handleOnFileUploadCompletion(); + getConfigDetails(); }, []); + const validationClassName = isValidated ? 'success' : 'error'; + + const containerClassName = `validation-container ${isValidationAttempted && !isValidated ? 'error-container' : ''}`; + return (
- {/* */}
-
- +
+ + {showMessage && + () + } +
+
diff --git a/ui/src/components/LegacyCms/StepperSteps.ts b/ui/src/components/LegacyCms/StepperSteps.ts index 08d5e004..423bc0ce 100644 --- a/ui/src/components/LegacyCms/StepperSteps.ts +++ b/ui/src/components/LegacyCms/StepperSteps.ts @@ -15,8 +15,7 @@ const getComponentObject = ( isCompleted: boolean, isMigrationLocked: boolean ): IStep => { - let updatedStep = { ...step }; - + let updatedStep = { ...step }; switch (step.step_id) { case 'Step1': { // Insert Data, Summary component, and status diff --git a/ui/src/components/LegacyCms/Summary/UploadFileSummary.tsx b/ui/src/components/LegacyCms/Summary/UploadFileSummary.tsx index 0311177b..11a16035 100644 --- a/ui/src/components/LegacyCms/Summary/UploadFileSummary.tsx +++ b/ui/src/components/LegacyCms/Summary/UploadFileSummary.tsx @@ -1,4 +1,4 @@ -import { useContext } from 'react'; +import { useContext, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { AppContext } from '../../../context/app/app.context'; import './summary.scss'; @@ -12,17 +12,20 @@ interface UploadFileSummaryProps { import { FileDetails } from '../../../context/app/app.interface'; import { RootState } from '../../../store'; +import { Paragraph } from '@contentstack/venus-components'; interface Props { fileDetails: FileDetails; } -const FileComponent: React.FC = ({ fileDetails }) => { +export const FileComponent: React.FC = ({ fileDetails }) => { + return ( -
+
{fileDetails?.isLocalPath ? (
-

Local Path: {fileDetails?.localPath}

+ +
) : (
@@ -41,12 +44,12 @@ const UploadFileSummary = ({ }: 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} diff --git a/ui/src/components/LegacyCms/Summary/summary.scss b/ui/src/components/LegacyCms/Summary/summary.scss index 05e61915..bb9cb6e9 100644 --- a/ui/src/components/LegacyCms/Summary/summary.scss +++ b/ui/src/components/LegacyCms/Summary/summary.scss @@ -1,12 +1,12 @@ @import '../../../scss/variables'; .summary-title { - font-family: $font-family-primary; + //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; + //color: $color-font-black; margin-top: 3px; } diff --git a/ui/src/components/LegacyCms/index.tsx b/ui/src/components/LegacyCms/index.tsx index 75415545..f515b14b 100644 --- a/ui/src/components/LegacyCms/index.tsx +++ b/ui/src/components/LegacyCms/index.tsx @@ -22,7 +22,7 @@ import { updateCurrentStepData, updateLegacyCMSData } from '../../services/api/m import { MigrationResponse } from '../../services/api/service.interface'; import { getCMSDataFromFile } from '../../cmsData/cmsSelector'; import { RootState } from '../../store'; -import { setMigrationData, setNewMigrationData, updateMigrationData } from '../../store/slice/migrationDataSlice'; +import { updateMigrationData, updateNewMigrationData } from '../../store/slice/migrationDataSlice'; type LegacyCMSComponentProps = { @@ -32,10 +32,9 @@ type LegacyCMSComponentProps = { }; const LegacyCMSComponent = ({ legacyCMSData, projectData, handleStepChange }: LegacyCMSComponentProps) => { - //react-redux apis const migrationData = useSelector((state:RootState)=>state?.migration?.migrationData); - const newMigrationData=useSelector((state:RootState)=>state?.migration?.newMigrationData); + const newMigrationData = useSelector((state:RootState)=>state?.migration?.newMigrationData); const selectedOrganisation = useSelector((state:RootState)=>state?.authentication?.selectedOrganisation); const dispatch = useDispatch(); @@ -83,110 +82,109 @@ const LegacyCMSComponent = ({ legacyCMSData, projectData, handleStepChange }: Le }; /********** ALL USEEFFECT HERE *************/ - const fetchCMSData = async () => { - setIsLoading(true); - - //check if offline CMS data field is set to true, if then read data from cms data file. - const data = await getCMSDataFromFile(CS_ENTRIES.LEGACY_CMS); - - //fetch Legacy CMS Component Data from Contentstack CMS - //const data = await getEntries({ contentType: CS_ENTRIES.LEGACY_CMS }) - - //Check for null - if (!data) { - dispatch(updateMigrationData({ legacyCMSData: DEFAULT_LEGACY_CMS_DATA })); - setIsLoading(false); - return; - } - - //Generate CMS Filter List - const cmsFilterList: IFilterType[] = []; - //Step1: traverse on all cms and check for parent , - //Step2: if exist and not yet added in CMS filter list then push to array. - //Step 3: Update it in APP context for later use - validateArray(data?.all_cms) && - data?.all_cms?.forEach((cms: ICMSType) => { - if (!isEmptyString(cms.parent)) { - const filterObject = cmsFilterList?.find( - (obj: IFilterType) => obj.value === cms.parent - ); - - if (!filterObject) { - cmsFilterList.push({ - value: cms.parent, - label: cms.parent, - isChecked: false - }); + useEffect(() => { + const fetchCMSData = async () => { + setIsLoading(true); + + //check if offline CMS data field is set to true, if then read data from cms data file. + const data = await getCMSDataFromFile(CS_ENTRIES.LEGACY_CMS); + + //fetch Legacy CMS Component Data from Contentstack CMS + //const data = await getEntries({ contentType: CS_ENTRIES.LEGACY_CMS }) + + //Check for null + if (!data) { + dispatch(updateMigrationData({ legacyCMSData: DEFAULT_LEGACY_CMS_DATA })); + setIsLoading(false); + return; + } + + //Generate CMS Filter List + const cmsFilterList: IFilterType[] = []; + + //Step1: traverse on all cms and check for parent , + //Step2: if exist and not yet added in CMS filter list then push to array. + //Step 3: Update it in APP context for later use + validateArray(data?.all_cms) && + data?.all_cms?.forEach((cms: ICMSType) => { + if (!isEmptyString(cms.parent)) { + const filterObject = cmsFilterList?.find( + (obj: IFilterType) => obj.value === cms.parent + ); + + if (!filterObject) { + cmsFilterList.push({ + value: cms.parent, + label: cms.parent, + isChecked: false + }); + } } - } - }); - - const legacyCMSDataMapped: ILegacyCMSComponent = { - ...data, - all_steps: getLegacyCMSSteps(isCompleted, isMigrationLocked, data?.all_steps), - cmsFilterList: cmsFilterList - }; - - dispatch(updateMigrationData({ legacyCMSData: legacyCMSDataMapped })); - - //Update New Migration data - - const selectedCmsData: ICMSType = validateArray(data.all_cms) - ? data.all_cms?.find((cms: ICMSType) => cms?.cms_id === legacyCMSData?.cms) || - DEFAULT_CMS_TYPE - : DEFAULT_CMS_TYPE; - - const selectedFileFormatData: ICardType | undefined = validateArray( - selectedCmsData?.allowed_file_formats - ) - ? selectedCmsData.allowed_file_formats?.find( - (cms: ICardType) => cms?.fileformat_id === legacyCMSData?.file_format - ) - : defaultCardType; - - //Make Step 1 Complete - if (!isEmptyString(selectedCmsData?.cms_id)) { - setInternalActiveStepIndex(0); - } - - //Make Step 2 complete - if (!isEmptyString(selectedCmsData?.cms_id) && !isEmptyString(legacyCMSData?.affix)) { - setInternalActiveStepIndex(1); - } - - //Make Step 3 complete - if ( - !isEmptyString(selectedCmsData?.cms_id) && - !isEmptyString(legacyCMSData?.affix) && - !isEmptyString(selectedFileFormatData?.fileformat_id) - ) { - setInternalActiveStepIndex(2); - } + }); + + const legacyCMSDataMapped: ILegacyCMSComponent = { + ...data, + all_steps: getLegacyCMSSteps(isCompleted, isMigrationLocked, data?.all_steps), + cmsFilterList: cmsFilterList + }; + + dispatch(updateMigrationData({ legacyCMSData: legacyCMSDataMapped })); + + //Update New Migration data; + + const selectedCmsData: ICMSType = validateArray(data.all_cms) + ? data.all_cms?.find((cms: ICMSType) => { + return cms?.cms_id === legacyCMSData?.cms}) + : DEFAULT_CMS_TYPE; - dispatch(updateMigrationData({ - ...newMigrationData, - legacy_cms: { - selectedCms: selectedCmsData, - selectedFileFormat: selectedFileFormatData || defaultCardType, - uploadedFile: newMigrationData?.legacy_cms?.uploadedFile, //need to add backend data once endpoint exposed. - affix: legacyCMSData?.affix || newMigrationData?.legacy_cms?.affix || '', - isFileFormatCheckboxChecked: - legacyCMSData?.affix_confirmation || - newMigrationData?.legacy_cms?.isFileFormatCheckboxChecked, //need to add backend data once endpoint exposed. - isRestictedKeywordCheckboxChecked: - legacyCMSData?.file_format_confirmation || - newMigrationData?.legacy_cms?.isRestictedKeywordCheckboxChecked //need to add backend data once endpoint exposed. + + const selectedFileFormatData: ICardType | undefined = validateArray( + selectedCmsData?.allowed_file_formats + ) + ? selectedCmsData.allowed_file_formats?.find( + (cms: ICardType) => cms?.fileformat_id === legacyCMSData?.file_format + ) + : defaultCardType; + + //Make Step 1 Complete + if (!isEmptyString(selectedCmsData?.cms_id)) { + setInternalActiveStepIndex(0); } - })) - - setIsLoading(false); - - //Check for migration Status and lock. - // Status where Migration is to be Locked: - setIsMigrationLocked(projectData?.status === 2 || projectData?.status === 5); - }; - useEffect(() => { + + //Make Step 2 complete + if (!isEmptyString(selectedCmsData?.cms_id) && !isEmptyString(legacyCMSData?.affix)) { + setInternalActiveStepIndex(1); + } + + //Make Step 3 complete + if ( + !isEmptyString(selectedCmsData?.cms_id) && + !isEmptyString(legacyCMSData?.affix) && + !isEmptyString(selectedFileFormatData?.fileformat_id) + ) { + setInternalActiveStepIndex(2); + } + + dispatch(updateNewMigrationData({ + ...newMigrationData, + legacy_cms: { + selectedCms: selectedCmsData, + selectedFileFormat: selectedFileFormatData || defaultCardType, + uploadedFile: newMigrationData?.legacy_cms?.uploadedFile, //need to add backend data once endpoint exposed. + affix: legacyCMSData?.affix || newMigrationData?.legacy_cms?.affix || '', + isFileFormatCheckboxChecked: true, //need to add backend data once endpoint exposed. + isRestictedKeywordCheckboxChecked: true //need to add backend data once endpoint exposed. + } + })) + + + setIsLoading(false); + + //Check for migration Status and lock. + // Status where Migration is to be Locked: + setIsMigrationLocked(projectData?.status === 2 || projectData?.status === 5); + }; fetchCMSData(); @@ -210,8 +208,7 @@ const LegacyCMSComponent = ({ legacyCMSData, projectData, handleStepChange }: Le autoVerticalStepper.current.handleDynamicStepChange(internalActiveStepIndex, true); } } - }, [internalActiveStepIndex]); - + }, [internalActiveStepIndex]); return ( <> {isLoading ? ( diff --git a/ui/src/components/LegacyCms/legacyCms.scss b/ui/src/components/LegacyCms/legacyCms.scss index c3918f41..7bc60e13 100644 --- a/ui/src/components/LegacyCms/legacyCms.scss +++ b/ui/src/components/LegacyCms/legacyCms.scss @@ -25,8 +25,11 @@ border-top: $px-5 solid $color-brand-primary-base !important; } .legacy-cms-container { - padding: $px-60 0 $px-60 10% !important; - width: $px-850 !important; + padding: $px-60 0 $px-10 5% !important; + //width: $px-850 !important; + overflow-y: auto; + overflow-x: hidden; + max-height: 70vh; } .service_list_search { @@ -63,14 +66,43 @@ .validation-container { display: flex; background-color: $color-base-white-5; - height: $px-108; - width: 100%; + height: 72px; + width: 592px; align-items: center; - padding: 0 !important; + margin-left: 20px !important; border: 1px solid $color-brand-secondary-lightest; border-radius: var(--TermCount, 5px); + +} +.error-container{ + display: flex; + background-color: $color-base-white-5; + height: 72px; + width: 592px; + align-items: center; + margin-left: 20px !important; + border: 1px solid $color-brand-fail-base; + border-radius: var(--TermCount, 5px); } .errorMessage { color: $color-brand-warning-medium; font-size: 12px; } +.validation-cta{ + margin: 20px 20px; +} +.success{ + color: $color-brand-success-base; +} +.error{ + color: $color-brand-fail-base; +} +.link-discription{ + font-family: $font-family-primary; + font-style: normal; + font-weight: $font-weight-regular; + font-size: $size-font-large; + line-height: 185%; + color: $color-base-gray-20; + margin-bottom: $space-10; +} \ No newline at end of file diff --git a/ui/src/components/LegacyCms/restrictedKeywords.json b/ui/src/components/LegacyCms/restrictedKeywords.json new file mode 100644 index 00000000..ea368cb4 --- /dev/null +++ b/ui/src/components/LegacyCms/restrictedKeywords.json @@ -0,0 +1,47 @@ +{ + "idArray": [ + "uid", + "api_key", + "created_at", + "deleted_at", + "updated_at", + "tags_array", + "klass_id", + "applikation_id", + "id", + "_id", + "ACL", + "SYS_ACL", + "DEFAULT_ACL", + "app_user_object_uid", + "built_io_upload", + "__loc", + "tags", + "_owner", + "_version", + "toJSON", + "save", + "update", + "domain", + "share_account", + "shard_app", + "shard_random", + "hook", + "__indexes", + "__meta", + "created_by", + "updated_by", + "inbuilt_class", + "tenant_id", + "isSystemUser", + "isApplicationUser", + "isNew", + "_shouldLean", + "_shouldFilter", + "options", + "_version", + "__v", + "locale", + "publish_details" + ] +} \ No newline at end of file diff --git a/ui/src/components/Migrations/NewMigration/NewMigrationWrapper.tsx b/ui/src/components/Migrations/NewMigration/NewMigrationWrapper.tsx index 3fe3c48b..771ae639 100644 --- a/ui/src/components/Migrations/NewMigration/NewMigrationWrapper.tsx +++ b/ui/src/components/Migrations/NewMigration/NewMigrationWrapper.tsx @@ -4,7 +4,7 @@ import { Outlet, Params, useNavigate, useParams } from 'react-router'; import { useSelector } from 'react-redux'; //venus components -import { Button, PageLayout, Stepper } from '@contentstack/venus-components'; +import { Button, CircularLoader, PageLayout, Stepper } from '@contentstack/venus-components'; // Services import { getMigrationData } from '../../../services/api/migration.service'; @@ -53,6 +53,7 @@ const MigrationExecutionComponentLazyLoaded = lazy( const createStepper = (projectData:any,handleStepChange: (currentStep: number) => void) => { + const steps = [ { data: { useEffect(() => { fetchData(); - }, [params?.stepId, params?.projectId, selectedOrganisation.value]); + }, [params?.stepId, params?.projectId, selectedOrganisation?.value]); const { settings, migration_steps_heading } = migrationData; @@ -234,7 +235,9 @@ const NewMigrationWrapper = () => {
+ {isLoading ? : + }
diff --git a/ui/src/components/Stepper/FlowStepper/FlowBlockItem.tsx b/ui/src/components/Stepper/FlowStepper/FlowBlockItem.tsx index f2e480ca..b7f330e7 100644 --- a/ui/src/components/Stepper/FlowStepper/FlowBlockItem.tsx +++ b/ui/src/components/Stepper/FlowStepper/FlowBlockItem.tsx @@ -20,7 +20,6 @@ interface FlowBlockItemProps { } const FlowBlockItem: FC = (props: FlowBlockItemProps) => { - //console.log("isComeplted : ", props?.isCompleted, props?.step); const [isHovered, setIsHovered] = useState(false); diff --git a/ui/src/components/Stepper/VerticalStepper/AutoVerticalStepper.scss b/ui/src/components/Stepper/VerticalStepper/AutoVerticalStepper.scss index 8b51c6f8..62fc2019 100644 --- a/ui/src/components/Stepper/VerticalStepper/AutoVerticalStepper.scss +++ b/ui/src/components/Stepper/VerticalStepper/AutoVerticalStepper.scss @@ -11,12 +11,12 @@ } .migration-vertical-stepper .stepper-title { - font-family: $font-family-primary; - font-style: normal; - font-weight: 700; - font-size: 1rem; - line-height: 135%; - color: $color-stepper-title; + //font-family: $font-family-primary; + //font-style: normal; + //font-weight: 600; + //font-size: 14px; + //line-height: 21px; + //color: $color-stepper-title; margin-bottom: $space-10; margin: 10px 20px; diff --git a/ui/src/components/Stepper/VerticalStepper/AutoVerticalStepper.tsx b/ui/src/components/Stepper/VerticalStepper/AutoVerticalStepper.tsx index d0f3c59c..3c84415d 100644 --- a/ui/src/components/Stepper/VerticalStepper/AutoVerticalStepper.tsx +++ b/ui/src/components/Stepper/VerticalStepper/AutoVerticalStepper.tsx @@ -48,6 +48,7 @@ const AutoVerticalStepper = React.forwardRef< }, [stepComponentProps?.step?.step_id, stepComponentProps?.connector?.group_name]); const handleStepChange = (stepIndex: number, closeStep = false) => { + if (closeStep) { const data = stepStatus.map((s: any, i: number) => { if (i === stepIndex) { @@ -56,6 +57,7 @@ const AutoVerticalStepper = React.forwardRef< return s; }); setStepStatus(data); + handleOnAllStepsComplete(true); } else { const data: string[] = stepStatus.map((s: any, i: number) => { @@ -160,7 +162,7 @@ const AutoVerticalStepper = React.forwardRef< id={step?.step_id} className="step_block" key={step?.step_id} - style={{ paddingBottom: '40px' }} + style={{ paddingBottom: '10px' }} >
{StepperStepTitleCreator(step)} diff --git a/ui/src/context/app/app.interface.ts b/ui/src/context/app/app.interface.ts index 8d4ca95d..743e885e 100644 --- a/ui/src/context/app/app.interface.ts +++ b/ui/src/context/app/app.interface.ts @@ -37,13 +37,13 @@ export interface User { organizations: Organization[]; } export interface FileDetails { - isLocalPath: boolean; - cmsType: string; - localPath: string; - awsData: { - awsRegion: string; - bucketName: string; - buketKey: string; + isLocalPath?: boolean; + cmsType?: string; + localPath?: string; + awsData?: { + awsRegion?: string; + bucketName?: string; + buketKey?: string; }; } export interface IFile { @@ -53,7 +53,7 @@ export interface IFile { type?: string; url?: string; validation?: string; - file_details: FileDetails; + file_details?: FileDetails; isValidated?: boolean; } From b4844ec065572393c6c5f3b64e1130bfbb7ffb79 Mon Sep 17 00:00:00 2001 From: AishDani Date: Mon, 10 Jun 2024 15:22:32 +0530 Subject: [PATCH 02/19] refactor:legacy cms step --- ui/src/components/Common/Card/card.tsx | 8 +-- ui/src/components/ContentMapper/index.tsx | 2 +- .../LegacyCms/Actions/LoadFileFormat.tsx | 43 +------------ .../LegacyCms/Actions/LoadPrefix.tsx | 18 +----- .../LegacyCms/Actions/LoadSelectCms.tsx | 60 ++++++------------- .../LegacyCms/Actions/LoadUploadFile.tsx | 42 ++++++++----- ui/src/components/LegacyCms/index.tsx | 56 +++++++---------- ui/src/components/LegacyCms/legacyCms.scss | 21 ++++++- .../components/MigrationFlowHeader/index.tsx | 8 ++- .../NewMigration/NewMigrationWrapper.tsx | 47 +-------------- ui/src/pages/Migration/index.tsx | 59 ++++++++++++++++-- uplaode-api/package-lock.json | 1 + uplaode-api/package.json | 3 +- 13 files changed, 155 insertions(+), 213 deletions(-) diff --git a/ui/src/components/Common/Card/card.tsx b/ui/src/components/Common/Card/card.tsx index cfcb986b..178e68d2 100644 --- a/ui/src/components/Common/Card/card.tsx +++ b/ui/src/components/Common/Card/card.tsx @@ -62,18 +62,14 @@ const Card = ({ data, selectedCard, onCardClick, cardType, idField = 'id' }: Car top: '-5px' }} > - {isHovered || selectedCard[idField] === data[idField] ? ( - + {isHovered || selectedCard[idField] === data?.[idField] ? ( + ) : ( <> )}
- {/* */}
diff --git a/ui/src/components/ContentMapper/index.tsx b/ui/src/components/ContentMapper/index.tsx index f0ca2070..0efe1492 100644 --- a/ui/src/components/ContentMapper/index.tsx +++ b/ui/src/components/ContentMapper/index.tsx @@ -129,7 +129,7 @@ const ContentMapper = () => { action_cta: actionCta, cta, search_placeholder: searchPlaceholder - } + }= {} } = migrationData; const parseDescription = HTMLReactParser(jsonToHtml(description ?? {})); diff --git a/ui/src/components/LegacyCms/Actions/LoadFileFormat.tsx b/ui/src/components/LegacyCms/Actions/LoadFileFormat.tsx index 186a335b..db7cd225 100644 --- a/ui/src/components/LegacyCms/Actions/LoadFileFormat.tsx +++ b/ui/src/components/LegacyCms/Actions/LoadFileFormat.tsx @@ -1,7 +1,7 @@ // Libraries -import { ChangeEvent, useContext, useEffect, useState } from 'react'; +import { ChangeEvent, useEffect, useState } from 'react'; import { useParams } from 'react-router'; -import { Button, Icon, TextInput } from '@contentstack/venus-components'; +import { Icon, TextInput } from '@contentstack/venus-components'; import { useDispatch, useSelector } from 'react-redux'; // Utilities @@ -15,14 +15,9 @@ import { // Interface import { ICardType, defaultCardType } from '../../../components/Common/Card/card.interface'; -import { INewMigration } from '../../../context/app/app.interface'; -// Context -import { AppContext } from '../../../context/app/app.context'; // Components -import Card from '../../../components/Common/Card/card'; -import DocLink from '../../../components/Common/DocLink/DocLink'; import { RootState } from '../../../store'; import { updateNewMigrationData } from '../../../store/slice/migrationDataSlice'; @@ -49,7 +44,6 @@ const LoadFileFormat = (props: LoadFileFormatProps) => { const { projectId = '' } = useParams(); const { allowed_file_formats = [], doc_url = { href: '', title: '' } } = newMigrationData?.legacy_cms?.selectedCms || {}; - /**** ALL METHODS HERE ****/ @@ -109,37 +103,11 @@ const LoadFileFormat = (props: LoadFileFormatProps) => { return (
- {/* */} -
- - Following is the file format in which data is exported from your current CMS - -
{validateArray(allowed_file_formats) ? ( allowed_file_formats?.map((data: ICardType, index: number) => ( - - - // { - // return; - // }} - // /> - - -
- +
{ )}
- {/*
- -
*/}
); }; diff --git a/ui/src/components/LegacyCms/Actions/LoadPrefix.tsx b/ui/src/components/LegacyCms/Actions/LoadPrefix.tsx index f602d702..608d9fd8 100644 --- a/ui/src/components/LegacyCms/Actions/LoadPrefix.tsx +++ b/ui/src/components/LegacyCms/Actions/LoadPrefix.tsx @@ -17,14 +17,11 @@ import { DEFAULT_URL_TYPE, INewMigration } from '../../../context/app/app.interf import '../legacyCms.scss'; import { Icon, TextInput } from '@contentstack/venus-components'; import { useDebouncer } from '../../../hooks'; -import DocLink from '../../../components/Common/DocLink/DocLink'; import { RootState } from '../../../store'; import { updateNewMigrationData } from '../../../store/slice/migrationDataSlice'; //import restricted keywords import restrictedKeywords from '../restrictedKeywords.json'; -import { set } from 'mongoose'; - interface LoadSelectCmsProps { stepComponentProps: any; @@ -156,15 +153,7 @@ const LoadPreFix = (props: LoadSelectCmsProps) => { return (
- {/* */} - -
+
{handleOnChange(e)}} value={prefix} @@ -185,11 +174,6 @@ const LoadPreFix = (props: LoadSelectCmsProps) => { {restricted_keyword_link?.title}
} - {/*
- -
*/}
); }; diff --git a/ui/src/components/LegacyCms/Actions/LoadSelectCms.tsx b/ui/src/components/LegacyCms/Actions/LoadSelectCms.tsx index 604308b8..14fd10a2 100644 --- a/ui/src/components/LegacyCms/Actions/LoadSelectCms.tsx +++ b/ui/src/components/LegacyCms/Actions/LoadSelectCms.tsx @@ -5,7 +5,7 @@ import { useDispatch, useSelector } from 'react-redux'; // Service import { updateLegacyCMSData } from '../../../services/api/migration.service'; -import { fileValidation, getConfig } from '../../../services/api/upload.service'; +import { getConfig } from '../../../services/api/upload.service'; // Utilities import { isEmptyString, validateArray } from '../../../utilities/functions'; @@ -17,7 +17,7 @@ import { DEFAULT_CMS_TYPE, ICMSType, INewMigration } from '../../../context/app/ // Components import Card from '../../../components/Common/Card/card'; -import { EmptyState, Line, Search } from '@contentstack/venus-components'; +import { EmptyState } from '@contentstack/venus-components'; // Style import '../legacyCms.scss'; @@ -46,16 +46,13 @@ const LoadSelectCms = (props: LoadSelectCmsProps) => { const [cmsFilterStatus, setCmsFilterStatus] = useState({}); const [cmsFilter, setCmsFilter] = useState([]); const [cmsType, setCmsType] = useState( - newMigrationData?.legacy_cms?.selectedCms + newMigrationData?.legacy_cms?.selectedCms || defaultCardType ); const [selectedCard, setSelectedCard] = useState( - newMigrationData?.legacy_cms?.selectedCms + newMigrationData?.legacy_cms?.selectedCms || defaultCardType ); const [errorMessage, setErrorMessage] = useState(''); - const [isError, setIsError] = useState(false); - - - + const [isError, setIsError] = useState(false); const { projectId = '' } = useParams(); @@ -64,9 +61,9 @@ const LoadSelectCms = (props: LoadSelectCmsProps) => { //Handle Legacy cms selection const handleCardClick = async(data: ICMSType) => { - const isSingleMatch = cmsData.length === 1; + const isSingleMatch = cmsData.length === 1; - if (isSingleMatch || selectedCard?.title !== data?.title) { + if (isSingleMatch || selectedCard?.cms_id !== data?.cms_id) { setSelectedCard({ ...data }); const newMigrationDataObj: INewMigration = { @@ -83,7 +80,7 @@ const LoadSelectCms = (props: LoadSelectCmsProps) => { const res = await updateLegacyCMSData(selectedOrganisation.value, projectId, { legacy_cms: data?.cms_id }); // Call for Step Change - props.handleStepChange(props.currentStep, true); + props?.handleStepChange(props?.currentStep, true); } }; @@ -97,7 +94,8 @@ const LoadSelectCms = (props: LoadSelectCmsProps) => { ...newMigrationData?.legacy_cms, selectedCms: cms } - })) + })); + const res = await updateLegacyCMSData(selectedOrganisation.value, projectId, { legacy_cms: cms}); if (!isEmptyString(cms?.title)) { @@ -135,14 +133,13 @@ const LoadSelectCms = (props: LoadSelectCmsProps) => { if(isEmptyString(cmsType?.cms_id)){ setCmsType(cms); } - + const cmstype = !isEmptyString(cmsType?.cms_id) ? cmsType?.parent : cms; // Fetch the specific CMS type let filteredCmsData = all_cms; if (cmstype) { filteredCmsData = all_cms.filter((cms: ICMSType) => cms?.parent?.toLowerCase() === cmstype?.toLowerCase()); } - setCmsData(filteredCmsData) @@ -157,18 +154,17 @@ const LoadSelectCms = (props: LoadSelectCmsProps) => { : []; setCmsData(_filterCmsData); - - let newSelectedCard: ICMSType | undefined; - - if (_filterCmsData.length === 1) { + + if (filteredCmsData?.length === 1) { newSelectedCard = filteredCmsData[0]; } else { - newSelectedCard = filteredCmsData.find((cms: ICMSType) => cms?.parent.toLowerCase() === cmstype.toLowerCase()); + newSelectedCard = DEFAULT_CMS_TYPE; } + - if (newSelectedCard) { + if (!isEmptyString(newSelectedCard?.title)) { setSelectedCard(newSelectedCard); setErrorMessage(''); setIsError(false); @@ -182,10 +178,6 @@ const LoadSelectCms = (props: LoadSelectCmsProps) => { }; dispatch(updateNewMigrationData(newMigrationDataObj)); - - }else{ - setIsError(true); - setErrorMessage('No matching CMS found. Please try a different search term.'); } }; @@ -198,28 +190,10 @@ const LoadSelectCms = (props: LoadSelectCmsProps) => { filterCMSData(searchText); }, [cmsFilter]); - // useEffect(() => { - // if (selectedCard?.title !== 'Drupal' && selectedCard?.title !== 'Sitecore') { - // handleDirectSelection(selectedCard); - // } - // }, [cmsType, selectedCard]); return (
- {/*
- setSearchText(text?.toLowerCase())} - /> -
- */}
{ isError ?
@@ -232,7 +206,7 @@ const LoadSelectCms = (props: LoadSelectCmsProps) => { ( cmsData && validateArray(cmsData) && (
- {cmsData.map((data: ICMSType) => ( + {cmsData?.map((data: ICMSType) => ( { return ( -
+
{fileDetails?.isLocalPath ? (
- +
) : (
-

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

-

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

-

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

+

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

+

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

+

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

)}
@@ -50,6 +50,7 @@ const LoadUploadFile = (props: LoadUploadFileProps) => { const [showMessage, setShowMessage] = useState(false); const [validationMessgae, setValidationMessage] = useState(''); const [isValidationAttempted, setIsValidationAttempted] = useState(false); + const [isDasabled, setIsDisabled] = useState(false); const { projectId = '' } = useParams(); @@ -65,7 +66,7 @@ const LoadUploadFile = (props: LoadUploadFileProps) => { const newMigrationDataObj: INewMigration = { ...newMigrationData, legacy_cms: { - ...newMigrationData.legacy_cms, + ...newMigrationData?.legacy_cms, uploadedFile: { name: res?.data?.localPath, url: res?.data?.localPath, @@ -107,18 +108,20 @@ const LoadUploadFile = (props: LoadUploadFileProps) => { //function to get config details const getConfigDetails = async () =>{ const res: any = await getConfig(); - if(newMigrationData?.legacy_cms?.selectedCms?.parent.toLowerCase() !== res?.data?.cmsType.toLowerCase()){ + + if(! isEmptyString(newMigrationData?.legacy_cms?.selectedCms?.parent) && newMigrationData?.legacy_cms?.selectedCms?.parent.toLowerCase() !== res?.data?.cmsType.toLowerCase()){ setIsValidated(false); setValidationMessage('Validation Falied'); setIsValidationAttempted(true); setShowMessage(true); setIsLoading(false); + setIsDisabled(true); } const newMigrationDataObj: INewMigration = { ...newMigrationData, legacy_cms: { - ...newMigrationData.legacy_cms, + ...newMigrationData?.legacy_cms, uploadedFile: { name: res?.data?.localPath, url: res?.data?.localPath, @@ -147,25 +150,34 @@ const LoadUploadFile = (props: LoadUploadFileProps) => { getConfigDetails(); }, []); + useEffect(()=>{ + if(newMigrationData?.legacy_cms?.uploadedFile?.isValidated){ + setIsValidated(true); + setValidationMessage('Validated'); + props.handleStepChange(props?.currentStep, true); + } + },[isValidated]) + const validationClassName = isValidated ? 'success' : 'error'; - const containerClassName = `validation-container ${isValidationAttempted && !isValidated ? 'error-container' : ''}`; - + const containerClassName = `validation-container ${isValidationAttempted && !isValidated ? 'error-container pb-2' : ''}`; + return (
-
+
{showMessage && - () + () }
+ version={"v2"} + disabled={isDasabled}>Validate
diff --git a/ui/src/components/LegacyCms/index.tsx b/ui/src/components/LegacyCms/index.tsx index f515b14b..bf08a288 100644 --- a/ui/src/components/LegacyCms/index.tsx +++ b/ui/src/components/LegacyCms/index.tsx @@ -1,12 +1,12 @@ -import { useContext, useEffect, useRef, useState } from 'react'; +import { forwardRef, useEffect, useRef, useState } from 'react'; import { useDispatch,useSelector } from 'react-redux'; import AutoVerticalStepper from '../Stepper/VerticalStepper/AutoVerticalStepper'; import { getLegacyCMSSteps } from './StepperSteps'; import { useNavigate, useParams } from 'react-router-dom'; -import { Button, CircularLoader } from '@contentstack/venus-components'; +import { CircularLoader } from '@contentstack/venus-components'; // import { getEntries } from '../../services/contentstackSDK'; import { CS_ENTRIES } from '../../utilities/constants'; -import { AppContext } from '../../context/app/app.context'; + import { DEFAULT_CMS_TYPE, DEFAULT_LEGACY_CMS_DATA, @@ -28,10 +28,12 @@ import { updateMigrationData, updateNewMigrationData } from '../../store/slice/ type LegacyCMSComponentProps = { legacyCMSData: any; projectData: MigrationResponse; + isCompleted: boolean handleStepChange: (currentStep: number) => void; + handleOnAllStepsComplete:(flag : boolean)=>void; }; -const LegacyCMSComponent = ({ legacyCMSData, projectData, handleStepChange }: LegacyCMSComponentProps) => { +const LegacyCMSComponent = forwardRef(({ legacyCMSData, projectData, isCompleted, handleStepChange, handleOnAllStepsComplete }: LegacyCMSComponentProps, ref) => { //react-redux apis const migrationData = useSelector((state:RootState)=>state?.migration?.migrationData); const newMigrationData = useSelector((state:RootState)=>state?.migration?.newMigrationData); @@ -40,7 +42,6 @@ const LegacyCMSComponent = ({ legacyCMSData, projectData, handleStepChange }: Le /** ALL HOOKS HERE */ - const [isCompleted, setIsCompleted] = useState(false); const [isMigrationLocked, setIsMigrationLocked] = useState(false); const [isLoading, setIsLoading] = useState(true); const [internalActiveStepIndex, setInternalActiveStepIndex] = useState(-1); @@ -53,10 +54,12 @@ const LegacyCMSComponent = ({ legacyCMSData, projectData, handleStepChange }: Le const navigate = useNavigate(); const autoVerticalStepper = useRef(null); + //Handle on all steps are completed - const handleOnAllStepsComplete = (flag = false) => { - setIsCompleted(flag); + const handleAllStepsComplete = (flag = false) => { + handleOnAllStepsComplete(flag); }; + // handle on proceed to destination stack const handleOnClick = async (event: MouseEvent,handleStepChange:any ) => { @@ -74,6 +77,7 @@ const LegacyCMSComponent = ({ legacyCMSData, projectData, handleStepChange }: Le } }; + //handle on delete click const handleOnClickDeleteUploadedFile = (e: MouseEvent) => { e.preventDefault(); @@ -108,15 +112,15 @@ const LegacyCMSComponent = ({ legacyCMSData, projectData, handleStepChange }: Le //Step 3: Update it in APP context for later use validateArray(data?.all_cms) && data?.all_cms?.forEach((cms: ICMSType) => { - if (!isEmptyString(cms.parent)) { + if (!isEmptyString(cms?.parent)) { const filterObject = cmsFilterList?.find( - (obj: IFilterType) => obj.value === cms.parent + (obj: IFilterType) => obj?.value === cms?.parent ); if (!filterObject) { - cmsFilterList.push({ - value: cms.parent, - label: cms.parent, + cmsFilterList?.push({ + value: cms?.parent, + label: cms?.parent, isChecked: false }); } @@ -132,13 +136,13 @@ const LegacyCMSComponent = ({ legacyCMSData, projectData, handleStepChange }: Le dispatch(updateMigrationData({ legacyCMSData: legacyCMSDataMapped })); //Update New Migration data; - + const selectedCmsData: ICMSType = validateArray(data.all_cms) - ? data.all_cms?.find((cms: ICMSType) => { + ? data.all_cms?.find((cms: ICMSType) => { return cms?.cms_id === legacyCMSData?.cms}) : DEFAULT_CMS_TYPE; - + const selectedFileFormatData: ICardType | undefined = validateArray( selectedCmsData?.allowed_file_formats ) @@ -209,6 +213,7 @@ const LegacyCMSComponent = ({ legacyCMSData, projectData, handleStepChange }: Le } } }, [internalActiveStepIndex]); + return ( <> {isLoading ? ( @@ -230,32 +235,17 @@ const LegacyCMSComponent = ({ legacyCMSData, projectData, handleStepChange }: Le migrationData?.legacyCMSData?.all_steps )} isEdit={!isMigrationLocked} - handleOnAllStepsComplete={handleOnAllStepsComplete} + handleOnAllStepsComplete={handleAllStepsComplete} stepComponentProps={{ handleDeleteFile: handleOnClickDeleteUploadedFile }} />
- {isCompleted && !isMigrationLocked ? ( -
-
- -
-
- ) : ( - <> - )}
)} ); -}; - +}); +LegacyCMSComponent.displayName = 'LegacyCMSComponent'; export default LegacyCMSComponent; diff --git a/ui/src/components/LegacyCms/legacyCms.scss b/ui/src/components/LegacyCms/legacyCms.scss index 7bc60e13..8ef07937 100644 --- a/ui/src/components/LegacyCms/legacyCms.scss +++ b/ui/src/components/LegacyCms/legacyCms.scss @@ -25,11 +25,16 @@ border-top: $px-5 solid $color-brand-primary-base !important; } .legacy-cms-container { - padding: $px-60 0 $px-10 5% !important; + //padding: $px-60 0 $px-10 5% !important; + padding-left: 25px !important; + padding-top: 26px; + padding-right: 30px; //width: $px-850 !important; overflow-y: auto; overflow-x: hidden; max-height: 70vh; + background-color: $color-base-white-10; + } .service_list_search { @@ -74,22 +79,32 @@ border-radius: var(--TermCount, 5px); } +.validation-container > * { + margin-right: 10px; + margin-left: 15px; +} .error-container{ display: flex; background-color: $color-base-white-5; height: 72px; + flex-direction: column; width: 592px; - align-items: center; + align-items: flex-start; margin-left: 20px !important; border: 1px solid $color-brand-fail-base; border-radius: var(--TermCount, 5px); } +.error-container > * { + margin-left: 10px; + margin-top: 5px; +} + .errorMessage { color: $color-brand-warning-medium; font-size: 12px; } .validation-cta{ - margin: 20px 20px; + margin: 10px 20px; } .success{ color: $color-brand-success-base; diff --git a/ui/src/components/MigrationFlowHeader/index.tsx b/ui/src/components/MigrationFlowHeader/index.tsx index 8ca00004..070407c6 100644 --- a/ui/src/components/MigrationFlowHeader/index.tsx +++ b/ui/src/components/MigrationFlowHeader/index.tsx @@ -16,7 +16,11 @@ import { DEFAULT_NEW_MIGRATION } from '../../context/app/app.interface'; // CSS import './index.scss'; -const MigrationFlowHeader = () => { +type MigrationFlowHeaderProps = { + handleOnClick: (event: MouseEvent, handleStepChange: (currentStep: number) => void) => void; +}; + +const MigrationFlowHeader = ({ handleOnClick }: MigrationFlowHeaderProps) => { const [projectName, setProjectName] = useState(''); const navigate = useNavigate(); @@ -67,7 +71,7 @@ const MigrationFlowHeader = () => {
- -
); diff --git a/ui/src/components/DestinationStack/DestinationStack.scss b/ui/src/components/DestinationStack/DestinationStack.scss index aac127a0..afb15c85 100644 --- a/ui/src/components/DestinationStack/DestinationStack.scss +++ b/ui/src/components/DestinationStack/DestinationStack.scss @@ -18,7 +18,12 @@ color: $color-font-black; margin-top: 3px; } - +.stackTitle { + color: $color-black-2121; + font-size: $size-font-large; + font-weight: $font-weight-semi-bold; + padding-bottom: 20px; +} .pl-40 { padding-left: $px-40; } @@ -28,9 +33,77 @@ max-width: $px-440 !important; } .destination-stack-container { - margin-top: $px-108 !important; - width: $px-850 !important; - margin-left: 10% !important; + padding: 20px; + .migration-vertical-stepper { + padding: 24px 30px; + border: 1px solid $color-brand-secondary-lightest; + border-radius: 4px; + background-color: $color-brand-white-base; + .step_block { + padding: 0 !important; + margin: 0; + background: none; + border: 0 none; + border-radius: 0; + } + .stepper-title { + margin: 20px 0 5px; + padding: 0 8px; + color: $color-black-2121; + font-size: $size-font-large; + font-weight: $font-weight-semi-bold; + line-height: 21px; + } + .action-content-wrapper { + box-shadow: none; + border: 0 none; + border-radius: 0; + padding:0 !important; + } + .migration-vertical-stepper-container { + border-bottom: 0 none; + } + .orgInput { + max-width: 600px; + width: 100%; + } + .Select__menu { + // max-width: 430px; + width: 100%; + margin: 0; + .Select__v2 .Select__menu .Select__menu-list .Select__option { + padding: 12px !important; + } + .Select .Select__control .Select__value-container input, .Select__single-value input[text]{ + font-size: 16px !important; + line-height: 24px !important; + color: $color-placeholder !important; + width: 100% !important; + } + .Select__option { + position: relative; + &:last-child { + border-top: 1px solid $color-brand-secondary-lightest; + position: absolute; + bottom: 0; + color: $color-brand-primary-base; + font-weight: $font-weight-semi-bold; + } + } + } + .TextInput--disabled .TextInput__v2 { + background-color: #F9F8FF !important; + } + #Step2 { + .action-summary-wrapper { + background-color: $color-brand-white-base; + margin-left: 2px; + padding: 0 !important; + } + } + + + } } .TextInput--disabled .TextInput__v2 { diff --git a/ui/src/components/DestinationStack/Summary/StacksSummary.tsx b/ui/src/components/DestinationStack/Summary/StacksSummary.tsx index 5523d196..e5082ad6 100644 --- a/ui/src/components/DestinationStack/Summary/StacksSummary.tsx +++ b/ui/src/components/DestinationStack/Summary/StacksSummary.tsx @@ -1,12 +1,9 @@ import { useState } from 'react'; -import { useDispatch,useSelector } from 'react-redux'; -import StepIcon from '../../../components/Stepper/FlowStepper/StepIcon'; -import { AppContext } from '../../../context/app/app.context'; +import { useSelector } from 'react-redux'; import { isEmptyString } from '../../../utilities/functions'; import { DEFAULT_DROPDOWN, IDropDown, - INewMigration, IStep } from '../../../context/app/app.interface'; diff --git a/ui/src/components/DestinationStack/index.tsx b/ui/src/components/DestinationStack/index.tsx index 52c3db98..887ee85a 100644 --- a/ui/src/components/DestinationStack/index.tsx +++ b/ui/src/components/DestinationStack/index.tsx @@ -3,9 +3,8 @@ import { useDispatch, useSelector } from 'react-redux'; import AutoVerticalStepper from '../Stepper/VerticalStepper/AutoVerticalStepper'; import { getDestinationStackSteps } from './StepperSteps'; import { useNavigate, useParams } from 'react-router-dom'; -import { Button, CircularLoader } from '@contentstack/venus-components'; +import { CircularLoader } from '@contentstack/venus-components'; import { CS_ENTRIES } from '../../utilities/constants'; -import { AppContext } from '../../context/app/app.context'; import { DEFAULT_DESTINATION_STACK_DATA, IDestinationStack, @@ -16,30 +15,34 @@ import './DestinationStack.scss'; import { isEmptyString, validateArray } from '../../utilities/functions'; import { getAllStacksInOrg } from '../../services/api/stacks.service'; import { MigrationResponse, StackResponse } from '../../services/api/service.interface'; -import { - updateCurrentStepData, - updateDestinationStack -} from '../../services/api/migration.service'; +// import { +// updateCurrentStepData, +// updateDestinationStack +// } from '../../services/api/migration.service'; import { getCMSDataFromFile } from '../../cmsData/cmsSelector'; import { RootState } from '../../store'; -import { setMigrationData, setNewMigrationData, updateMigrationData, updateNewMigrationData } from '../../store/slice/migrationDataSlice'; +import { updateMigrationData, updateNewMigrationData } from '../../store/slice/migrationDataSlice'; type DestinationStackComponentProps = { destination_stack: string; org_id: string; + isCompleted: boolean; projectData: MigrationResponse; handleStepChange: (currentStep: number) => void; + handleOnAllStepsComplete:(flag : boolean)=>void; }; const DestinationStackComponent = ({ destination_stack, org_id, projectData, - handleStepChange + isCompleted, + // handleStepChange, + handleOnAllStepsComplete, }: DestinationStackComponentProps) => { /** ALL HOOKS HERE */ const [isLoading, setIsLoading] = useState(true); - const [isCompleted, setIsCompleted] = useState(false); + // const [isCompleted, setIsCompleted] = useState(false); const [isMigrationLocked, setIsMigrationLocked] = useState(false); const [stepperKey, setStepperKey] = useState('v-mig-destination-step'); const [internalActiveStepIndex, setInternalActiveStepIndex] = useState(-1); @@ -53,27 +56,27 @@ const DestinationStackComponent = ({ const organisationsList = useSelector((state:RootState)=>state?.authentication?.organisationsList); const dispatch = useDispatch(); - const { projectId = '' } = useParams(); + // const { projectId = '' } = useParams(); - const navigate = useNavigate(); + // const navigate = useNavigate(); - const handleOnAllStepsComplete = (flag = false) => { - setIsCompleted(flag); + const handleAllStepsComplete = (flag = false) => { + handleOnAllStepsComplete(flag); }; - const handleOnClick = async (event: MouseEvent) => { - event?.preventDefault(); - //Update Data in backend - await updateDestinationStack(selectedOrganisation?.value, projectId, { - stack_api_key: newMigrationData?.destination_stack?.selectedStack?.value - }); - handleStepChange(2); - const res = await updateCurrentStepData(selectedOrganisation?.value, projectId); - if (res) { - const url = `/projects/${projectId}/migration/steps/3`; - navigate(url, { replace: true }); - } - }; + // const handleOnClick = async (event: MouseEvent) => { + // event?.preventDefault(); + // //Update Data in backend + // await updateDestinationStack(selectedOrganisation?.value, projectId, { + // stack_api_key: newMigrationData?.destination_stack?.selectedStack?.value + // }); + // handleStepChange(2); + // const res = await updateCurrentStepData(selectedOrganisation?.value, projectId); + // if (res) { + // const url = `/projects/${projectId}/migration/steps/3`; + // navigate(url, { replace: true }); + // } + // }; const updateDestinationStackData = async () => { //Update New Migration data @@ -124,7 +127,7 @@ const DestinationStackComponent = ({ !isEmptyString(selectedStackData?.value) ) { setInternalActiveStepIndex(1); - setIsCompleted(true); + // setIsCompleted(true); } //Update newMigration Data for destination stack @@ -196,7 +199,7 @@ const DestinationStackComponent = ({ } } }, [internalActiveStepIndex]); - + // console.log(".........DestinationStackComponent", migrationData?.destinationStackData, isMigrationLocked) return ( <> {isLoading ? ( @@ -207,32 +210,19 @@ const DestinationStackComponent = ({
) : (
-
-
- -
- {isCompleted && !isMigrationLocked ? ( -
-
- -
-
- ) : ( - <> +
{migrationData?.destinationStackData?.title}
+ + description={migrationData?.destinationStackData?.description} + ref={autoVerticalStepperComponent} + isEdit={!isMigrationLocked} + handleOnAllStepsComplete={handleAllStepsComplete} + />
)} diff --git a/ui/src/components/Stepper/HorizontalStepper/HorizontalStepper.scss b/ui/src/components/Stepper/HorizontalStepper/HorizontalStepper.scss index 935727a4..0b66abdf 100644 --- a/ui/src/components/Stepper/HorizontalStepper/HorizontalStepper.scss +++ b/ui/src/components/Stepper/HorizontalStepper/HorizontalStepper.scss @@ -120,4 +120,5 @@ } .stepContent { padding-top: 190px; + background: $color-base-white-10; } \ No newline at end of file diff --git a/ui/src/components/Stepper/VerticalStepper/AutoVerticalStepper.tsx b/ui/src/components/Stepper/VerticalStepper/AutoVerticalStepper.tsx index 3c84415d..791880e6 100644 --- a/ui/src/components/Stepper/VerticalStepper/AutoVerticalStepper.tsx +++ b/ui/src/components/Stepper/VerticalStepper/AutoVerticalStepper.tsx @@ -12,6 +12,7 @@ export enum StepStatus { type AutoVerticalStepperProps = { steps: any[]; className?: string; + description?: string; stepComponentProps?: any; isEdit: boolean; handleOnAllStepsComplete: (flag: boolean) => void; @@ -32,6 +33,7 @@ const AutoVerticalStepper = React.forwardRef< const { steps, className = '', + description='', stepComponentProps, isEdit = false, handleOnAllStepsComplete = () => { @@ -78,10 +80,10 @@ const AutoVerticalStepper = React.forwardRef< <>
- + {data.titleNote ? data.titleNote : ''}
- {data.lock ? ( + {data?.lock ? (
lock-icon @@ -89,7 +91,7 @@ const AutoVerticalStepper = React.forwardRef< ) : null}
-
{data.description}
+ {data.description &&
{data.description}
} ); }; @@ -149,6 +151,7 @@ const AutoVerticalStepper = React.forwardRef< return (
+ {props?.description &&
{props?.description}
}
    {steps?.map((step: any, index: number) => { diff --git a/ui/src/context/app/app.interface.ts b/ui/src/context/app/app.interface.ts index 743e885e..1b26fe15 100644 --- a/ui/src/context/app/app.interface.ts +++ b/ui/src/context/app/app.interface.ts @@ -96,6 +96,7 @@ export interface ILegacyCMSComponent { export interface IDestinationStackComponent { title: string; + description: string; cta: string; new_stack: { save_stack_cta: string; @@ -316,6 +317,7 @@ export const DEFAULT_LEGACY_CMS_DATA: ILegacyCMSComponent = { export const DEFAULT_DESTINATION_STACK_DATA: IDestinationStackComponent = { title: '', cta: '', + description: '', new_stack: { save_stack_cta: '', new_stack_input: '', diff --git a/ui/src/pages/Migration/index.tsx b/ui/src/pages/Migration/index.tsx index 7b7b2469..67fad7d0 100644 --- a/ui/src/pages/Migration/index.tsx +++ b/ui/src/pages/Migration/index.tsx @@ -8,7 +8,7 @@ import { RootState } from '../../store'; import { updateMigrationData } from '../../store/slice/migrationDataSlice'; // Services -import { getMigrationData, updateCurrentStepData, updateLegacyCMSData } from '../../services/api/migration.service'; +import { getMigrationData, updateCurrentStepData, updateDestinationStack, updateLegacyCMSData } from '../../services/api/migration.service'; import { getCMSDataFromFile } from '../../cmsData/cmsSelector'; // Utilities @@ -111,11 +111,12 @@ const Migration = () => { }, { data: , + destination_stack={projectData?.destination_stack_id} + org_id={projectData?.org_id} + projectData={projectData} + handleStepChange={handleStepChange} + isCompleted={isCompleted} + handleOnAllStepsComplete={handleOnAllStepsComplete} />, id:'2', title:'Destination Stack' }, @@ -179,9 +180,26 @@ const Migration = () => { } }; + // handle on proceed to content mapping + const handleOnClickDestinationStack = async (event: MouseEvent) => { + if(isCompleted){ + event?.preventDefault(); + //Update Data in backend + await updateDestinationStack(selectedOrganisation?.value, projectId, { + stack_api_key: newMigrationData?.destination_stack?.selectedStack?.value + }); + handleStepChange(2); + const res = await updateCurrentStepData(selectedOrganisation?.value, projectId); + if (res) { + const url = `/projects/${projectId}/migration/steps/3`; + navigate(url, { replace: true }); + } + } + }; const handleOnClickFunctions = [ - handleOnClickLegacyCms, + handleOnClickLegacyCms, + handleOnClickDestinationStack ]; return ( From 98283956c05c827952e9ce88140d9861c6eb0cb2 Mon Sep 17 00:00:00 2001 From: AishDani Date: Tue, 11 Jun 2024 15:34:37 +0530 Subject: [PATCH 07/19] refactor:added notification and error message for mismatch file format --- .../LegacyCms/Actions/LoadFileFormat.tsx | 6 +- .../LegacyCms/Actions/LoadPrefix.tsx | 8 +- .../LegacyCms/Actions/LoadSelectCms.tsx | 13 ++- .../LegacyCms/Actions/LoadUploadFile.tsx | 87 ++++++++++++------- ui/src/components/LegacyCms/index.tsx | 7 +- ui/src/components/LegacyCms/legacyCms.scss | 6 +- ui/src/pages/Migration/index.tsx | 10 ++- 7 files changed, 80 insertions(+), 57 deletions(-) diff --git a/ui/src/components/LegacyCms/Actions/LoadFileFormat.tsx b/ui/src/components/LegacyCms/Actions/LoadFileFormat.tsx index db7cd225..604d85ae 100644 --- a/ui/src/components/LegacyCms/Actions/LoadFileFormat.tsx +++ b/ui/src/components/LegacyCms/Actions/LoadFileFormat.tsx @@ -63,11 +63,11 @@ const LoadFileFormat = (props: LoadFileFormatProps) => { }); await fileformatConfirmation(selectedOrganisation?.value, projectId, { - fileformat_confirmation: isCheckedBoxChecked + fileformat_confirmation: true }); //call for Step Change - props.handleStepChange(props?.currentStep, true); + props.handleStepChange(props?.currentStep); } }; @@ -103,7 +103,6 @@ const LoadFileFormat = (props: LoadFileFormatProps) => { return (
    -
    {validateArray(allowed_file_formats) ? ( allowed_file_formats?.map((data: ICardType, index: number) => ( @@ -125,7 +124,6 @@ const LoadFileFormat = (props: LoadFileFormatProps) => { <>No File formats available )}
    -
    ); }; diff --git a/ui/src/components/LegacyCms/Actions/LoadPrefix.tsx b/ui/src/components/LegacyCms/Actions/LoadPrefix.tsx index 608d9fd8..737cbc18 100644 --- a/ui/src/components/LegacyCms/Actions/LoadPrefix.tsx +++ b/ui/src/components/LegacyCms/Actions/LoadPrefix.tsx @@ -77,7 +77,7 @@ const LoadPreFix = (props: LoadSelectCmsProps) => { }); //call for Step Change - props.handleStepChange(props.currentStep); + props.handleStepChange(props?.currentStep); return; } @@ -111,11 +111,11 @@ const LoadPreFix = (props: LoadSelectCmsProps) => { //API call for saving Affix await updateAffixData(selectedOrganisation?.value, projectId, { affix: value }); await affixConfirmation(selectedOrganisation?.value, projectId, { - affix_confirmation: isCheckedBoxChecked + affix_confirmation: true }); //call for Step Change - props.handleStepChange(props.currentStep, true); + props.handleStepChange(props?.currentStep); return; } @@ -152,7 +152,7 @@ const LoadPreFix = (props: LoadSelectCmsProps) => { migrationData.legacyCMSData; return ( -
    +
    {handleOnChange(e)}} diff --git a/ui/src/components/LegacyCms/Actions/LoadSelectCms.tsx b/ui/src/components/LegacyCms/Actions/LoadSelectCms.tsx index 14fd10a2..e35afc5f 100644 --- a/ui/src/components/LegacyCms/Actions/LoadSelectCms.tsx +++ b/ui/src/components/LegacyCms/Actions/LoadSelectCms.tsx @@ -49,7 +49,7 @@ const LoadSelectCms = (props: LoadSelectCmsProps) => { newMigrationData?.legacy_cms?.selectedCms || defaultCardType ); const [selectedCard, setSelectedCard] = useState( - newMigrationData?.legacy_cms?.selectedCms || defaultCardType + newMigrationData?.legacy_cms?.selectedCms ); const [errorMessage, setErrorMessage] = useState(''); const [isError, setIsError] = useState(false); @@ -77,7 +77,7 @@ const LoadSelectCms = (props: LoadSelectCmsProps) => { dispatch(updateNewMigrationData(newMigrationDataObj)); //API call for saving selected CMS - const res = await updateLegacyCMSData(selectedOrganisation.value, projectId, { legacy_cms: data?.cms_id }); + await updateLegacyCMSData(selectedOrganisation.value, projectId, { legacy_cms: data?.cms_id }); // Call for Step Change props?.handleStepChange(props?.currentStep, true); @@ -99,7 +99,7 @@ const LoadSelectCms = (props: LoadSelectCmsProps) => { const res = await updateLegacyCMSData(selectedOrganisation.value, projectId, { legacy_cms: cms}); if (!isEmptyString(cms?.title)) { - props?.handleStepChange(props?.currentStep); + props?.handleStepChange(props?.currentStep, true); } }; @@ -176,8 +176,9 @@ const LoadSelectCms = (props: LoadSelectCmsProps) => { selectedCms: newSelectedCard } }; - + await updateLegacyCMSData(selectedOrganisation.value, projectId, { legacy_cms: newSelectedCard?.cms_id }); dispatch(updateNewMigrationData(newMigrationDataObj)); + props?.handleStepChange(props?.currentStep); } }; @@ -190,11 +191,9 @@ const LoadSelectCms = (props: LoadSelectCmsProps) => { filterCMSData(searchText); }, [cmsFilter]); - return (
    -
    { isError ?
    { ) ) } - -
    ); diff --git a/ui/src/components/LegacyCms/Actions/LoadUploadFile.tsx b/ui/src/components/LegacyCms/Actions/LoadUploadFile.tsx index 75859a20..032ccdde 100644 --- a/ui/src/components/LegacyCms/Actions/LoadUploadFile.tsx +++ b/ui/src/components/LegacyCms/Actions/LoadUploadFile.tsx @@ -22,7 +22,7 @@ const FileComponent = ({fileDetails}:Props ) => { return (
    - {fileDetails?.isLocalPath ? ( + {fileDetails?.isLocalPath && (!isEmptyString(fileDetails?.localPath) || !isEmptyString(fileDetails?.awsData?.awsRegion)) ? (
    @@ -51,8 +51,11 @@ const LoadUploadFile = (props: LoadUploadFileProps) => { const [validationMessgae, setValidationMessage] = useState(''); const [isValidationAttempted, setIsValidationAttempted] = useState(false); const [isDasabled, setIsDisabled] = useState(false); - - const { projectId = '' } = useParams(); + const [isConfigLoading, setIsConfigLoading] = useState(true); + const [cmsType, setCmsType]= useState(''); + const [fileDetails, setFileDetails] = useState(); + const [fileExtension, setFileExtension] = useState(''); + //Handle further action on file is uploaded to server const handleOnFileUploadCompletion = async () => { @@ -105,11 +108,52 @@ const LoadUploadFile = (props: LoadUploadFileProps) => { }; + const getFileExtension = (filePath: string): string => { + const ext = filePath.split('.').pop(); + return ext ? `${ext}` : ''; + }; + //function to get config details const getConfigDetails = async () =>{ + setIsConfigLoading(true); const res: any = await getConfig(); - - if(! isEmptyString(newMigrationData?.legacy_cms?.selectedCms?.parent?.toLowerCase()) && newMigrationData?.legacy_cms?.selectedCms?.parent.toLowerCase() !== res?.data?.cmsType.toLowerCase()){ + + + if(res?.status === 200){ + const extension = getFileExtension(res?.data?.localPath); + setCmsType(res?.data?.cmsType); + setFileDetails(res?.data); + setFileExtension(extension); + + const newMigrationDataObj: INewMigration = { + ...newMigrationData, + legacy_cms: { + ...newMigrationData?.legacy_cms, + uploadedFile: { + name: res?.data?.localPath, + url: res?.data?.localPath, + file_details: { + isLocalPath: res?.data?.isLocalPath, + cmsType: res?.data?.cmsType, + localPath: res?.data?.localPath, + awsData: { + awsRegion: res?.data?.awsData?.awsRegion, + bucketName: res?.data?.awsData?.bucketName, + buketKey: res?.data?.awsData?.buketKey + } + } + } + } + }; + + dispatch(updateNewMigrationData(newMigrationDataObj)); + + } + else if(! isEmptyString(newMigrationData?.legacy_cms?.selectedCms?.parent?.toLowerCase()) && + newMigrationData?.legacy_cms?.selectedCms?.parent.toLowerCase() !== res?.data?.cmsType.toLowerCase() + || fileExtension !== newMigrationData?.legacy_cms?.selectedFileFormat?.fileformat_id + ) + { setIsValidated(false); setValidationMessage('Validation Falied'); setIsValidationAttempted(true); @@ -117,28 +161,8 @@ const LoadUploadFile = (props: LoadUploadFileProps) => { setIsLoading(false); setIsDisabled(true); } - - const newMigrationDataObj: INewMigration = { - ...newMigrationData, - legacy_cms: { - ...newMigrationData?.legacy_cms, - uploadedFile: { - name: res?.data?.localPath, - url: res?.data?.localPath, - file_details: { - isLocalPath: res?.data?.isLocalPath, - cmsType: res?.data?.cmsType, - localPath: res?.data?.localPath, - awsData: { - awsRegion: res?.data?.awsData?.awsRegion, - bucketName: res?.data?.awsData?.bucketName, - buketKey: res?.data?.awsData?.buketKey - } - } - } - } - }; - dispatch(updateNewMigrationData(newMigrationDataObj)); + setIsConfigLoading(false); + } @@ -156,7 +180,8 @@ const LoadUploadFile = (props: LoadUploadFileProps) => { setValidationMessage('Validated'); props.handleStepChange(props?.currentStep, true); } - },[isValidated]) + + },[isValidated,newMigrationData]) const validationClassName = isValidated ? 'success' : 'error'; @@ -167,10 +192,10 @@ const LoadUploadFile = (props: LoadUploadFileProps) => {
    - {! isDasabled ? ( - + {!isConfigLoading && !isEmptyString(cmsType) ? ( + ) : - } + } {showMessage && () } diff --git a/ui/src/components/LegacyCms/index.tsx b/ui/src/components/LegacyCms/index.tsx index bf08a288..230fec41 100644 --- a/ui/src/components/LegacyCms/index.tsx +++ b/ui/src/components/LegacyCms/index.tsx @@ -135,14 +135,12 @@ const LegacyCMSComponent = forwardRef(({ legacyCMSData, projectData, isCompleted dispatch(updateMigrationData({ legacyCMSData: legacyCMSDataMapped })); - //Update New Migration data; - + //Update New Migration data; const selectedCmsData: ICMSType = validateArray(data.all_cms) - ? data.all_cms?.find((cms: ICMSType) => { + ? data.all_cms?.find((cms: ICMSType) => { return cms?.cms_id === legacyCMSData?.cms}) : DEFAULT_CMS_TYPE; - const selectedFileFormatData: ICardType | undefined = validateArray( selectedCmsData?.allowed_file_formats ) @@ -213,7 +211,6 @@ const LegacyCMSComponent = forwardRef(({ legacyCMSData, projectData, isCompleted } } }, [internalActiveStepIndex]); - return ( <> {isLoading ? ( diff --git a/ui/src/components/LegacyCms/legacyCms.scss b/ui/src/components/LegacyCms/legacyCms.scss index 8ef07937..b6bfcb8b 100644 --- a/ui/src/components/LegacyCms/legacyCms.scss +++ b/ui/src/components/LegacyCms/legacyCms.scss @@ -4,7 +4,7 @@ display: flex; flex-wrap: wrap; gap: 12px; - margin: $space-15; + margin: 20px 20px !important; } .pl-40 { @@ -25,11 +25,11 @@ border-top: $px-5 solid $color-brand-primary-base !important; } .legacy-cms-container { - //padding: $px-60 0 $px-10 5% !important; + padding-left: 25px !important; padding-top: 26px; padding-right: 30px; - //width: $px-850 !important; + overflow-y: auto; overflow-x: hidden; max-height: 70vh; diff --git a/ui/src/pages/Migration/index.tsx b/ui/src/pages/Migration/index.tsx index 7b7b2469..f8a6f8af 100644 --- a/ui/src/pages/Migration/index.tsx +++ b/ui/src/pages/Migration/index.tsx @@ -18,7 +18,6 @@ import { isEmptyString, validateArray } from '../../utilities/functions'; // Interface import { MigrationResponse, - defaultMigrationResponse } from '../../services/api/service.interface'; import { DEFAULT_IFLOWSTEP, @@ -33,9 +32,10 @@ import DestinationStackComponent from '../../components/DestinationStack'; import ContentMapper from '../../components/ContentMapper'; import TestMigration from '../../components/TestMigration'; import MigrationExecution from '../../components/MigrationExecution'; +import { Notification } from '@contentstack/venus-components'; const Migration = () => { - const [projectData, setProjectData] = useState(defaultMigrationResponse); + const [projectData, setProjectData] = useState(); const [isLoading, setIsLoading] = useState(false); const [curreentStepIndex, setCurrentStepIndex] = useState(0); const [isCompleted, setIsCompleted] = useState(false); @@ -177,6 +177,12 @@ const Migration = () => { } } + else{ + Notification({ + notificationContent: { text: 'Please complete all steps' }, + type: 'warning' + }); + } }; From f96e34dd481f943a7a32244f5f67d070f7f05f76 Mon Sep 17 00:00:00 2001 From: Sayali Joshi Date: Tue, 11 Jun 2024 17:24:41 +0530 Subject: [PATCH 08/19] Content mapper new UI --- ui/package.json | 4 +- ui/src/cmsData/content_mapping.json | 2 +- ui/src/components/ContentMapper/index.scss | 54 +++++--- ui/src/components/ContentMapper/index.tsx | 136 +++++++++------------ ui/src/scss/App.scss | 8 +- ui/tsconfig.json | 3 +- 6 files changed, 104 insertions(+), 103 deletions(-) diff --git a/ui/package.json b/ui/package.json index ca22c2f2..e578593c 100644 --- a/ui/package.json +++ b/ui/package.json @@ -4,7 +4,7 @@ "private": true, "dependencies": { "@contentstack/json-rte-serializer": "^2.0.5", - "@contentstack/venus-components": "1.5.1", + "@contentstack/venus-components": "^2.2.4", "@reduxjs/toolkit": "^2.2.5", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", @@ -65,4 +65,4 @@ "last 1 safari version" ] } -} \ No newline at end of file +} diff --git a/ui/src/cmsData/content_mapping.json b/ui/src/cmsData/content_mapping.json index a0eba06e..43a812fa 100644 --- a/ui/src/cmsData/content_mapping.json +++ b/ui/src/cmsData/content_mapping.json @@ -142,7 +142,7 @@ ], "_version": 3 }, - "search_placeholder": "Search", + "search_placeholder": "Search for content types...", "tags": [], "title": "Content Mapping", "updated_at": "2024-01-25T12:13:32.967Z", diff --git a/ui/src/components/ContentMapper/index.scss b/ui/src/components/ContentMapper/index.scss index 33ca9ad5..037652b7 100644 --- a/ui/src/components/ContentMapper/index.scss +++ b/ui/src/components/ContentMapper/index.scss @@ -5,13 +5,19 @@ display: flex; flex-direction: column; max-height: calc(100vh - 173px); - max-width: 27%; + max-width: 25%; overflow: hidden; width: 100%; } .content-types-list-header { + background-color: $color-base-white-10; border-bottom: 1px solid $color-brand-secondary-lightest; - padding: 18px $space-12; + padding: $px-20 $space-12; + h2 { + color: $color-font-base; + font-size: $size-font-20; + font-weight: $font-weight-semi-bold; + } .Search { margin: $space-20 0 $space-12; width: 100%; @@ -20,21 +26,36 @@ } } } -.ct-list { - list-style-type: none; - padding: 15px 0; +.ct-search-wrapper { + border-bottom: 1px solid $color-brand-secondary-lightest; + padding: $px-8 $px-12; + .Search__v2 { + height: 2.5rem; + width: 100%!important; + .Search-input-show { + width: 100%!important; + } + } +} +.ct-list-wrapper { overflow-y: auto; overflow-x: hidden; +} +.ct-list { + border-right: 1px solid $color-brand-secondary-lightest; + list-style-type: none; + margin: 0 0 0 $px-12; + padding: 15px 12px 15px 0; li { align-items: center; border: 1px solid transparent; cursor: pointer; display: flex; - font-size: $size-font-large; + font-size: $size-font-xl; justify-content: space-between; line-height: normal; min-height: 42px; - padding: $space-10 35px; + padding: $px-8 $px-12; &.active-ct { background-color: $color-brand-white-base; border: 1px solid $color-brand-primary-base; @@ -46,10 +67,10 @@ padding-left: 12px; } .content-types-fields-wrapper { - border-left: 1px solid $color-brand-secondary-lightest; + // border-left: 1px solid $color-brand-secondary-lightest; display: flex; flex-direction: column; - max-width: 73%; + max-width: 75%; width: 100%; padding: 0px; } @@ -72,9 +93,10 @@ padding: 0 1.25rem; } .cms-field { - font-weight: $font-weight-semi-bold; + text-transform: capitalize; } .InstructionText { + font-size: $size-font-small; margin: 0; } } @@ -96,7 +118,6 @@ flex-direction: column; margin-top: 0; margin-left: 0px; - // margin-bottom: 20px; width: 100%; } .saveButton { @@ -105,10 +126,13 @@ .btnWrapper { margin-left: 20px; } -div .select .Select { - width: $px-50; - max-width: $px-50 !important; -} +div .select { + width: calc(100% - 30px); + .Select { + width: 100%; + max-width: 100% !important; + } +} div .table-row { display: flex; justify-content: space-between; diff --git a/ui/src/components/ContentMapper/index.tsx b/ui/src/components/ContentMapper/index.tsx index f0ca2070..90d426bc 100644 --- a/ui/src/components/ContentMapper/index.tsx +++ b/ui/src/components/ContentMapper/index.tsx @@ -3,7 +3,6 @@ import { useEffect, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useNavigate, useParams } from 'react-router-dom'; import { - Heading, InfiniteScrollTable, Select, ButtonGroup, @@ -34,13 +33,14 @@ import { } from '../../services/api/migration.service'; import { getStackStatus } from '../../services/api/stacks.service'; +// Redux +import { RootState } from '../../store'; +import { updateMigrationData, updateNewMigrationData } from '../../store/slice/migrationDataSlice'; + // Utilities import { CS_ENTRIES } from '../../utilities/constants'; import { validateArray } from '../../utilities/functions'; -// Context -import { AppContext } from '../../context/app/app.context'; - // Interface import { DEFAULT_CONTENT_MAPPING_DATA, INewMigration } from '../../context/app/app.interface'; import { @@ -66,9 +66,6 @@ import AdvanceSettings from '../AdvancePropertise'; // Styles import './index.scss'; -import { RootState } from '../../store'; -import { setNewMigrationData, updateMigrationData, updateNewMigrationData } from '../../store/slice/migrationDataSlice'; -import { setMigrationData } from '../../store/slice/migrationDataSlice'; const Fields: Mapping = { 'Single Line Textbox': [ @@ -107,7 +104,6 @@ const Fields: Mapping = { CheckBox: 'Select', global_field: 'Global' }; - interface ModalProps { e: React.MouseEvent; newIndex: number; @@ -126,14 +122,12 @@ const ContentMapper = () => { contentMappingData: { content_types_heading: contentTypesHeading, description, - action_cta: actionCta, - cta, + // action_cta: actionCta, + // cta, search_placeholder: searchPlaceholder } } = migrationData; - const parseDescription = HTMLReactParser(jsonToHtml(description ?? {})); - const [tableData, setTableData] = useState([]); const [loading, setLoading] = useState(false); const [itemStatusMap, updateItemStatusMap] = useState({}); @@ -250,7 +244,7 @@ const ContentMapper = () => { // Method to fetch content types const fetchContentTypes = async (searchText: string) => { - const { data } = await getContentTypes(projectId || '', 0, 10, searchContentType || ''); //org id will always present + const { data } = await getContentTypes(projectId || '', 0, 5000, searchContentType || ''); //org id will always present setContentTypes(data?.contentTypes); setSelectedContentType(data?.contentTypes?.[0]); @@ -279,7 +273,7 @@ const ContentMapper = () => { const handleSearch = async (searchCT: string) => { setSearchContentType(searchCT); - const { data } = await getContentTypes(projectId, 0, 5, searchCT || ''); //org id will always present + const { data } = await getContentTypes(projectId, 0, 1000, searchCT || ''); //org id will always present setContentTypes(data?.contentTypes); setSelectedContentType(data?.contentTypes?.[0]); @@ -369,40 +363,7 @@ const ContentMapper = () => { setSelectedContentType(contentTypes?.[i]); }; - //function to handle previous content type navigation - const handlePrevClick = (e: React.MouseEvent) => { - const newIndex = currentIndex > 0 ? currentIndex - 1 : 0; - if (isDropDownChanged) { - handleSaveContentTypeModal(e, newIndex); - } else { - setCurrentIndex(newIndex); - openContentType(e, newIndex); - document.querySelectorAll('.ct-list li').forEach((ctLi, ind) => { - if (newIndex === ind) { - ctLi?.classList?.add('active-ct'); - } - }); - } - }; - - // function to handle next content type navigation - const handleNextClick = (e: React.MouseEvent) => { - if (currentIndex < contentTypes?.length - 1) { - const newIndex = currentIndex + 1; - - if (isDropDownChanged) { - handleSaveContentTypeModal(e, newIndex); - } else { - setCurrentIndex(newIndex); - openContentType(e, newIndex); - document.querySelectorAll('.ct-list li').forEach((ctLi, ind) => { - if (newIndex === ind) { - ctLi?.classList?.add('active-ct'); - } - }); - } - } - }; + // Function to Save the Content Type const SaveContentType = (props: ModalProps) => { return ( <> @@ -484,9 +445,6 @@ const ContentMapper = () => { { - // return; - // }} {...props} /> ), @@ -531,7 +489,6 @@ const ContentMapper = () => { setRowIds(selectedObj); setSelectedEntries(selectedData); - }; // Function to find unchecked field @@ -605,8 +562,6 @@ const ContentMapper = () => { const SelectAccessor = (data: FieldMapType) => { const OptionsForRow = Fields[data?.backupFieldType as keyof Mapping]; - - const option = Array.isArray(OptionsForRow) ? OptionsForRow.map((option) => ({ label: option, value: option })) : [{ label: OptionsForRow, value: OptionsForRow }]; @@ -708,6 +663,7 @@ const ContentMapper = () => { 'multiline': 'multiline', 'HTML Rich text Editor': 'allow_rich_text', 'JSON Rich Text Editor': 'json', + group: 'Group', URL: 'url', file: 'file', number: 'number', @@ -728,11 +684,14 @@ const ContentMapper = () => { ); setContentTypeSchema(ContentType?.schema) } - + console.log('contentTypeSchema', contentTypeSchema); + if (contentTypeSchema && validateArray(contentTypeSchema)) { const fieldTypeToMatch = fieldsOfContentstack[data?.otherCmsType as keyof Mapping]; contentTypeSchema.forEach((value) => { + console.log("value", value); + switch (fieldTypeToMatch) { case 'text': if ( @@ -785,11 +744,9 @@ const ContentMapper = () => { OptionsForRow.push({ label: value?.display_name, value: value, isDisabled: false }); } break; - // case 'Group': - // if (value?.data_type === 'group') { - // OptionsForRow.push({ label: value?.display_name, value: value, isDisabled: false }); - // } - // break; + case 'Group': + OptionsForRow.push({ label: value?.display_name, value: value, isDisabled: false }); + break; default: OptionsForRow.push({ label: 'No matches found', @@ -1019,15 +976,28 @@ const ContentMapper = () => { isDisabled: contentTypeMapped && Object.values(contentTypeMapped).includes(option?.label) })); + const calcHeight = () => { + // Get the viewport height in pixels + const viewportHeight = window.innerHeight; + + // Subtract 246 pixels from the viewport height + const result = viewportHeight - 226; + + return result; + } + + const tableHeight = calcHeight(); + return (
    {/* Content Types List */}
    - -

    {parseDescription}

    + {contentTypesHeading &&

    {contentTypesHeading}

    } +
    +
    {
    {contentTypes && validateArray(contentTypes) && ( +
      {contentTypes?.map((content: ContentType, index: number) => (
    • {
    • ))}
    +
    )}
    {/* Content Type Fields */}
    - {!IsEmptyStack && ( -
    - +
    + )}
    ), showExportCta: true @@ -1129,7 +1103,7 @@ const ContentMapper = () => { />
    - {actionCta && validateArray(actionCta) && ( + {/* {actionCta && validateArray(actionCta) && (
    {
    - )} + )} */}
    - {cta?.title && ( + {/* {cta?.title && (
    - )} + )} */}
    ); }; diff --git a/ui/src/scss/App.scss b/ui/src/scss/App.scss index ddc48962..b76ecbd7 100644 --- a/ui/src/scss/App.scss +++ b/ui/src/scss/App.scss @@ -284,7 +284,9 @@ html, body { color: $color-font-base; font-family: $font-family-primary; + height: 100%; line-height: 1.3rem; + overflow-x: hidden; span, p { line-height: $line-height-default !important; @@ -386,11 +388,11 @@ h2 { } } ::-webkit-input-placeholder { - color: $color-black-2121 !important; + color: $color-stepper-title !important; } ::-ms-input-placeholder { - color: $color-black-2121 !important; + color: $color-stepper-title !important; } ::placeholder { - color: $color-black-2121 !important; + color: $color-stepper-title !important; } diff --git a/ui/tsconfig.json b/ui/tsconfig.json index 17773cb6..bc3afcbe 100644 --- a/ui/tsconfig.json +++ b/ui/tsconfig.json @@ -17,7 +17,8 @@ "jsx": "react-jsx", "baseUrl": "./", "paths": { - "*": ["src/types/*"] + "*": ["src/types/*"], + "react": [ "./node_modules/@types/react" ] }, "typeRoots": ["./node_modules/@types", "./src/types"] }, From 096b3961508b94b0fdd70fbbbe993de126c4f6f8 Mon Sep 17 00:00:00 2001 From: Shristi Sinha Date: Tue, 11 Jun 2024 17:30:39 +0530 Subject: [PATCH 09/19] add file path, is_fileValid and aws details in file-format api --- api/src/models/project-lowdb.ts | 7 +++++++ api/src/services/projects.service.ts | 19 ++++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/api/src/models/project-lowdb.ts b/api/src/models/project-lowdb.ts index c7fb3c39..683c60c5 100644 --- a/api/src/models/project-lowdb.ts +++ b/api/src/models/project-lowdb.ts @@ -14,6 +14,13 @@ interface LegacyCMS { type: string; path: string; }; + awsDetails: { + awsRegion: string; + bucketName: string; + buketKey: string; +} + file_path: string; + is_fileValid: boolean; } interface ExecutionLog { diff --git a/api/src/services/projects.service.ts b/api/src/services/projects.service.ts index 83d2121b..337f05fa 100644 --- a/api/src/services/projects.service.ts +++ b/api/src/services/projects.service.ts @@ -83,7 +83,13 @@ const createProject = async (req: Request) => { destination_stack_id: "", test_stacks: [], current_test_stack_id: "", - legacy_cms: {}, + legacy_cms: { + "is_fileValid":false, + awsDetails: { + awsRegion: "", + bucketName: "", + buketKey: "" + } }, content_mapper: [], execution_log: [], created_by: user_id, @@ -346,10 +352,8 @@ const affixConfirmation = async (req: Request) => { const updateFileFormat = async (req: Request) => { const { orgId, projectId } = req.params; - const { token_payload, file_format } = req.body; + const { token_payload, file_format,file_path,is_fileValid,awsDetails } = req.body; const srcFunc = "updateFileFormat"; - - await ProjectModelLowdb.read(); const projectIndex = (await getProjectUtil( projectId, { @@ -390,11 +394,16 @@ const updateFileFormat = async (req: Request) => { } try { - ProjectModelLowdb.update((data: any) => { + ProjectModelLowdb.update((data: any) => { data.projects[projectIndex].legacy_cms.file_format = file_format; + data.projects[projectIndex].legacy_cms.file_path = file_path; + data.projects[projectIndex].legacy_cms.is_fileValid = is_fileValid; data.projects[projectIndex].current_step = STEPPER_STEPS.LEGACY_CMS; data.projects[projectIndex].status = NEW_PROJECT_STATUS[0]; data.projects[projectIndex].updated_at = new Date().toISOString(); + data.projects[projectIndex].legacy_cms.awsDetails.awsRegion = awsDetails.awsRegion; + data.projects[projectIndex].legacy_cms.awsDetails.bucketName = awsDetails.bucketName; + data.projects[projectIndex].legacy_cms.awsDetails.buketKey = awsDetails.buketKey; }); logger.info( From 196209e95805e0152abcd13c1554ca409a566264 Mon Sep 17 00:00:00 2001 From: Sayali Joshi Date: Fri, 14 Jun 2024 16:34:14 +0530 Subject: [PATCH 10/19] Content mapper UI design changes --- ui/src/cmsData/content_mapping.json | 1 + ui/src/components/ContentMapper/index.scss | 11 ++- ui/src/components/ContentMapper/index.tsx | 83 +++++++++++++------ ui/src/components/ProjectsHeader/index.tsx | 15 ---- .../HorizontalStepper/HorizontalStepper.scss | 2 + ui/src/context/app/app.interface.ts | 6 +- ui/src/pages/Migration/index.tsx | 55 ++++++++++-- 7 files changed, 120 insertions(+), 53 deletions(-) diff --git a/ui/src/cmsData/content_mapping.json b/ui/src/cmsData/content_mapping.json index 43a812fa..034d76f1 100644 --- a/ui/src/cmsData/content_mapping.json +++ b/ui/src/cmsData/content_mapping.json @@ -142,6 +142,7 @@ ], "_version": 3 }, + "table_search_placeholder": "Search in Fields...", "search_placeholder": "Search for content types...", "tags": [], "title": "Content Mapping", diff --git a/ui/src/components/ContentMapper/index.scss b/ui/src/components/ContentMapper/index.scss index 037652b7..b7ec331d 100644 --- a/ui/src/components/ContentMapper/index.scss +++ b/ui/src/components/ContentMapper/index.scss @@ -4,7 +4,7 @@ .content-types-list-wrapper { display: flex; flex-direction: column; - max-height: calc(100vh - 173px); + // max-height: calc(100vh - 173px); max-width: 25%; overflow: hidden; width: 100%; @@ -38,6 +38,7 @@ } } .ct-list-wrapper { + height: calc(100vh - 375px); overflow-y: auto; overflow-x: hidden; } @@ -63,6 +64,11 @@ } } } +.dropdown-align { + .Dropdown__menu--primary { + right: 0.25rem; + } +} .content-type-list { padding-left: 12px; } @@ -100,6 +106,9 @@ margin: 0; } } + .import-cta { + margin: 0; + } } .disabled-field { color: $color-font-disabled; diff --git a/ui/src/components/ContentMapper/index.tsx b/ui/src/components/ContentMapper/index.tsx index eb0dcea6..19680ce8 100644 --- a/ui/src/components/ContentMapper/index.tsx +++ b/ui/src/components/ContentMapper/index.tsx @@ -15,7 +15,8 @@ import { InstructionText, ModalHeader, ModalBody, - ModalFooter + ModalFooter, + Dropdown } from '@contentstack/venus-components'; import { jsonToHtml } from '@contentstack/json-rte-serializer'; import HTMLReactParser from 'html-react-parser'; @@ -109,6 +110,7 @@ interface ModalProps { newIndex: number; closeModal: () => void; } + const ContentMapper = () => { /** ALL CONTEXT HERE */ @@ -124,7 +126,8 @@ const ContentMapper = () => { description, // action_cta: actionCta, // cta, - search_placeholder: searchPlaceholder + search_placeholder: searchPlaceholder, + table_search_placeholder: tableSearchPlaceholder }= {} } = migrationData; @@ -211,8 +214,8 @@ const ContentMapper = () => { useEffect(() => { if (contentTypeMapped && otherCmsTitle) { setOtherContentType({ - label: contentTypeMapped?.[otherCmsTitle] ?? 'Select Content Type', - value: contentTypeMapped?.[otherCmsTitle] ?? 'Select Content Type' + label: contentTypeMapped?.[otherCmsTitle] ?? 'Select content type from existing stack', + value: contentTypeMapped?.[otherCmsTitle] ?? 'Select content type from existing stack' }); } }, [contentTypeMapped, otherCmsTitle]); @@ -439,7 +442,7 @@ const ContentMapper = () => { setTableData(newTableData); }; - const handleOnClick = (title: string) => { + const handleSchemaPreview = (title: string) => { return cbModal({ component: (props: ModalObj) => ( {
    @@ -1101,8 +1118,20 @@ const ContentMapper = () => { getSelectedRow={handleSelectedEntries} rowSelectCheckboxProp={{ key: '_canSelect', value: true }} /> +
    + +
    + + {/* {actionCta && validateArray(actionCta) && (
    - {restoreCta?.title} - - ), - type: 'secondary' - }, { label: cta && cta?.title && ( +
    +
    ); diff --git a/ui/src/components/LegacyCms/index.tsx b/ui/src/components/LegacyCms/index.tsx index 230fec41..ef89fb09 100644 --- a/ui/src/components/LegacyCms/index.tsx +++ b/ui/src/components/LegacyCms/index.tsx @@ -167,13 +167,18 @@ const LegacyCMSComponent = forwardRef(({ legacyCMSData, projectData, isCompleted ) { setInternalActiveStepIndex(2); } - dispatch(updateNewMigrationData({ ...newMigrationData, legacy_cms: { selectedCms: selectedCmsData, selectedFileFormat: selectedFileFormatData || defaultCardType, - uploadedFile: newMigrationData?.legacy_cms?.uploadedFile, //need to add backend data once endpoint exposed. + uploadedFile: { + file_details:{ + localPath: legacyCMSData?.file_path, + awsData: legacyCMSData?.awsDetails + }, + isValidated: legacyCMSData?.is_fileValid + }, //need to add backend data once endpoint exposed. affix: legacyCMSData?.affix || newMigrationData?.legacy_cms?.affix || '', isFileFormatCheckboxChecked: true, //need to add backend data once endpoint exposed. isRestictedKeywordCheckboxChecked: true //need to add backend data once endpoint exposed. diff --git a/ui/src/components/LegacyCms/legacyCms.scss b/ui/src/components/LegacyCms/legacyCms.scss index b6bfcb8b..deae77be 100644 --- a/ui/src/components/LegacyCms/legacyCms.scss +++ b/ui/src/components/LegacyCms/legacyCms.scss @@ -120,4 +120,11 @@ line-height: 185%; color: $color-base-gray-20; margin-bottom: $space-10; +} +.bar-container{ + height: 10px; + width: 592px; + align-items: center; + margin-left: 20px !important; + margin-top: 10px; } \ No newline at end of file diff --git a/ui/src/context/app/app.interface.ts b/ui/src/context/app/app.interface.ts index 743e885e..6adb7fe8 100644 --- a/ui/src/context/app/app.interface.ts +++ b/ui/src/context/app/app.interface.ts @@ -54,7 +54,7 @@ export interface IFile { url?: string; validation?: string; file_details?: FileDetails; - isValidated?: boolean; + isValidated: boolean; } export interface ICMSType extends ICardType { From c9671a6a04f5ee35b1782c0392a1e3d5a2567709 Mon Sep 17 00:00:00 2001 From: snehalsankhe Date: Mon, 17 Jun 2024 18:23:05 +0530 Subject: [PATCH 13/19] added destination stack code --- ui/src/cmsData/destinationStack.json | 3 +- .../Actions/LoadOrganisation.tsx | 37 ++++++++++--------- .../DestinationStack/Actions/LoadStacks.tsx | 2 +- .../DestinationStack/DestinationStack.scss | 20 +++++++--- ui/src/components/ProjectsHeader/index.tsx | 15 -------- .../VerticalStepper/AutoVerticalStepper.scss | 8 ++++ .../VerticalStepper/AutoVerticalStepper.tsx | 7 +++- 7 files changed, 52 insertions(+), 40 deletions(-) diff --git a/ui/src/cmsData/destinationStack.json b/ui/src/cmsData/destinationStack.json index 7a52910a..9f1267f7 100644 --- a/ui/src/cmsData/destinationStack.json +++ b/ui/src/cmsData/destinationStack.json @@ -11,7 +11,8 @@ { "step_id": "Step1", "_metadata": { "uid": "cs45d60445c89ed302" }, - "title": "Organization (read only)", + "title": "Organization", + "ifReadonly": true, "description": "", "lock": false, "active": true, diff --git a/ui/src/components/DestinationStack/Actions/LoadOrganisation.tsx b/ui/src/components/DestinationStack/Actions/LoadOrganisation.tsx index 0ef05243..d9b799ee 100644 --- a/ui/src/components/DestinationStack/Actions/LoadOrganisation.tsx +++ b/ui/src/components/DestinationStack/Actions/LoadOrganisation.tsx @@ -23,7 +23,7 @@ const LoadOrganisation = (props: LoadOrganisationProps) => { const dispatch = useDispatch(); - // const [selectedOrg, setSelectedOrg] = useState(); + const [selectedOrg, setSelectedOrg] = useState(); /**** ALL METHODS HERE ****/ @@ -31,23 +31,25 @@ const LoadOrganisation = (props: LoadOrganisationProps) => { const setNewMigrationData = (data: INewMigration) => { dispatch(updateNewMigrationData((data))); }; + + const textInput = newMigrationData?.destination_stack?.selectedOrg?.label //Handle Organisation selection // const handleDropdownChange = (data: ChangeEvent) => { - // // if (selectedOrg?.value !== data?.value) { - // // setSelectedOrg(() => ({ ...data })); - - // // setNewMigrationData({ - // // ...newMigrationData, - // // destination_stack: { - // // ...newMigrationData.destination_stack, - // // selectedOrg: { ...data } - // // } - // // }); - // // } - - // //call for Step Change - // // props.handleStepChange(props.currentStep); + // if (selectedOrg?.value !== data?.value) { + // setSelectedOrg(() => ({ ...data })); + + // setNewMigrationData({ + // ...newMigrationData, + // destination_stack: { + // ...newMigrationData.destination_stack, + // selectedOrg: { ...data } + // } + // }); + // } + + // call for Step Change + // props.handleStepChange(props.currentStep); // }; /**** ALL USEEffects HERE ****/ @@ -57,7 +59,7 @@ const LoadOrganisation = (props: LoadOrganisationProps) => { ? newMigrationData?.destination_stack?.selectedOrg : selectedOrganisation; - // setSelectedOrg(org as any); + setSelectedOrg(org as any); setNewMigrationData({ ...newMigrationData, @@ -67,6 +69,7 @@ const LoadOrganisation = (props: LoadOrganisationProps) => { } }); }, []); + return (
    {/*
    @@ -84,7 +87,7 @@ const LoadOrganisation = (props: LoadOrganisationProps) => {
    */} { canEditOption={true} value={selectedStack} isSearchable={true} - isClearable={true} + // isClearable={true} width="600px" isDisabled={props?.stepComponentProps?.isSummary || false} placeholder={'Select a stack'} diff --git a/ui/src/components/DestinationStack/DestinationStack.scss b/ui/src/components/DestinationStack/DestinationStack.scss index afb15c85..154401e8 100644 --- a/ui/src/components/DestinationStack/DestinationStack.scss +++ b/ui/src/components/DestinationStack/DestinationStack.scss @@ -71,6 +71,7 @@ // max-width: 430px; width: 100%; margin: 0; + padding-bottom: 0; .Select__v2 .Select__menu .Select__menu-list .Select__option { padding: 12px !important; } @@ -84,7 +85,7 @@ position: relative; &:last-child { border-top: 1px solid $color-brand-secondary-lightest; - position: absolute; + position: sticky; bottom: 0; color: $color-brand-primary-base; font-weight: $font-weight-semi-bold; @@ -105,12 +106,21 @@ } } - -.TextInput--disabled .TextInput__v2 { - background-color: $color-base-white-5 !important; - color: $color-font-black; +.action-summary-wrapper { + .Select .Select__control .Select__value-container.Select__value-container--has-value .Select__single-value input { + width: 100% !important; + background-color: $color-brand-white-base; + font-size: $size-font-xl; + color: $color-black-2121; + font-weight: $font-weight-regular; + } + .TextInput--disabled .TextInput__v2 { + background-color: $color-base-white-5 !important; + color: $color-black-2121; + } } + .locale-container { display: flex; background-color: $color-base-white-5; diff --git a/ui/src/components/ProjectsHeader/index.tsx b/ui/src/components/ProjectsHeader/index.tsx index a92a7afa..493867fc 100644 --- a/ui/src/components/ProjectsHeader/index.tsx +++ b/ui/src/components/ProjectsHeader/index.tsx @@ -62,21 +62,6 @@ const ProjectsHeader = ({ const pageActions: any = [ - { - label:( - - ), - type: 'secondary' - }, { label: cta && cta?.title && (