Skip to content

Commit 34cfd0c

Browse files
Merge pull request #724 from contentstack/bugfix/cmg-616
refactor:added alert box for refresh and refactored the issue of cont…
2 parents d65604f + 1d2d51d commit 34cfd0c

File tree

8 files changed

+88
-26
lines changed

8 files changed

+88
-26
lines changed

ui/src/components/ContentMapper/contentMapper.interface.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,4 +206,5 @@ export interface ModifiedField {
206206
backupFieldType: string;
207207
parentId: string;
208208
uid: string;
209+
_canSelect?: boolean;
209210
}

ui/src/components/ContentMapper/index.tsx

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R
272272

273273
const [searchContentType, setSearchContentType] = useState('');
274274

275-
const [rowIds, setRowIds] = useState({});
275+
const [rowIds, setRowIds] = useState<Record<string, boolean>>({});
276276
const [selectedEntries, setSelectedEntries] = useState<FieldMapType[]>([]);
277277
const [contentTypeSchema, setContentTypeSchema] = useState<ContentTypesSchema[] | undefined>([]);
278278
const [showFilter, setShowFilter] = useState<boolean>(false);
@@ -292,7 +292,7 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R
292292
const [isCsCTypeUpdated, setsCsCTypeUpdated] = useState<boolean>(false);
293293
const [isLoadingSaveButton, setisLoadingSaveButton] = useState<boolean>(false);
294294
const [activeFilter, setActiveFilter] = useState<string>('');
295-
295+
const [isAllCheck, setIsAllCheck] = useState<boolean>(false);
296296

297297
/** ALL HOOKS Here */
298298
const { projectId = '' } = useParams();
@@ -361,6 +361,7 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R
361361

362362

