Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UILD-462: Remove autosave feature #62

Merged
merged 2 commits into from
Dec 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions src/common/constants/storage.constants.ts

This file was deleted.

8 changes: 0 additions & 8 deletions src/common/helpers/progressBackup.helper.ts

This file was deleted.

74 changes: 0 additions & 74 deletions src/common/helpers/record.helper.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import { AUTOCLEAR_TIMEOUT } from '@common/constants/storage.constants';
import { localStorageService } from '@common/services/storage';
import { generateRecordBackupKey } from './progressBackup.helper';
import {
GROUP_BY_LEVEL,
GROUP_CONTENTS_LEVEL,
Expand All @@ -9,7 +6,6 @@ import {
TITLE_CONTAINER_URIS,
TYPE_URIS,
} from '@common/constants/bibframe.constants';
import { formatRecord } from './recordFormatting.helper';
import {
BFLITE_URI_TO_BLOCK,
BFLITE_URIS,
Expand All @@ -35,76 +31,6 @@ export const getRecordId = (record: RecordEntry | null, selectedBlock?: string,
return previewBlock ? (record?.resource?.[block]?.[previewBlock] as any[])?.[0]?.id : record?.resource?.[block]?.id;
};

export const getRecordWithUpdatedID = (record: RecordEntry, id: RecordID) => ({
resource: {
...record.resource,
[TYPE_URIS.INSTANCE]: { ...record.resource[TYPE_URIS.INSTANCE], id },
},
});

export const deleteRecordLocally = (profile: string, recordId?: RecordID) => {
const storageKey = generateRecordBackupKey(profile, recordId);

localStorageService.delete(storageKey);
};

export const generateRecordData = (record: ParsedRecord) => {
return {
createdAt: new Date().getTime(),
data: record,
};
};

export const generateAndSaveRecord = (storageKey: string, record: ParsedRecord) => {
const newRecord = generateRecordData(record);

localStorageService.serialize(storageKey, newRecord);

return newRecord;
};

export const saveRecordLocally = ({
profile,
parsedRecord,
record,
selectedRecordBlocks,
}: {
profile: string;
parsedRecord: ParsedRecord;
record: RecordEntry | null;
selectedRecordBlocks?: SelectedRecordBlocks;
}) => {
if (!record) return;

const recordId = getRecordId(record) as string;
const storageKey = generateRecordBackupKey(profile, recordId);
const formattedRecord = formatRecord({ parsedRecord, record, selectedRecordBlocks });
const updatedRecord = getRecordWithUpdatedID(formattedRecord as RecordEntry, recordId);

return generateAndSaveRecord(storageKey, updatedRecord as ParsedRecord);
};

export const getSavedRecord = (profile: string, recordId?: RecordID): LocallySavedRecord | null => {
const storageKey = generateRecordBackupKey(profile, recordId);
const savedRecordData = localStorageService.deserialize(storageKey);

if (savedRecordData && !savedRecordData?.data) {
return generateAndSaveRecord(storageKey, savedRecordData);
}

return savedRecordData ? autoClearSavedData(savedRecordData, profile, recordId) : null;
};

export const autoClearSavedData = (savedRecordData: LocallySavedRecord, profile: string, recordId?: RecordID) => {
const shouldBeCleared = savedRecordData.createdAt + AUTOCLEAR_TIMEOUT <= new Date().getTime();

if (!shouldBeCleared) return savedRecordData;

deleteRecordLocally(profile, recordId);

return null;
};

export const checkIdentifierAsValue = (record: Record<string, string[]>, uri: string) => {
const identifierAsValueSelection = IDENTIFIER_AS_VALUE[uri];

Expand Down
57 changes: 23 additions & 34 deletions src/common/hooks/useRecordControls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,9 @@ import {
getGraphIdByExternalId,
getRecord,
} from '@common/api/records.api';
import { BibframeEntities, PROFILE_BFIDS } from '@common/constants/bibframe.constants';
import { BibframeEntities } from '@common/constants/bibframe.constants';
import { StatusType } from '@common/constants/status.constants';
import { DEFAULT_RECORD_ID } from '@common/constants/storage.constants';
import {
deleteRecordLocally,
getPrimaryEntitiesFromRecord,
getRecordId,
getSelectedRecordBlocks,
saveRecordLocally,
getSavedRecord,
} from '@common/helpers/record.helper';
import { getPrimaryEntitiesFromRecord, getRecordId, getSelectedRecordBlocks } from '@common/helpers/record.helper';
import { UserNotificationFactory } from '@common/services/userNotification';
import { PreviewParams, useConfig } from '@common/hooks/useConfig.hook';
import { formatRecord } from '@common/helpers/recordFormatting.helper';
Expand Down Expand Up @@ -53,8 +45,12 @@ export const useRecordControls = () => {
const { setSelectedProfile } = useProfileState();
const { setIsDuplicateImportedResourceModalOpen, setCurrentlyEditedEntityBfid, setCurrentlyPreviewedEntityBfid } =
useUIState();
const { setRecordStatus, setLastSavedRecordId, setIsRecordEdited: setIsEdited, addStatusMessagesItem } = useStatusState();
const profile = PROFILE_BFIDS.MONOGRAPH;
const {
setRecordStatus,
setLastSavedRecordId,
setIsRecordEdited: setIsEdited,
addStatusMessagesItem,
} = useStatusState();
const currentRecordId = getRecordId(record);
const { getProfiles } = useConfig();
const navigate = useNavigate();
Expand All @@ -66,12 +62,7 @@ export const useRecordControls = () => {
const { generateRecord } = useRecordGeneration();

const fetchRecord = async (recordId: string, previewParams?: PreviewParams) => {
const profile = PROFILE_BFIDS.MONOGRAPH;
const locallySavedData = getSavedRecord(profile, recordId);
const cachedRecord: RecordEntry | undefined =
locallySavedData && !previewParams ? (locallySavedData.data as RecordEntry) : undefined;

const recordData = await getRecordAndInitializeParsing({ recordId, cachedRecord });
const recordData = await getRecordAndInitializeParsing({ recordId });

if (!recordData) return;

Expand All @@ -98,7 +89,6 @@ export const useRecordControls = () => {
shouldSetSearchParams = true,
}: SaveRecordProps = {}) => {
const parsed = generateRecord();
const currentRecordId = record?.id;

if (!parsed) return;

Expand All @@ -113,14 +103,13 @@ export const useRecordControls = () => {
}) as RecordEntry;

const recordId = getRecordId(record, selectedRecordBlocks?.block);
const shouldPostRecord = !recordId || getRecordId(record) === DEFAULT_RECORD_ID || isClone;
const shouldPostRecord = !recordId || isClone;

const response = shouldPostRecord
? await postRecord(formattedRecord)
: await putRecord(recordId as string, formattedRecord);
const parsedResponse = await response.json();

deleteRecordLocally(profile, currentRecordId as RecordID);
dispatchUnblockEvent();
!asRefToNewRecord && setRecord(parsedResponse);

Expand Down Expand Up @@ -177,14 +166,6 @@ export const useRecordControls = () => {
}
};

const saveLocalRecord = () => {
const parsed = generateRecord();

if (!parsed) return;

return saveRecordLocally({ profile, parsedRecord: parsed, record, selectedRecordBlocks });
};

const clearRecordState = () => {
resetUserValues();
setRecord(null);
Expand All @@ -205,7 +186,6 @@ export const useRecordControls = () => {
if (!currentRecordId) return;

await deleteRecordRequest(currentRecordId as unknown as string);
deleteRecordLocally(profile, currentRecordId as unknown as string);
discardRecord();
addStatusMessagesItem?.(UserNotificationFactory.createMessage(StatusType.success, 'ld.rdDeleted'));

Expand All @@ -224,7 +204,9 @@ export const useRecordControls = () => {
const contents = record?.resource?.[uriSelector];

if (!contents) {
addStatusMessagesItem?.(UserNotificationFactory.createMessage(StatusType.error, 'ld.cantSelectReferenceContents'));
addStatusMessagesItem?.(
UserNotificationFactory.createMessage(StatusType.error, 'ld.cantSelectReferenceContents'),
);

return navigate(ROUTES.RESOURCE_CREATE.uri);
}
Expand All @@ -248,7 +230,13 @@ export const useRecordControls = () => {
}
};

const getRecordAndInitializeParsing = async ({ recordId, cachedRecord, idType, previewParams, errorMessage }: IBaseFetchRecord) => {
const getRecordAndInitializeParsing = async ({
recordId,
cachedRecord,
idType,
previewParams,
errorMessage,
}: IBaseFetchRecord) => {
if (!recordId && !cachedRecord) return;

try {
Expand All @@ -262,7 +250,9 @@ export const useRecordControls = () => {

return recordData;
} catch (_err) {
addStatusMessagesItem?.(UserNotificationFactory.createMessage(StatusType.error, errorMessage ?? 'ld.errorFetching'));
addStatusMessagesItem?.(
UserNotificationFactory.createMessage(StatusType.error, errorMessage ?? 'ld.errorFetching'),
);
}
};

Expand Down Expand Up @@ -301,7 +291,6 @@ export const useRecordControls = () => {
return {
fetchRecord,
saveRecord,
saveLocalRecord,
deleteRecord,
discardRecord,
clearRecordState,
Expand Down
4 changes: 1 addition & 3 deletions src/components/DeleteRecord/DeleteRecord.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { FC, memo } from 'react';
import { FormattedMessage } from 'react-intl';
import { DEFAULT_RECORD_ID } from '@common/constants/storage.constants';
import { useRecordControls } from '@common/hooks/useRecordControls';
import { ModalDeleteRecord } from '@components/ModalDeleteRecord';
import { useModalControls } from '@common/hooks/useModalControls';
import { getRecordId } from '@common/helpers/record.helper';
import { useRoutePathPattern } from '@common/hooks/useRoutePathPattern';
import { RESOURCE_URLS } from '@common/constants/routes.constants';
import { checkButtonDisabledState } from '@common/helpers/recordControls.helper';
Expand All @@ -21,7 +19,7 @@ const DeleteRecord: FC = () => {
const { hasBeenSaved } = useRecordStatus();
const isDisabledForEditPage =
checkButtonDisabledState({ resourceRoutePattern, isInitiallyLoaded: !hasBeenSaved, isEdited }) || false;
const isDisabled = !record || getRecordId(record) === DEFAULT_RECORD_ID || isDisabledForEditPage;
const isDisabled = !record || isDisabledForEditPage;

return (
<>
Expand Down
29 changes: 2 additions & 27 deletions src/components/EditSection/EditSection.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import { useEffect, memo, useRef } from 'react';
import { memo, useRef } from 'react';
import { debounce } from 'lodash';
import classNames from 'classnames';
import { saveRecordLocally } from '@common/helpers/record.helper';
import { PROFILE_BFIDS } from '@common/constants/bibframe.constants';
import { AUTOSAVE_INTERVAL } from '@common/constants/storage.constants';
import { EDIT_SECTION_CONTAINER_ID } from '@common/constants/uiElements.constants';
import { Fields } from '@components/Fields';
import { Prompt } from '@components/Prompt';
import { useContainerEvents } from '@common/hooks/useContainerEvents';
import { useServicesContext } from '@common/hooks/useServicesContext';
import { useRecordGeneration } from '@common/hooks/useRecordGeneration';
import { useInputsState, useProfileState, useStatusState, useUIState } from '@src/store';
import { renderDrawComponent } from './renderDrawComponent';
import './EditSection.scss';
Expand All @@ -20,34 +17,12 @@ export const EditSection = memo(() => {
const { selectedEntriesService } = useServicesContext() as Required<ServicesParams>;
const { selectedProfile, initialSchemaKey } = useProfileState();
const resourceTemplates = selectedProfile?.json.Profile.resourceTemplates;
const { userValues, addUserValuesItem, selectedRecordBlocks, record, selectedEntries, setSelectedEntries } =
useInputsState();
const { userValues, addUserValuesItem, selectedEntries, setSelectedEntries } = useInputsState();
const { isRecordEdited: isEdited, setIsRecordEdited: setIsEdited } = useStatusState();
const { collapsedEntries, setCollapsedEntries, collapsibleEntries, currentlyEditedEntityBfid } = useUIState();
const { generateRecord } = useRecordGeneration();

useContainerEvents({ watchEditedState: true });

useEffect(() => {
if (!isEdited) return;

const autoSaveRecord = setInterval(() => {
try {
const parsed = generateRecord();

if (!parsed) return;

const profile = PROFILE_BFIDS.MONOGRAPH;

saveRecordLocally({ profile, parsedRecord: parsed, record, selectedRecordBlocks });
} catch (error) {
console.error('Unable to automatically save changes:', error);
}
}, AUTOSAVE_INTERVAL);

return () => clearInterval(autoSaveRecord);
}, [isEdited, userValues]);

const debouncedAddUserValues = useRef(
debounce((value: UserValues) => {
addUserValuesItem?.(value);
Expand Down
2 changes: 0 additions & 2 deletions src/test/__mocks__/common/hooks/useRecordControls.mock.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export const saveRecord = jest.fn();
export const saveRecordLocally = jest.fn();
export const discardRecord = jest.fn();
export const fetchRecord = jest.fn();
export const clearRecordState = jest.fn();
Expand All @@ -13,7 +12,6 @@ jest.mock('@common/hooks/useRecordControls', () => ({
discardRecord,
fetchRecord,
clearRecordState,
saveRecordLocally,
fetchRecordAndSelectEntityValues,
fetchExternalRecordForPreview,
getRecordAndInitializeParsing,
Expand Down
31 changes: 0 additions & 31 deletions src/test/__tests__/common/helpers/progressBackup.helper.test.ts

This file was deleted.

Loading
Loading