From f96e34dd481f943a7a32244f5f67d070f7f05f76 Mon Sep 17 00:00:00 2001 From: Sayali Joshi Date: Tue, 11 Jun 2024 17:24:41 +0530 Subject: [PATCH 1/3] 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 ca22c2f2f..e578593c2 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 a0eba06ec..43a812fa3 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 33ca9ad58..037652b74 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 f0ca20704..90d426bc7 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 ddc489626..b76ecbd76 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 17773cb6c..bc3afcbe1 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 196209e95805e0152abcd13c1554ca409a566264 Mon Sep 17 00:00:00 2001 From: Sayali Joshi Date: Fri, 14 Jun 2024 16:34:14 +0530 Subject: [PATCH 2/3] 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 43a812fa3..034d76f1e 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 037652b74..b7ec331de 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 eb0dcea6c..19680ce80 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 && (