rhythmEventsRecoilDataEffect.js
Thu Nov 28 2024 02:30:32 GMT+0000 (Coordinated Universal Time)
Saved by @khainguyenhm
/* eslint-disable no-promise-executor-return */
import dayjs from 'dayjs';
import _ from 'lodash';
import {
useEffect, useRef, useState,
} from 'react';
import {
useRecoilValue, useSetRecoilState,
} from 'recoil';
import { t } from 'ttag';
import {
beatEventCountState,
rhythmEventCountState,
specialEventTypesState, updatedAfibAvgHrState, updatedDailyAfibHrSummariesState,
} from '.';
import { clearApolloCache } from '../../../../../Apollo/apolloClient';
import fetchHolterBeatEventsCount from '../../../../../Apollo/Functions/fetchHolterBeatEventsCount';
import fetchHolterEventIndex from '../../../../../Apollo/Functions/fetchHolterEventIndex';
import fetchHolterEvents from '../../../../../Apollo/Functions/fetchHolterEvents';
import fetchHolterEventsDailyCount from '../../../../../Apollo/Functions/fetchHolterEventsDailyCount';
import fetchHolterRhythmEventsCount from '../../../../../Apollo/Functions/fetchHolterRhythmEventsCount';
import handleCheckSavingAiProcess from '../../../../../Apollo/Functions/handleCheckSavingAiProcess';
import { EMITTER_CONSTANTS } from '../../../../../ConstantsV2';
import {
AI_COMMAND,
canShowCountBeatEvents, canShowDurationEvents,
ECG_EVENT_MENU_OPTIONS, EVENT_COUNT_CONVERT, ID_BOOKMARK_TAB, KEY_CANCEL, KEY_RECOIL, STRIP_EVENT_THUMBNAIL_INFO, TYPE_RHYTHM_EVENT_ENUM,
typesPersistEventV2,
} from '../../../../../ConstantsV2/aiConstants';
import { convertToDayJS } from '../../../../../UtilsV2/aiUtils';
import { useEmitter, useGetRecoilValue } from '../../../../../UtilsV2/customHooks';
import emitter from '../../../../../UtilsV2/eventEmitter';
import { toastrError } from '../../../../../UtilsV2/toastNotification';
import {
activeTabState,
beatChangesState,
dailyCountState,
ecgDataMapState,
eventChangesState,
eventFilterState,
eventNewsState,
eventOptionsState,
eventOthersState,
groupEventChangesState,
isActiveTabState,
isNotReadyAfterSaveState,
isRenderViewerEcgState,
originalDailySummariesState,
pageIndexState,
profileAfibAvgHrState,
reloadEcgViewerState,
reloadHrChartState,
reportInfoState,
selectedDateValueState,
selectedStripState,
} from '../../Recoil';
import { logError } from '../../handler';
import {
generateFilterSpecialEventType,
isAppliedFilterEvent,
} from '../handler';
import { clearCachesBeatHourly } from '../../../../../Store/caches';
import { removeSavingData } from '../../BeatHR/helper';
import { beatOptionsState } from '../../BeatHR/recoil';
const RhythmEventsRecoilDataEffect = (props) => {
const keyRecoil = KEY_RECOIL.TAB_2;
const activeButton = useRecoilValue(activeTabState(keyRecoil));
const getActiveButton = useGetRecoilValue(activeTabState(keyRecoil));
const getSelectedStrip = useGetRecoilValue(selectedStripState(keyRecoil));
const getPageIndex = useGetRecoilValue(pageIndexState(keyRecoil));
const setPageIndex = useSetRecoilState(pageIndexState(keyRecoil));
const getSelectedDateValue = useGetRecoilValue(selectedDateValueState(keyRecoil));
const getSpecialEventTypes = useGetRecoilValue(specialEventTypesState);
const getEventFilter = useGetRecoilValue(eventFilterState(keyRecoil));
const setDailyCount = useSetRecoilState(dailyCountState(keyRecoil));
const setUpdatedAfibAvgHr = useSetRecoilState(updatedAfibAvgHrState);
const setUpdatedDailyAfibHrSummaries = useSetRecoilState(updatedDailyAfibHrSummariesState);
const setEventChanges = useSetRecoilState(eventChangesState(keyRecoil));
const setBeatChanges = useSetRecoilState(beatChangesState(keyRecoil));
const setReloadEcgViewer = useSetRecoilState(reloadEcgViewerState(keyRecoil));
const setReloadHrChart = useSetRecoilState(reloadHrChartState(keyRecoil));
const setGroupEventChanges = useSetRecoilState(groupEventChangesState(keyRecoil));
const isActiveTab = useRecoilValue(isActiveTabState(keyRecoil));
const setIsNotReadyAfterSaveTab1 = useSetRecoilState(isNotReadyAfterSaveState(KEY_RECOIL.TAB_1));
const setIsNotReadyAfterSaveTab2 = useSetRecoilState(isNotReadyAfterSaveState(KEY_RECOIL.TAB_2));
const setIsNotReadyAfterSaveTab3 = useSetRecoilState(isNotReadyAfterSaveState(KEY_RECOIL.TAB_3));
const getHolterRhythmEventsCount = useGetRecoilValue(rhythmEventCountState);
const getHolterBeatEventsCount = useGetRecoilValue(beatEventCountState);
const { studyId, profileId, timezoneOffset } = useRecoilValue(reportInfoState);
const setEcgDataMap = useSetRecoilState(ecgDataMapState);
const getEcgDataMap = useGetRecoilValue(ecgDataMapState);
const setOriginalDailySummaries = useSetRecoilState(originalDailySummariesState);
const setProfileAfibAvgHr = useSetRecoilState(profileAfibAvgHrState);
const setEventOthers = useSetRecoilState(eventOthersState(keyRecoil));
const setEventNews = useSetRecoilState(eventNewsState(keyRecoil));
const setEventOptions = useSetRecoilState(eventOptionsState(keyRecoil));
const setIsRenderViewerEcg = useSetRecoilState(isRenderViewerEcgState);
const setHolterRhythmEventsCount = useSetRecoilState(rhythmEventCountState);
const setHolterBeatEventsCount = useSetRecoilState(beatEventCountState);
const setSelectedStrip = useSetRecoilState(selectedStripState(keyRecoil));
const [doneReset, setDoneReset] = useState(false);
const setBeatOptions = useSetRecoilState(beatOptionsState(keyRecoil));
const commandPendingQueue = useRef([]);
const updateDataMessageQueue = useRef([]);
const promiseUpdateData = useRef([]);
const promiseUpdateDataType = useRef([]);
const isExcutedRef = useRef(false);
const handleFetchStripEvents = async ({ page, additionalFilter = {} }) => {
try {
const type = getActiveButton();
const validatePage = page <= 0 ? 0 : page;
const filterHolterEvents = {
studyId,
profileId,
types: [type],
skip: validatePage * STRIP_EVENT_THUMBNAIL_INFO.stripDisplayLimit,
...additionalFilter,
};
const promises = [fetchHolterEvents(
filterHolterEvents,
STRIP_EVENT_THUMBNAIL_INFO.stripDisplayLimit,
true,
KEY_CANCEL.API_HOLTER_AI,
)];
if (!_.isEmpty(additionalFilter)) {
const holterEventsCountFilter = {
studyId,
profileId,
types: [type],
...additionalFilter,
};
promises.push(
_.find(ECG_EVENT_MENU_OPTIONS, (x) => x.value === type).type === 'beat'
? fetchHolterBeatEventsCount(holterEventsCountFilter, true, KEY_CANCEL.API_HOLTER_AI)
: fetchHolterRhythmEventsCount(holterEventsCountFilter, true, KEY_CANCEL.API_HOLTER_AI),
);
}
const [{ events }, eventsCount] = await Promise.all(promises);
if (!_.isEmpty(additionalFilter)) {
return { events, eventsCount };
}
return { events, eventsCount: _.find(ECG_EVENT_MENU_OPTIONS, (x) => x.value === type).type === 'beat' ? getHolterBeatEventsCount() : getHolterRhythmEventsCount() };
} catch (error) {
return { events: undefined, eventsCount: 0 };
}
};
const handleReloadEventHrChartV2 = async () => {
try {
const type = activeButton;
const selectedDateValue = getSelectedDateValue();
const startSearchDate = selectedDateValue;
const stopSearchDate = selectedDateValue ? dayjs(selectedDateValue).add(1, 'days').toISOString() : null;
const promiseArr = [
selectedDateValue ? fetchHolterEvents({
studyId,
profileId,
types: typesPersistEventV2,
startSearchDate,
stopSearchDate,
}, 0, true, KEY_CANCEL.API_HOLTER_AI) : undefined,
];
await Promise.allSettled(promiseArr);
if (!_.includes(promiseUpdateDataType.current, 'setReloadHrChart')) {
promiseUpdateDataType.current.push('setReloadHrChart');
promiseUpdateData.current.push(() => setReloadHrChart((prev) => prev + _.round(Math.random() * 100)));
}
} catch (error) {
logError('Failed to fetch reload data: ', error);
toastrError(error.message, t`Error`);
}
};
const handleReloadEventDataV2 = async (needUpdateAfibArtifact) => {
try {
if (isActiveTab) {
setIsRenderViewerEcg(false);
}
const type = activeButton;
const selectedDateValue = getSelectedDateValue();
const startSearchDate = selectedDateValue;
const stopSearchDate = selectedDateValue ? dayjs(selectedDateValue).add(1, 'days').toISOString() : null;
const additionalFilter = generateFilterSpecialEventType(type, getSpecialEventTypes());
const eventFilter = getEventFilter();
if (isAppliedFilterEvent(eventFilter, type)) {
_.assign(additionalFilter, {
...(eventFilter.isHideReviewed && { isReviewed: false }),
...(eventFilter.isCapture && { isCaptured: true }),
...(eventFilter.sortOrder && (canShowCountBeatEvents.includes(type) || canShowDurationEvents.includes(type)) && {
sortBy: eventFilter.sortBy || 'countBeats',
sortOrder: eventFilter.sortOrder,
}),
});
}
const promiseArr = [
selectedDateValue ? fetchHolterEvents({
studyId,
profileId,
types: typesPersistEventV2,
startSearchDate,
stopSearchDate,
}, 0, true, KEY_CANCEL.API_HOLTER_AI) : undefined,
fetchHolterEventsDailyCount({
studyId,
profileId,
types: [type],
...additionalFilter,
}, null, false),
];
const selectedStrip = getSelectedStrip();
if (selectedStrip?.idEvent) {
const filterHolterEventIndex = {
studyId,
profileId,
types: [type],
includedEventId: selectedStrip.idEvent,
...additionalFilter,
};
promiseArr.push(fetchHolterEventIndex(filterHolterEventIndex, false, KEY_CANCEL.API_HOLTER_AI));
} else {
promiseArr.push(new Promise((resolve) => resolve(undefined)));
}
const [resultHolterEventsPersistAllDay, resultDailyCount, resultEventIndex] = await Promise.allSettled(promiseArr);
const dailyCount = resultDailyCount?.status === 'rejected' ? undefined : resultDailyCount.value;
if (resultEventIndex?.status === 'fulfilled') {
const eventIndex = resultEventIndex.value;
if (!_.isNil(eventIndex) && eventIndex >= 0) {
const page = Math.floor(eventIndex / STRIP_EVENT_THUMBNAIL_INFO.stripDisplayLimit);
await handleFetchStripEvents({ page, additionalFilter });
promiseUpdateData.current.push(() => setPageIndex({ index: page < 0 ? 0 : page }));
} else {
const pageIndex = getPageIndex();
const { events, eventsCount } = await handleFetchStripEvents({ page: pageIndex.index, additionalFilter });
if (_.isEmpty(events)) {
const totalEvent = eventsCount[EVENT_COUNT_CONVERT[getActiveButton()]]?.count || 0;
const pageTemp = Math.floor(totalEvent / STRIP_EVENT_THUMBNAIL_INFO.stripDisplayLimit);
const page = (totalEvent % STRIP_EVENT_THUMBNAIL_INFO.stripDisplayLimit) === 0 ? pageTemp - 1 : pageTemp;
promiseUpdateData.current.push(() => setPageIndex({ index: page < 0 ? 0 : page }));
} else {
promiseUpdateData.current.push(() => setPageIndex({ index: getPageIndex().index }));
}
}
}
if (needUpdateAfibArtifact) {
handleReloadEventHrChartV2();
}
if (!_.isEmpty(dailyCount)) {
promiseUpdateData.current.push(() => setDailyCount(dailyCount));
}
if (!_.includes(promiseUpdateDataType.current, 'setReloadHrChart')) {
promiseUpdateDataType.current.push('setReloadHrChart');
promiseUpdateData.current.push(() => setReloadHrChart((prev) => prev + _.round(Math.random() * 100)));
}
} catch (error) {
logError('Failed to fetch reload data: ', error);
toastrError(error.message, t`Error`);
}
};
const handleReloadEvent = async (msg) => {
try {
if (isActiveTab) {
setIsRenderViewerEcg(false);
}
const {
newEvents, deletedEvents, updatedEvents, deletedEventTypes,
} = msg;
const selectedDateValue = getSelectedDateValue();
const selectedDateString = selectedDateValue ? convertToDayJS(selectedDateValue, timezoneOffset).format('DD-MM-YYYY') : null;
const types = [TYPE_RHYTHM_EVENT_ENUM.AFIB, TYPE_RHYTHM_EVENT_ENUM.ARTIFACT];
let needUpdate;
let needUpdateAfibArtifact; //* Trường hợp sửa artifact hoặc afib xong qua tab event khác save thì hr chart ko update
if (deletedEventTypes?.length) {
deletedEventTypes.forEach((type) => {
if (type === activeButton || type === TYPE_RHYTHM_EVENT_ENUM.TACHY) {
needUpdate = true;
} else if (types.includes(type)) {
needUpdateAfibArtifact = true;
}
});
}
if (deletedEvents?.length) {
deletedEvents.forEach((deletedEvent) => {
if (deletedEvent.type === activeButton || (deletedEvent.type === TYPE_RHYTHM_EVENT_ENUM.TACHY)) {
needUpdate = true;
} else {
const isSameDate = selectedDateString === convertToDayJS(deletedEvent.start, timezoneOffset).format('DD-MM-YYYY');
if (types.includes(deletedEvent.type) && isSameDate) {
needUpdateAfibArtifact = true;
}
}
});
}
if (newEvents?.length) {
newEvents.forEach((newEvent) => {
if (newEvent.type === activeButton) {
needUpdate = true;
} else {
const isSameDate = selectedDateString === convertToDayJS(newEvent.start, timezoneOffset).format('DD-MM-YYYY');
if (types.includes(newEvent.type) && isSameDate) {
needUpdateAfibArtifact = true;
}
}
});
}
if (updatedEvents?.length) {
updatedEvents.forEach((updatedEvent) => {
if (updatedEvent.type === activeButton) {
needUpdate = true;
} else {
const isSameDate = selectedDateString === convertToDayJS(updatedEvent.start, timezoneOffset).format('DD-MM-YYYY');
if (types.includes(updatedEvent.type) && isSameDate) {
needUpdateAfibArtifact = true;
}
}
});
}
if (needUpdate) {
await handleReloadEventDataV2(needUpdateAfibArtifact);
} else if (needUpdateAfibArtifact || activeButton === TYPE_RHYTHM_EVENT_ENUM.AFIB) {
await handleReloadEventHrChartV2();
} else if (activeButton === ID_BOOKMARK_TAB) {
if (!_.includes(promiseUpdateDataType.current, 'setReloadHrChart')) {
promiseUpdateDataType.current.push('setReloadHrChart');
promiseUpdateData.current.push(() => setReloadHrChart((prev) => prev + _.round(Math.random() * 100)));
}
}
console.log('[rhythmEventsRecoilDataEffect]-RELOAD-EVENT-RHYTHMEVENT', needUpdate, activeButton, needUpdateAfibArtifact);
if (!_.includes(promiseUpdateDataType.current, 'setReloadEcgViewer')) {
promiseUpdateDataType.current.push('setReloadEcgViewer');
promiseUpdateData.current.push(() => setReloadEcgViewer((prev) => prev + _.round(Math.random() * 100)));
}
promiseUpdateData.current.push(() => {
setGroupEventChanges((prev) => {
if (prev.length === 0) {
return prev;
}
return [];
});
let eventChanges = [];
let eventNews = [];
let eventOthers = [];
setEventChanges((prev) => {
let count = 0;
const filterResult = prev.filter((x) => {
if (x.isSaving) {
count += 1;
return false;
}
return true;
});
if (count === 0) {
return prev;
}
eventChanges.push(...filterResult);
return filterResult;
});
setEventOthers((prev) => {
let count = 0;
const filterResult = prev.filter((x) => {
if (x.isSaving) {
count += 1;
return false;
}
return true;
});
if (count === 0) {
return prev;
}
eventOthers.push(...filterResult);
return filterResult;
});
setEventNews((prev) => {
let count = 0;
const filterResult = prev.filter((x) => {
if (x.isSaving) {
count += 1;
return false;
}
return true;
});
if (count === 0) {
return prev;
}
eventNews.push(...filterResult);
return filterResult;
});
// Perform grouping action applicable to undo/redo
setEventOptions({
eventNewsState: eventNews,
eventChangesState: eventChanges,
eventOthersState: eventOthers,
});
eventChanges = [];
eventNews = [];
eventOthers = [];
const selectedStrip = getSelectedStrip();
if (selectedStrip?.isNew) {
setSelectedStrip(null);
}
});
} catch (error) {
logError('Error: ', error);
}
return true;
};
const handleUpdateBeats = (msg) => {
const prevEcgDataMap = getEcgDataMap();
const cloneEcgDataMap = { ...prevEcgDataMap };
if ((msg.summaries?.length || msg.beatsUpdated?.summaries?.length) && !_.isEmpty(prevEcgDataMap?.data)) {
_.forEach(msg.summaries || msg.beatsUpdated?.summaries, (summary) => {
const foundData = _.find(cloneEcgDataMap.data, (x) => x.id === summary.id);
if (foundData) {
_.assign(foundData, {
avgHrs: summary?.avgHrs,
maxHrs: summary?.maxHrs,
minHrs: summary?.minHrs,
beatFinalPath: summary?.beatFinalPath,
latestBeatPrefix: summary?.latestBeatPrefix,
});
}
});
const summaryIds = _.map(msg.summaries || msg.beatsUpdated?.summaries, 'id');
const socketUpdateEcgDataMap = {
...cloneEcgDataMap,
data: _.filter(cloneEcgDataMap.data, (item) => summaryIds.includes(item.id)),
};
if (isActiveTab) {
emitter.emit(EMITTER_CONSTANTS.UPDATE_SOCKET_BEAT_DATA_MAP, socketUpdateEcgDataMap);
}
}
return cloneEcgDataMap;
};
const handleReloadBeat = async (msg) => {
try {
const cloneEcgDataMap = handleUpdateBeats(msg);
promiseUpdateData.current.push(() => {
let beatsChanges = [];
setBeatChanges((prev) => {
if (_.isEmpty(prev)) return prev;
const beats = removeSavingData(prev);
beatsChanges = beats;
return beats;
});
setBeatOptions((prev) => ({ ...prev, beatChangesState: beatsChanges }));
setEcgDataMap((prev) => {
if (_.isEqual(prev, cloneEcgDataMap)) {
return prev;
}
return cloneEcgDataMap;
});
setReloadEcgViewer((prev) => prev + _.round(Math.random() * 100));
});
} catch (error) {
logError('Failed to reload beat', error);
}
return true;
};
const fetchEventsCount = async () => {
try {
const eventsCountFilter = {
studyId,
profileId,
};
const promises = [
fetchHolterBeatEventsCount(eventsCountFilter, false, null, false),
fetchHolterRhythmEventsCount(eventsCountFilter, false, null, false),
];
const [holterBeatEventsCount, holterRhythmEventsCount] = await Promise.all(promises);
setHolterBeatEventsCount(holterBeatEventsCount);
setHolterRhythmEventsCount(holterRhythmEventsCount);
} catch (error) {
logError('Failed to fetch holter rhythm events count: ', error);
}
};
const updateEventOutOfPending = _.debounce(async () => {
await clearApolloCache();
setIsRenderViewerEcg(false);
setTimeout(() => {
setIsRenderViewerEcg(true);
}, 500);
}, 2000);
const batchUpdateData = async () => {
try {
await clearApolloCache();
await clearCachesBeatHourly();
if (isActiveTab || props.activeTab !== '1') {
setIsRenderViewerEcg(false);
}
const promise = [];
updateDataMessageQueue.current.forEach((x) => {
if (x.type === AI_COMMAND.EVENT) {
promise.push(handleReloadEvent(x.msg));
promise.push(fetchEventsCount());
}
});
const beatPromises = [];
updateDataMessageQueue.current.forEach((x) => {
if (x.type === AI_COMMAND.BEAT) {
beatPromises.push(handleReloadBeat(x.msg));
}
});
await Promise.all(beatPromises); // Wait for all beat promises to resolve
console.log('[rhythmEventsRecoilDataEffect]-COMMANDEXECUTED-1', {
promise,
updateDataMessageQueue: updateDataMessageQueue.current,
promiseUpdateData: promiseUpdateData.current,
});
await Promise.all(promise);
promiseUpdateData.current.forEach((update) => update());
updateDataMessageQueue.current.length = 0;
} catch (error) {
logError('Error: ', error);
} finally {
console.log('[rhythmEventsRecoilDataEffect]-COMMANDEXECUTED-2', {
updateDataMessageQueue: updateDataMessageQueue.current,
promiseUpdateData: promiseUpdateData.current,
});
updateDataMessageQueue.current.length = 0;
promiseUpdateData.current.length = 0;
commandPendingQueue.current.length = 0;
promiseUpdateDataType.current.length = 0;
emitter.emit(EMITTER_CONSTANTS.RELOAD_EVENT_STRIP);
if (isActiveTab) {
setDoneReset(true);
}
}
};
useEffect(() => {
if (doneReset) {
setTimeout(() => {
emitter.emit(EMITTER_CONSTANTS.AI_LOADING, {
isLoading: false,
tab: 'rhythmEvents',
isExcuted: isExcutedRef.current,
});
setDoneReset(false);
if (isExcutedRef.current) {
isExcutedRef.current = false;
}
}, 2000);
}
}, [doneReset]);
useEmitter(EMITTER_CONSTANTS.EVENTSUPDATED_EVENT, (msg) => {
const foundMsg = updateDataMessageQueue.current.find((x) => x.type === AI_COMMAND.EVENT);
if (foundMsg) {
if (!_.isEmpty(msg)) {
Object.keys(msg).forEach((key) => {
if (foundMsg.msg[key]) {
foundMsg.msg[key] = foundMsg.msg[key].concat(msg[key]);
} else {
foundMsg.msg[key] = msg[key];
}
});
}
} else {
updateDataMessageQueue.current.push({
type: AI_COMMAND.EVENT,
msg: _.cloneDeep(msg),
});
}
if (commandPendingQueue.current.length === 0) { // update out of pending command
updateEventOutOfPending();
}
}, [studyId, profileId]);
useEmitter(EMITTER_CONSTANTS.BEATSUPDATED_EVENT, async (msg) => {
const foundMsg = updateDataMessageQueue.current.find((x) => x.type === AI_COMMAND.BEAT);
if (foundMsg) {
if (!_.isEmpty(msg)) {
_.assign(foundMsg, { msg });
}
} else {
updateDataMessageQueue.current.push({
type: AI_COMMAND.BEAT,
msg,
});
}
}, []);
useEmitter(EMITTER_CONSTANTS.DAILY_SUMMARY_UPDATED, (msg) => {
setOriginalDailySummaries((prev) => {
if (msg) {
const cloneDailySummaries = _.cloneDeep(prev);
_.forEach(msg, (dailySummary) => {
const foundDailySummary = _.find(cloneDailySummaries, (x) => x.date === dailySummary.date);
if (foundDailySummary) {
_.assign(foundDailySummary, dailySummary);
}
});
return cloneDailySummaries;
}
return prev;
});
}, []);
useEmitter(EMITTER_CONSTANTS.AFIB_HR_SUMMARY_UPDATED, (msg) => {
const { afibAvgHr } = msg;
setProfileAfibAvgHr(afibAvgHr);
setUpdatedAfibAvgHr(undefined);
setUpdatedDailyAfibHrSummaries([]);
}, []);
useEmitter(EMITTER_CONSTANTS.AI_PROCESS_SAVED, async (msg) => {
await batchUpdateData();
setIsNotReadyAfterSaveTab2(false);
}, [activeButton, studyId, profileId, isActiveTab, props.activeTab]);
useEmitter(EMITTER_CONSTANTS.COMMAND_PENDING, (msg) => {
//* Khi 1 user save, BE gửi command pending về tuỳ theo số lượng api gọi lúc save, push command vào mảng và khi
// có socket command execute thì remove => khi mảng về 0 thì get hết data nhận đc trong mảng updateDataMessage => update UI
if (msg.messageId !== profileId) return;
emitter.emit(EMITTER_CONSTANTS.AI_LOADING, { isLoading: true, tab: 'rhythmEvents' });
commandPendingQueue.current.push(msg.command);
}, [profileId]);
useEmitter(EMITTER_CONSTANTS.COMMAND_EXECUTED, async (msg) => {
// msg.command: update-events, update-beats, updateHolterHrDailySummary
// updateHolterProfile, generate-report-comments
if (msg.messageId !== profileId) return;
if (msg.command === 'updateHolterProfile' || msg.command === 'generate-report-comments') return;
console.log('[rhythmEventsRecoilDataEffect]-COMMANDEXECUTED-BEFORE', {
msg,
commandPendingQueue: commandPendingQueue.current,
updateDataMessageQueue: updateDataMessageQueue.current,
});
const foundIndexCommand = commandPendingQueue.current.findIndex((command) => command === msg.command);
if (foundIndexCommand !== -1) {
commandPendingQueue.current.splice(foundIndexCommand, 1);
}
//* Finish all command
if (commandPendingQueue.current.length === 0) {
isExcutedRef.current = true;
if (isActiveTab) {
if (updateDataMessageQueue.current.length !== 0) {
//* Announce this tab have data to update
emitter.emit(EMITTER_CONSTANTS.AI_UPDATE_TAB, '2');
const { beats, events, strips } = await handleCheckSavingAiProcess({
studyId,
profileId,
});
if (!beats) {
setIsNotReadyAfterSaveTab1(true);
}
if (!strips) {
setIsNotReadyAfterSaveTab3(true);
}
await batchUpdateData();
} else {
setDoneReset(true);
}
} else {
await batchUpdateData();
}
}
}, [activeButton, isActiveTab, studyId, profileId, props.activeTab]);
return null;
};
export default RhythmEventsRecoilDataEffect;
old
/Users/khainguyen/ITRVN_REPO/BTCY/btcy-bioflux-frontend-ai_report_processing/app/LayoutV2/Reports/AiEditReport/RhythmEvents/recoil/rhythmEventsRecoilDataEffect.js


Comments