363363
if (newMigrationData?.content_mapping?.content_type_mapping?.[selectedContentType?.contentstackUid || ''] === otherContentType?.id) {
364+
setIsAllCheck(false);
364365
tableData?.forEach((row) => {
365366
contentTypeSchema?.forEach((schema) => {
366367

@@ -432,14 +433,16 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R
432433
}, [tableData, otherContentType]);
433434

434435
useEffect(() => {
435-
if (isUpdated) {
436+
if (isUpdated) {
437+
setIsAllCheck(false);
436438
setTableData(updatedRows);
437439
setExistingField(updatedExstingField);
438440
setSelectedOptions(updatedSelectedOptions);
439441
setSelectedEntries(updatedRows);
440442
setIsUpdated(false);
441443
}
442444
else{
445+
setIsAllCheck(false);
443446
setExistingField({});
444447
setSelectedOptions([]);
445448

@@ -449,15 +452,15 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R
449452
// To make all the fields checked
450453
useEffect(() => {
451454
const selectedId = tableData?.reduce<UidMap>((acc, item) => {
452-
if(!item?.isDeleted) {
455+
if(!item?.isDeleted && isAllCheck) {
453456
acc[item?.id] = true;
454457

455458
}
456459
return acc;
457460
}, {});
458461

459-
setRowIds(selectedId);
460-
}, [tableData]);
462+
isAllCheck && setRowIds(selectedId);
463+
}, [tableData, isAllCheck]);
461464

462465
// To fetch existing content types or global fields as per the type
463466
useEffect(() => {
@@ -542,6 +545,7 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R
542545
},[contentTypeSchema]);
543546
useEffect(() => {
544547
if (existingField && isCsCTypeUpdated) {
548+
setIsAllCheck(false);
545549
const matchedKeys = new Set<string>();
546550

547551
contentTypeSchema?.forEach((item) => {
@@ -672,7 +676,7 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R
672676
setItemStatusMap({ ...itemStatusMap });
673677

674678
const validTableData = data?.fieldMapping?.filter((field: FieldMapType) => field?.otherCmsType !== undefined);
675-
679+
setIsAllCheck(true);
676680
setTableData(validTableData ?? []);
677681
setSelectedEntries(validTableData ?? []);
678682
setTotalCounts(validTableData?.length);
@@ -717,7 +721,8 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R
717721
// eslint-disable-next-line no-unsafe-optional-chaining
718722
setTableData([...tableData, ...validTableData ?? tableData]);
719723
setTotalCounts([...tableData, ...validTableData ?? tableData]?.length);
720-
setIsLoading(false)
724+
setIsLoading(false);
725+
setIsAllCheck(true);
721726
} catch (error) {
722727
console.error('loadMoreItems -> error', error);
723728
}
@@ -749,6 +754,7 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R
749754
};
750755

751756
const openContentType = (i: number) => {
757+
setIsAllCheck(true);
752758
setIsFieldDeleted(false);
753759
setActive(i);
754760
const otherTitle = filteredContentTypes?.[i]?.contentstackUid;
@@ -821,24 +827,26 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R
821827

822828
// add row ids with their data to rowHistoryObj
823829
useEffect(() => {
830+
setIsAllCheck(false);
824831
Object.keys(rowHistoryObj)?.forEach(key => delete rowHistoryObj[key]);
825832
tableData?.forEach(item => {
826833
rowHistoryObj[item?.id] = [{checked: true, at: Date.now(), ...modifiedObj(item)}]
827834
});
828835
}, [tableData]);
829836

830-
const getParentId = (uid: string) => {
831-
return tableData?.find(i => i?.uid?.toLowerCase() === uid?.toLowerCase())?.id ?? ''
837+
const getParentId = (uid: string) => {
838+
return tableData?.find((i) => i?.uid?.toLowerCase() === uid?.toLowerCase() && i?.backupFieldType?.toLowerCase() === 'group')?.id ?? ''
832839
}
833840

834841
const modifiedObj = (obj: FieldMapType) => {
835-
const {backupFieldType, uid, id} = obj ?? {}
842+
const {backupFieldType, uid, id, _canSelect} = obj ?? {}
836843
const excludeArr = ["group"]
837844
return {
838845
id,
839846
backupFieldType,
840847
uid,
841-
parentId : excludeArr?.includes?.(backupFieldType?.toLowerCase()) ? '' : getParentId(uid?.split('.')[0]?.toLowerCase())
848+
parentId : excludeArr?.includes?.(backupFieldType?.toLowerCase()) ? '' : getParentId(uid?.split('.')[0]?.toLowerCase()),
849+
_canSelect,
842850
}
843851
}
844852

@@ -886,7 +894,7 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R
886894

887895
const handleSelectedEntries = (singleSelectedRowIds: string[]) => {
888896
const selectedObj: UidMap = {};
889-
897+
setIsAllCheck(false);
890898
singleSelectedRowIds?.forEach((uid: string) => {
891899
const isId = selectedEntries?.some((item) => item?.id === uid);
892900
if (isId) {
@@ -940,7 +948,7 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R
940948
})
941949
}
942950
}
943-
} else if(latestRow?.parentId && !["title", "url"]?.includes?.(latestRow?.uid?.toLowerCase())){
951+
} else if(latestRow?.parentId && latestRow?._canSelect === true){
944952
// Extract the group UID if item is child of any group
945953
const uidBeforeDot = latestRow?.uid?.split?.('.')?.[0]?.toLowerCase();
946954
const groupItem = tableData?.find((entry) => entry?.uid?.toLowerCase() === uidBeforeDot);
@@ -972,7 +980,7 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R
972980
}
973981
}
974982

975-
const updatedTableData = tableData?.map?.((tableItem) => {
983+
const updatedTableData = selectedEntries?.map?.((tableItem) => {
976984
// Mark the item as deleted if not found in selectedData
977985
return {
978986
...tableItem,
@@ -988,6 +996,7 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R
988996
const handleValueChange = (value: FieldTypes, rowIndex: string, rowContentstackFieldUid: string) => {
989997
setIsDropDownChanged(true);
990998
setFieldValue(value);
999+
setIsAllCheck(false);
9911000
const updatedRows: FieldMapType[] = selectedEntries?.map?.((row) => {
9921001
if (row?.uid === rowIndex && row?.contentstackFieldUid === rowContentstackFieldUid) {
9931002
return { ...row, contentstackFieldType: value?.value };
@@ -1010,7 +1019,7 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R
10101019

10111020
const handleDropDownChange = (value: FieldTypes) => {
10121021
(value?.id !== otherContentType?.id) && setsCsCTypeUpdated(true);
1013-
1022+
setIsAllCheck(false);
10141023
setOtherContentType(value);
10151024
};
10161025

@@ -1503,6 +1512,7 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R
15031512
if (!updatedSelectedOptions?.includes?.(newValue)) {
15041513
updatedSelectedOptions.push(newValue);
15051514
}
1515+
setIsAllCheck(false);
15061516
setIsUpdated(true);
15071517
}
15081518

@@ -1620,6 +1630,7 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R
16201630

16211631
const handleSaveContentType = async () => {
16221632
setisLoadingSaveButton(true);
1633+
setIsAllCheck(false);
16231634
const orgId = selectedOrganisation?.uid;
16241635
const projectID = projectId;
16251636
if (

ui/src/components/DestinationStack/Actions/LoadLanguageMapper.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ const LanguageMapper = ({stack, uid} :{ stack : IDropDown, uid : string}) => {
480480
const [cmsLocaleOptions, setcmsLocaleOptions] = useState<{ label: string; value: string }[]>([]);
481481
const [sourceLocales, setsourceLocales] = useState<{ label: string; value: string }[]>([]);
482482
const [isLoading, setisLoading] = useState<boolean>(false);
483-
const [currentStack, setCurrentStack] = useState<IDropDown>();
483+
const [currentStack, setCurrentStack] = useState<IDropDown>(stack);
484484
const [previousStack, setPreviousStack] = useState<IDropDown>();
485485
const [isStackChanged, setisStackChanged] = useState<boolean>(false);
486486
const [stackValue, setStackValue] = useState<string>(stack?.value)

ui/src/components/DestinationStack/Actions/LoadStacks.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ const LoadStacks = (props: LoadFileFormatProps) => {
8686
const [placeholder] = useState<string>('Select a stack');
8787
const [localePlaceholder, setlocalePlaceholder ] = useState<string>('Master Locale will be set after stack selection');
8888
const newMigrationDataRef = useRef(newMigrationData);
89+
const [isStackLoading, setIsStackLoading] = useState<boolean>(true);
8990

9091
useEffect(() => {
9192
newMigrationDataRef.current = newMigrationData;
@@ -111,6 +112,7 @@ const LoadStacks = (props: LoadFileFormatProps) => {
111112
const handleOnSave = async (data: Stack) => {
112113
try {
113114
// Post data to backend
115+
setIsStackLoading(true);
114116
const resp = await createStacksInOrg(selectedOrganisation?.value, {
115117
...data,
116118
master_locale: data?.locale
@@ -153,6 +155,7 @@ const LoadStacks = (props: LoadFileFormatProps) => {
153155
};
154156

155157
dispatch(updateNewMigrationData(newMigrationDataObj));
158+
setIsStackLoading(false);
156159
// call for Step Change
157160
props.handleStepChange(props?.currentStep, true);
158161

@@ -357,7 +360,7 @@ const LoadStacks = (props: LoadFileFormatProps) => {
357360
</div>
358361
</div>
359362

360-
{newMigrationData?.destination_stack?.selectedStack?.value && (
363+
{newMigrationData?.destination_stack?.selectedStack?.value && (!isEmptyString(newMigrationData?.destination_stack?.selectedStack?.value) || !isStackLoading) &&(
361364
<div className="language-mapper">
362365
<div className="info-lang">
363366
<div className="stackTitle language-title">Language Mapping</div>
@@ -375,7 +378,7 @@ const LoadStacks = (props: LoadFileFormatProps) => {
375378
</div>
376379
<LanguageMapper
377380
uid={selectedStack?.uid ?? ''}
378-
stack={selectedStack ?? DEFAULT_DROPDOWN} />
381+
stack={newMigrationData?.destination_stack?.selectedStack ?? DEFAULT_DROPDOWN} />
379382
</div>
380383
)}
381384
</div>

ui/src/components/DestinationStack/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ const DestinationStackComponent = ({
101101
},[newMigrationData?.isprojectMapped]);
102102

103103
useEffect(()=>{
104-
if(! isEmptyString(newMigrationData?.destination_stack?.selectedStack?.value )
104+
if(!isEmptyString(newMigrationData?.destination_stack?.selectedStack?.value )
105105
){
106106
handleAllStepsComplete(true);
107107
}

ui/src/components/LegacyCms/Actions/LoadUploadFile.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ interface UploadState {
2626
fileFormat?: string;
2727
isConfigLoading: boolean;
2828
isLoading: boolean;
29-
isValidated: boolean;
29+
isValidated?: boolean;
3030
isDisabled?: boolean;
3131
processing: string;
3232
progressPercentage: number;
@@ -190,7 +190,7 @@ const LoadUploadFile = (props: LoadUploadFileProps) => {
190190
{
191191
isLoading,
192192
isConfigLoading,
193-
isValidated,
193+
//isValidated,
194194
validationMessgae,
195195
isDisabled,
196196
cmsType,
@@ -290,7 +290,7 @@ const LoadUploadFile = (props: LoadUploadFileProps) => {
290290
if (savedState) {
291291
setIsLoading(savedState.isLoading);
292292
setIsConfigLoading(savedState.isConfigLoading);
293-
setIsValidated(savedState?.isValidated);
293+
//setIsValidated(savedState?.isValidated);
294294
setValidationMessage(savedState?.validationMessage);
295295
//setIsDisabled(savedState?.isDisabled);
296296
setCmsType(savedState.cmsType);
@@ -315,7 +315,7 @@ const LoadUploadFile = (props: LoadUploadFileProps) => {
315315
{
316316
isLoading,
317317
isConfigLoading,
318-
isValidated,
318+
//isValidated,
319319
validationMessgae,
320320
//isDisabled,
321321
cmsType,
@@ -331,7 +331,7 @@ const LoadUploadFile = (props: LoadUploadFileProps) => {
331331
}, [
332332
isLoading,
333333
isConfigLoading,
334-
isValidated,
334+
//isValidated,
335335
validationMessgae,
336336
//isDisabled,
337337
cmsType,

ui/src/hooks/useWarnOnrefresh.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { useEffect } from "react";
2+
3+
export function useWarnOnRefresh(isUnsaved : boolean){
4+
useEffect(() => {
5+
const handleBeforeUnload = (e: BeforeUnloadEvent) => {
6+
if (isUnsaved) {
7+
e.preventDefault();
8+
e.returnValue = '';
9+
}
10+
};
11+
12+
window.addEventListener('beforeunload', handleBeforeUnload);
13+
14+
return () => {
15+
window.removeEventListener('beforeunload', handleBeforeUnload);
16+
};
17+
}, [isUnsaved]);
18+
}

ui/src/pages/Migration/index.tsx

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { cbModal, Notification } from '@contentstack/venus-components';
77
// Redux files
88
import { RootState } from '../../store';
99
import { updateMigrationData, updateNewMigrationData } from '../../store/slice/migrationDataSlice';
10+
import { useWarnOnRefresh } from '../../hooks/useWarnOnrefresh';
1011

1112
// Services
1213
import {
@@ -100,10 +101,38 @@ const Migration = () => {
100101
const saveRef = useRef<ContentTypeSaveHandles>(null);
101102
const newMigrationDataRef = useRef(newMigrationData);
102103

104+
const [isSaved, setIsSaved] = useState<boolean>(false);
105+
103106
useEffect(() => {
104107
fetchData();
105108
}, [params?.stepId, params?.projectId, selectedOrganisation?.value]);
106109

110+
useWarnOnRefresh(isSaved);
111+
112+
useEffect(()=>{
113+
const hasNonEmptyMapping =
114+
newMigrationData?.destination_stack?.localeMapping &&
115+
Object.entries(newMigrationData?.destination_stack?.localeMapping || {})?.every(
116+
([label, value]: [string, string]) =>
117+
Boolean(label?.trim()) &&
118+
value !== '' &&
119+
value !== null &&
120+
value !== undefined
121+
);
122+
if(legacyCMSRef?.current && !isCompleted && newMigrationData?.project_current_step === 1){
123+
setIsSaved(true);
124+
}
125+
else if ((isCompleted && !isEmptyString(newMigrationData?.destination_stack?.selectedStack?.value) && newMigrationData?.project_current_step === 2)){
126+
setIsSaved(true);
127+
}
128+
else if(newMigrationData?.content_mapping?.isDropDownChanged){
129+
setIsSaved(true);
130+
}
131+
else{
132+
setIsSaved(false);
133+
}
134+
},[isCompleted, newMigrationData])
135+
107136
/**
108137
* Dispatches the isprojectMapped key to redux
109138
*/
@@ -220,7 +249,7 @@ const Migration = () => {
220249
const newMigrationDataObj = {
221250
name: data?.localPath,
222251
url: data?.localPath,
223-
isValidated: data?.localPath !== newMigrationData?.legacy_cms?.uploadedFile?.file_details?.localPath ? false : newMigrationData?.legacy_cms?.uploadedFile?.isValidated,
252+
isValidated: false,
224253
file_details: {
225254
isLocalPath: data?.isLocalPath,
226255
cmsType: data?.cmsType,

0 commit comments

Comments
 (0)