handleToggleChange("unique" , e?.target?.checked,true)}
/>
+
handleToggleChange("nonLocalizable" , e?.target?.checked,true)}
/>
+
+
If enabled, editing this field is restricted in localized entries. The field will use
the value of the master-language entry in all localized entries.
diff --git a/ui/src/components/Common/AddStack/addStack.tsx b/ui/src/components/Common/AddStack/addStack.tsx
index d45581423..9d948f472 100644
--- a/ui/src/components/Common/AddStack/addStack.tsx
+++ b/ui/src/components/Common/AddStack/addStack.tsx
@@ -44,7 +44,7 @@ const AddStack = (props: any): JSX.Element => {
const [addStackCMSData, setAddStackCMSData] = useState(defaultAddStackCMSData);
const onSubmit = async (formData: any) => {
setIsProcessing(true);
- const resp = await props.onSubmit({
+ const resp = await props?.onSubmit({
name: formData?.name || props?.defaultValues?.name,
description: formData?.description || props?.defaultValues?.description,
locale: formData?.locale?.value || props?.defaultValues?.locale
@@ -55,7 +55,7 @@ const AddStack = (props: any): JSX.Element => {
notificationContent: { text: 'Stack created successfully' },
type: 'success'
});
- props.closeModal();
+ props?.closeModal();
} else {
Notification({ notificationContent: { text: 'Failed to create the stack' }, type: 'error' });
}
@@ -88,7 +88,8 @@ const AddStack = (props: any): JSX.Element => {
uid: key,
label: response?.data?.locales[key],
value: key,
- locale: key,
+ master_locale: key,
+ locales:[],
created_at: key
}))
: [];
diff --git a/ui/src/components/ContentMapper/contentMapper.interface.ts b/ui/src/components/ContentMapper/contentMapper.interface.ts
index 77287cd11..997c47d0e 100644
--- a/ui/src/components/ContentMapper/contentMapper.interface.ts
+++ b/ui/src/components/ContentMapper/contentMapper.interface.ts
@@ -9,6 +9,13 @@ interface mapDataType {
contentTypes: ContentType[];
projectId: string;
}
+interface Advanced {
+ ValidationRegex: string,
+ mandatory:boolean,
+ multiple:boolean,
+ unique:boolean,
+ nonLocalizable:boolean
+}
export interface ContentMapperType {
content_types_heading?: string;
cta: CTA;
@@ -24,7 +31,7 @@ export interface ContentstackFields {
export interface FieldTypes {
label: string;
- value: string;
+ value: any;
}
export interface TableTypes {
sortBy: any;
@@ -57,6 +64,7 @@ export interface FieldMapType {
uid: string;
id: string;
_invalid?: boolean;
+ advanced:Advanced
}
export interface ItemStatus {
diff --git a/ui/src/components/ContentMapper/index.tsx b/ui/src/components/ContentMapper/index.tsx
index ffd9b51a7..1f43a9f72 100644
--- a/ui/src/components/ContentMapper/index.tsx
+++ b/ui/src/components/ContentMapper/index.tsx
@@ -12,7 +12,10 @@ import {
Tooltip,
Notification,
cbModal,
- InstructionText
+ InstructionText,
+ ModalHeader,
+ ModalBody,
+ ModalFooter
} from '@contentstack/venus-components';
import { jsonToHtml } from '@contentstack/json-rte-serializer';
import HTMLReactParser from 'html-react-parser';
@@ -84,7 +87,11 @@ const Fields: Mapping = {
interface ContentTypeMap {
[key: string]: string;
}
-
+interface ModalProps {
+ e:React.MouseEvent;
+ newIndex:number;
+ closeModal: () => void;
+}
const ContentMapper = () => {
/** ALL CONTEXT HERE */
const {
@@ -135,6 +142,16 @@ const ContentMapper = () => {
const [otherCmsUid, setotherCmsUid] = useState(contentTypes[0]?.otherCmsUid);
const [isContentTypeMapped, setisContentTypeMapped] = useState(false);
const [isContentTypeSaved, setisContentTypeSaved] = useState(false);
+ const [advancePropertise, setadvancePropertise] = useState({
+ validationRegex:'',
+ Mandatory: false,
+ Multiple: false,
+ Unique: false,
+ NonLocalizable: false
+ });
+ const [isLocalised, setisLocalised] = useState(newMigrationData?.destination_stack?.selectedStack?.locales?.length > 1 ? true : false);
+
+
const [active, setActive] = useState(null ?? 0);
@@ -325,28 +342,89 @@ const ContentMapper = () => {
//function to handle previous content type navigation
const handlePrevClick = (e: React.MouseEvent) => {
const newIndex = currentIndex > 0 ? currentIndex - 1 : 0;
- setCurrentIndex(newIndex);
- openContentType(e, newIndex);
- document.querySelectorAll('.ct-list li').forEach((ctLi, ind) => {
- if (newIndex === ind) {
- ctLi?.classList?.add('active-ct');
- }
- });
- };
+ if(isDropDownChanged){
+ handleSaveContentTypeModal(e, newIndex)
- // function to handle next content type navigation
- const handleNextClick = (e: React.MouseEvent) => {
- if (currentIndex < contentTypes?.length - 1) {
- const newIndex = currentIndex + 1;
+ }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');
+ }
+ })
+
+ }
+
}
};
+ const SaveContentType = (props:ModalProps) => {
+
+ return (
+ <>
+
+
+ Hey there! You have unsaved changes on this page.
+
+
+
+
+
+
+
+
+ >
+ );
+ }
+ const handleSaveContentTypeModal = (e:any, newIndex:number) => {
+ return cbModal({
+ component: (props: ModalObj) => (
+
+ ),
+ modalProps: {
+ shouldCloseOnOverlayClick: true,
+ size: 'small'
+ }
+ });
+ }
// Function to get exisiting content types list
const fetchExistingContentTypes = async () => {
@@ -355,7 +433,26 @@ const ContentMapper = () => {
setContentTypesList(data?.contentTypes);
}
};
+
+ const updateFieldSettings = (rowId:string, updatedSettings:any, checkBoxChanged:boolean) => {
+ setisDropDownCHanged(checkBoxChanged);
+ //setadvancePropertise(...updatedSettings);
+
+ const newTableData = tableData?.map(row => {
+ if (row?.uid === rowId) {
+ setadvancePropertise({...row?.advanced, ...updatedSettings});
+
+ return { ...row, advanced: { ...row?.advanced, ...updatedSettings } };
+ }
+ return row;
+ });
+
+
+ setTableData(newTableData);
+ };
+
+
const handleOnClick = (title: string) => {
return cbModal({
component: (props: ModalObj) => (
@@ -415,15 +512,20 @@ const ContentMapper = () => {
const handleAdvancedSetting = (
fieldtype: string,
- fieldvalue: ExistingFieldType,
- rowId: string
+ fieldvalue: any,
+ rowId: string,
+ data: any
) => {
+
return cbModal({
component: (props: ModalObj) => (
),
@@ -438,7 +540,7 @@ const ContentMapper = () => {
const data = {
name: newMigrationData?.destination_stack?.selectedStack?.label,
description: 'test migration stack',
- master_locale: newMigrationData?.destination_stack?.selectedStack?.locale
+ master_locale: newMigrationData?.destination_stack?.selectedStack?.master_locale
};
const res = await createTestStack(
newMigrationData?.destination_stack?.selectedOrg?.value,
@@ -480,24 +582,35 @@ const ContentMapper = () => {
isDisabled={data?.ContentstackFieldType === "group"}
/>
-
- handleAdvancedSetting(data?.ContentstackFieldType, exstingField, data?.uid)
- }
- />
+
+
+ handleAdvancedSetting(data?.ContentstackFieldType, data?.advanced, data?.uid, data)
+ }
+ />
+
+
+
);
};
- const handleFieldChange = (selectedValue: FieldTypes, rowIndex: string) => {
+ const handleFieldChange = (selectedValue: FieldTypes, rowIndex: string) => {
setisDropDownCHanged(true);
setexsitingField((prevOptions) => ({
...prevOptions,
[rowIndex]: { label: selectedValue?.label, value: selectedValue?.value }
}));
+ setadvancePropertise({
+ validationRegex: selectedValue?.value?.format,
+ Mandatory: selectedValue?.value?.mandatory,
+ Multiple: selectedValue?.value?.multiple,
+ Unique: selectedValue?.value?.unique,
+ NonLocalizable: selectedValue?.value?.non_localizable
+ });
if (isDropDownChanged && isContentTypeSaved) {
setSelectedOptions((prevSelected) => {
@@ -508,11 +621,23 @@ const ContentMapper = () => {
const updatedRows = tableData.map((row) => {
if (row?.uid === rowIndex) {
- return { ...row, contentstackField: selectedValue?.label };
+
+ return {
+ ...row,
+ contentstackField: selectedValue?.label,
+ advanced:{
+ validationRegex: selectedValue?.value?.format,
+ Mandatory: selectedValue?.value?.mandatory,
+ Multiple: selectedValue?.value?.multiple,
+ Unique: selectedValue?.value?.unique,
+ NonLocalizable: selectedValue?.value?.non_localizable
+ }
+ };
}
return row;
});
- setTableData(updatedRows);
+
+ setTableData(updatedRows as FieldMapType[]);
};
const SelectAccessorOfColumn = (data: FieldMapType) => {
@@ -618,8 +743,7 @@ const ContentMapper = () => {
const adjustedOptions = OptionsForRow.map((option: optionsType) => ({
...option,
isDisabled: selectedOptions?.includes(option?.label ?? '')
- }));
-
+ }));
return (
@@ -637,8 +761,15 @@ const ContentMapper = () => {
version="v2"
icon="Setting"
size="small"
- onClick={() =>
- handleAdvancedSetting(data?.ContentstackFieldType, exstingField, data?.uid)
+ onClick={() =>{
+ const value ={
+ ValidationRegex: data?.advanced?.ValidationRegex,
+ Mandatory: data?.advanced?.mandatory,
+ Multiple: data?.advanced?.multiple,
+ Unique: data?.advanced?.unique,
+ NonLocalizable: data?.advanced?.nonLocalizable
+ }
+ handleAdvancedSetting(data?.ContentstackFieldType, advancePropertise, data?.uid, data)}
}
/>
@@ -801,7 +932,7 @@ const ContentMapper = () => {
const adjustedOption = options.map((option: any) => ({
...option,
isDisabled: contentTypeMapped && Object.values(contentTypeMapped).includes(option?.label)
- }));
+ }));
return (
diff --git a/ui/src/components/DestinationStack/Actions/LoadStacks.tsx b/ui/src/components/DestinationStack/Actions/LoadStacks.tsx
index 454910cac..661e866c5 100644
--- a/ui/src/components/DestinationStack/Actions/LoadStacks.tsx
+++ b/ui/src/components/DestinationStack/Actions/LoadStacks.tsx
@@ -38,7 +38,8 @@ const LoadStacks = (props: LoadFileFormatProps) => {
label: 'Loading stacks...',
value: 'loading',
default: false,
- locale: '',
+ master_locale:'',
+ locales:[],
created_at: ''
}
];
@@ -74,7 +75,8 @@ const LoadStacks = (props: LoadFileFormatProps) => {
const newCreatedStack: IDropDown = {
label: resp?.data?.stack?.name,
value: resp?.data?.stack?.api_key,
- locale: resp?.data?.stack?.master_locale,
+ master_locale: resp?.data?.stack?.master_locale,
+ locales: resp?.data?.stack?.locales,
created_at: resp?.data?.stack?.created_at,
uid: resp?.data?.stack?.api_key
};
@@ -145,7 +147,8 @@ const LoadStacks = (props: LoadFileFormatProps) => {
label: stack?.name,
value: stack?.api_key,
uid: stack?.api_key,
- locale: stack?.master_locale,
+ master_locale: stack?.master_locale,
+ locales: stack?.locales,
created_at: stack?.created_at
}))
: [];
@@ -231,7 +234,7 @@ const LoadStacks = (props: LoadFileFormatProps) => {
- {selectedStack?.locale}
+ {selectedStack?.master_locale}
diff --git a/ui/src/components/DestinationStack/Summary/StacksSummary.tsx b/ui/src/components/DestinationStack/Summary/StacksSummary.tsx
index 2728a0361..ebb20d70d 100644
--- a/ui/src/components/DestinationStack/Summary/StacksSummary.tsx
+++ b/ui/src/components/DestinationStack/Summary/StacksSummary.tsx
@@ -25,7 +25,8 @@ const StacksSummary = (props: StacksSummaryProps): JSX.Element => {
label: 'Loading stacks...',
value: 'loading',
default: false,
- locale: '',
+ master_locale: '',
+ locales:[],
created_at: ''
}
];
@@ -57,7 +58,7 @@ const StacksSummary = (props: StacksSummaryProps): JSX.Element => {
- {selectedStack?.locale}
+ {selectedStack?.master_locale}
diff --git a/ui/src/components/DestinationStack/index.tsx b/ui/src/components/DestinationStack/index.tsx
index 720b86cb7..f08cae353 100644
--- a/ui/src/components/DestinationStack/index.tsx
+++ b/ui/src/components/DestinationStack/index.tsx
@@ -83,7 +83,8 @@ const DestinationStackComponent = ({
let selectedStackData: IDropDown = {
value: destination_stack,
label: '',
- locale: '',
+ master_locale: '',
+ locales:[],
created_at: ''
};
@@ -103,7 +104,8 @@ const DestinationStackComponent = ({
selectedStackData = {
label: stack?.name,
value: stack?.api_key,
- locale: stack?.master_locale,
+ master_locale: stack?.master_locale,
+ locales: stack?.locales,
created_at: stack?.created_at
};
}
diff --git a/ui/src/components/MigrationExecution/index.tsx b/ui/src/components/MigrationExecution/index.tsx
index 62fc10b0e..47a63e89a 100644
--- a/ui/src/components/MigrationExecution/index.tsx
+++ b/ui/src/components/MigrationExecution/index.tsx
@@ -52,7 +52,7 @@ const MigrationExecution = () => {
return newMigrationData?.destination_stack?.selectedStack?.label;
case 'Selected locale':
- return newMigrationData?.destination_stack?.selectedStack?.locale;
+ return newMigrationData?.destination_stack?.selectedStack?.master_locale;
}
};
diff --git a/ui/src/context/app/app.interface.ts b/ui/src/context/app/app.interface.ts
index 919d5ef7e..d17692ba0 100644
--- a/ui/src/context/app/app.interface.ts
+++ b/ui/src/context/app/app.interface.ts
@@ -136,7 +136,10 @@ interface FieldTypes {
label: string;
value: string;
}
-
+interface locales {
+ code:string;
+ name:string
+}
export interface ILegacyCms {
selectedCms: ICMSType;
selectedFileFormat: ICardType;
@@ -177,7 +180,8 @@ export interface IDropDown {
label: string;
value: string;
default?: boolean;
- locale: string;
+ master_locale: string;
+ locales:locales[];
created_at: string;
}
export interface ITestMigration {
@@ -205,7 +209,8 @@ export const DEFAULT_DROPDOWN: IDropDown = {
value: '',
default: false,
uid: '',
- locale: '',
+ master_locale: '',
+ locales:[],
created_at: ''
};
diff --git a/ui/src/services/api/service.interface.ts b/ui/src/services/api/service.interface.ts
index bb72271c1..3a3fa636f 100644
--- a/ui/src/services/api/service.interface.ts
+++ b/ui/src/services/api/service.interface.ts
@@ -12,6 +12,7 @@ export interface StackResponse {
name: string;
api_key: string;
master_locale: string;
+ locales:[];
created_at: string;
}