diff --git a/i18n/en.pot b/i18n/en.pot
index a555e6bc51..903fce47f5 100644
--- a/i18n/en.pot
+++ b/i18n/en.pot
@@ -5,8 +5,8 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-"POT-Creation-Date: 2026-09-08T15:17:29.259Z\n"
-"PO-Revision-Date: 2026-09-08T15:17:29.262Z\n"
+"POT-Creation-Date: 2026-09-08T15:49:17.652Z\n"
+"PO-Revision-Date: 2026-09-08T15:49:17.653Z\n"
msgid "The application could not be loaded."
msgstr "The application could not be loaded."
diff --git a/src/core_modules/capture-core/components/EventOverflowMenu/MenuItems/CompletionMenuItem.tsx b/src/core_modules/capture-core/components/EventOverflowMenu/MenuItems/CompletionMenuItem.tsx
index de35726c0b..69899a51e1 100644
--- a/src/core_modules/capture-core/components/EventOverflowMenu/MenuItems/CompletionMenuItem.tsx
+++ b/src/core_modules/capture-core/components/EventOverflowMenu/MenuItems/CompletionMenuItem.tsx
@@ -2,13 +2,14 @@ import React from 'react';
import i18n from '@dhis2/d2-i18n';
import log from 'loglevel';
import { MenuItem, IconCheckmark16, IconUndo16 } from '@dhis2/ui';
-import { useMutation } from '@tanstack/react-query';
+import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useAlert, useDataEngine } from '@dhis2/app-runtime';
import { useDispatch } from 'react-redux';
import { errorCreator } from 'capture-core-utils';
import { statusTypes as eventStatuses } from 'capture-core/events/statusTypes';
-import { CompleteModal } from '../../DataEntries/common/trackerEvent/withAskToCompleteEnrollment/CompleteModal';
+import { removeEventChangelogQueries } from '../../WidgetsChangelog';
import { statusTypes as enrollmentStatuses } from '../../../enrollment';
+import { CompleteModal } from '../../DataEntries/common/trackerEvent/withAskToCompleteEnrollment/CompleteModal';
import {
updateEnrollmentAndEvents,
commitEnrollmentAndEvents,
@@ -64,6 +65,7 @@ export const CompletionMenuItem = ({
onAskCompleteEnrollment,
}: MenuItemProps) => {
const dataEngine = useDataEngine();
+ const queryClient = useQueryClient();
const { show: showError } = useAlert(({ message }) => message, { critical: true });
const isCompleted = eventStatus === eventStatuses.COMPLETED;
@@ -78,7 +80,10 @@ export const CompletionMenuItem = ({
log.error(errorCreator('An error occurred when updating event status')({ error, eventId, newStatus }));
onError?.();
},
- onSuccess: () => onSuccess?.(newStatus),
+ onSuccess: () => {
+ removeEventChangelogQueries(queryClient, eventId);
+ onSuccess?.(newStatus);
+ },
},
);
@@ -122,6 +127,7 @@ export const CompleteMenuItemModal = ({
}: ModalProps) => {
const dataEngine = useDataEngine();
const dispatch = useDispatch();
+ const queryClient = useQueryClient();
const { show: showError } = useAlert(({ message }) => message, { critical: true });
const handleError = (error: unknown) => {
@@ -134,7 +140,10 @@ export const CompleteMenuItemModal = ({
{
onMutate: () => onMutate?.(eventStatuses.COMPLETED),
onError: (error) => { handleError(error); onError?.(); },
- onSuccess: () => onSuccess?.(eventStatuses.COMPLETED),
+ onSuccess: () => {
+ removeEventChangelogQueries(queryClient, eventId);
+ onSuccess?.(eventStatuses.COMPLETED);
+ },
},
);
@@ -165,6 +174,7 @@ export const CompleteMenuItemModal = ({
},
onSuccess: () => {
dispatch(commitEnrollmentAndEvents());
+ removeEventChangelogQueries(queryClient, eventId);
onSuccess?.(eventStatuses.COMPLETED);
},
},
diff --git a/src/core_modules/capture-core/components/Pages/Enrollment/EnrollmentPageDefault/EnrollmentPageDefault.container.tsx b/src/core_modules/capture-core/components/Pages/Enrollment/EnrollmentPageDefault/EnrollmentPageDefault.container.tsx
index bfa61fbf85..0b2af5d2a9 100644
--- a/src/core_modules/capture-core/components/Pages/Enrollment/EnrollmentPageDefault/EnrollmentPageDefault.container.tsx
+++ b/src/core_modules/capture-core/components/Pages/Enrollment/EnrollmentPageDefault/EnrollmentPageDefault.container.tsx
@@ -5,7 +5,9 @@ import { errorCreator } from 'capture-core-utils';
import { formatMomentEn } from 'capture-core-utils/date';
import { useDispatch, useSelector } from 'react-redux';
import { useTimeZoneConversion } from '@dhis2/app-runtime';
+import { useQueryClient } from '@tanstack/react-query';
import type { ApiEnrollmentEvent } from 'capture-core-utils/types/api-types';
+import { removeEventChangelogQueries } from '../../../WidgetsChangelog';
import {
commitEnrollmentAndEvents,
EnrollmentAccessProvider,
@@ -50,6 +52,7 @@ import { useHideWidgetByRuleLocations } from '../../../../hooks';
export const EnrollmentPageDefault = () => {
const { navigate } = useNavigate();
const dispatch = useDispatch();
+ const queryClient = useQueryClient();
const { fromClientDate } = useTimeZoneConversion();
const { status: widgetEnrollmentStatus } = useSelector(({ widgetEnrollment }: any) => widgetEnrollment);
const { enrollmentId, programId, teiId, orgUnitId } = useLocationQuery();
@@ -181,7 +184,8 @@ export const EnrollmentPageDefault = () => {
);
const onUpdateEnrollmentStatusSuccess = useCallback(() => {
dispatch(commitEnrollmentAndEvents());
- }, [dispatch]);
+ removeEventChangelogQueries(queryClient);
+ }, [dispatch, queryClient]);
const onBackToMainPage = useCallback(() => {
navigate(`/?${buildUrlQueryString({ orgUnitId, programId })}`);
diff --git a/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/EnrollmentEditEventPage.container.tsx b/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/EnrollmentEditEventPage.container.tsx
index 201e616deb..760e891ff4 100644
--- a/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/EnrollmentEditEventPage.container.tsx
+++ b/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/EnrollmentEditEventPage.container.tsx
@@ -42,8 +42,7 @@ import { DataStoreKeyByPage, useEnrollmentPageLayout } from '../common/Enrollmen
import { DefaultPageLayout } from './PageLayout/DefaultPageLayout.constants';
import { rollbackAssignee, setAssignee } from './EnrollmentEditEventPage.actions';
import { convertClientToServer, convertServerToClient } from '../../../converters';
-import { CHANGELOG_ENTITY_TYPES } from '../../WidgetsChangelog';
-import { ReactQueryAppNamespace } from '../../../utils/reactQueryHelpers';
+import { removeEventChangelogQueries } from '../../WidgetsChangelog';
import { statusTypes } from '../../../enrollment';
import { cancelEditEventDataEntry } from '../../WidgetEventEdit/EditEventDataEntry/editEventDataEntry.actions';
import { setCurrentDataEntry } from '../../DataEntry/actions/dataEntry.actions';
@@ -246,8 +245,7 @@ const EnrollmentEditEventPageWithContextPlain = ({
}, [dispatch, navigate, orgUnitId, enrollmentId, eventId]);
const onSaveExternal = useCallback(() => {
- const queryKey = [ReactQueryAppNamespace, 'changelog', CHANGELOG_ENTITY_TYPES.EVENT, eventId];
- queryClient.removeQueries(queryKey);
+ removeEventChangelogQueries(queryClient, eventId);
navigate(`enrollment?${buildUrlQueryString({ orgUnitId, enrollmentId })}`);
}, [navigate, orgUnitId, enrollmentId, eventId, queryClient]);
diff --git a/src/core_modules/capture-core/components/Pages/ViewEvent/EventDetailsSection/EventDetailsSection.component.tsx b/src/core_modules/capture-core/components/Pages/ViewEvent/EventDetailsSection/EventDetailsSection.component.tsx
index 3dd42407a5..b6098cf6ab 100644
--- a/src/core_modules/capture-core/components/Pages/ViewEvent/EventDetailsSection/EventDetailsSection.component.tsx
+++ b/src/core_modules/capture-core/components/Pages/ViewEvent/EventDetailsSection/EventDetailsSection.component.tsx
@@ -20,8 +20,7 @@ import { useCoreOrgUnit } from '../../../../metadataRetrieval/coreOrgUnit';
import { NoticeBox } from '../../../NoticeBox';
import { EventChangelogWrapper } from '../../../WidgetEventEdit/EventChangelogWrapper';
import { OverflowButton } from '../../../Buttons';
-import { ReactQueryAppNamespace } from '../../../../utils/reactQueryHelpers';
-import { CHANGELOG_ENTITY_TYPES } from '../../../WidgetsChangelog';
+import { removeEventChangelogQueries } from '../../../WidgetsChangelog';
import { useCategoryCombinations } from '../../../DataEntryDhis2Helpers/AOC/useCategoryCombinations';
import { useMetadataForProgramStage } from '../../../DataEntries/common/ProgramStage/useMetadataForProgramStage';
import { useProgramExpiryForUser, useEventEditPermissions } from '../../../../hooks';
@@ -64,7 +63,6 @@ const EventDetailsSectionPlain = (props: PlainProps & { classes: any }) => {
const {
classes,
eventId,
- eventData,
onOpenEditEvent,
isEditEventPage,
programStage,
@@ -74,7 +72,9 @@ const EventDetailsSectionPlain = (props: PlainProps & { classes: any }) => {
showEditButton,
...passOnProps
} = props;
- const orgUnitId = useSelector((state: any) => state.viewEventPage.loadedValues?.orgUnit?.id);
+ const orgUnitId = useSelector((state: { viewEventPage: { loadedValues: any } }) =>
+ state.viewEventPage.loadedValues?.orgUnit?.id);
+ const loadedValues = useSelector((state: { viewEventPage: { loadedValues: any } }) => state.viewEventPage.loadedValues);
const { formFoundation } = useMetadataForProgramStage({ programId });
const { orgUnit, error } = useCoreOrgUnit(orgUnitId);
const { programCategory, isLoading } = useCategoryCombinations(programId);
@@ -85,14 +85,13 @@ const EventDetailsSectionPlain = (props: PlainProps & { classes: any }) => {
const { canToggleCompletion } = useEventEditPermissions({
programId,
stage: programStage,
- eventStatus: eventData?.eventContainer?.event?.status,
- occurredAtClient: convertFormToClient(eventData?.dataEntryValues?.occurredAt, dataElementTypes.DATE) as string,
- completedAtClient: eventData?.eventContainer?.event?.completedAt,
+ eventStatus: loadedValues?.eventContainer?.event?.status,
+ occurredAtClient: convertFormToClient(loadedValues?.dataEntryValues?.occurredAt, dataElementTypes.DATE) as string,
+ completedAtClient: loadedValues?.eventContainer?.event?.completedAt,
});
const onSaveExternal = useCallback(() => {
- const queryKey = [ReactQueryAppNamespace, 'changelog', CHANGELOG_ENTITY_TYPES.EVENT, eventId];
- queryClient.removeQueries(queryKey);
+ removeEventChangelogQueries(queryClient, eventId);
onBackToAllEvents();
}, [eventId, queryClient, onBackToAllEvents]);
@@ -190,7 +189,6 @@ const EventDetailsSectionPlain = (props: PlainProps & { classes: any }) => {
diff --git a/src/core_modules/capture-core/components/Pages/ViewEvent/EventDetailsSection/EventDetailsSection.container.ts b/src/core_modules/capture-core/components/Pages/ViewEvent/EventDetailsSection/EventDetailsSection.container.ts
index 52962ab10f..3ac04acd35 100644
--- a/src/core_modules/capture-core/components/Pages/ViewEvent/EventDetailsSection/EventDetailsSection.container.ts
+++ b/src/core_modules/capture-core/components/Pages/ViewEvent/EventDetailsSection/EventDetailsSection.container.ts
@@ -7,7 +7,6 @@ import {
const mapStateToProps = (state: any, ownProps: any) => ({
isEditEventPage: state.viewEventPage.eventDetailsSection && state.viewEventPage.eventDetailsSection.showEditEvent,
eventId: state.viewEventPage.eventId,
- eventData: state.viewEventPage.loadedValues || {},
programId: state.currentSelections.programId,
...ownProps,
});
diff --git a/src/core_modules/capture-core/components/Pages/ViewEvent/EventDetailsSection/EventDetailsSection.types.ts b/src/core_modules/capture-core/components/Pages/ViewEvent/EventDetailsSection/EventDetailsSection.types.ts
index 337cb058f4..8f675676ad 100644
--- a/src/core_modules/capture-core/components/Pages/ViewEvent/EventDetailsSection/EventDetailsSection.types.ts
+++ b/src/core_modules/capture-core/components/Pages/ViewEvent/EventDetailsSection/EventDetailsSection.types.ts
@@ -3,7 +3,6 @@ import { ProgramStage } from 'capture-core/metaData';
export type PlainProps = {
isEditEventPage?: boolean;
eventId: string;
- eventData: any;
onOpenEditEvent: (orgUnit: any, programCategory?: any) => void;
programStage: ProgramStage;
eventAccess: { read: boolean, write: boolean };
diff --git a/src/core_modules/capture-core/components/WidgetEventEdit/EventChangelogWrapper/EventChangelogWrapper.component.tsx b/src/core_modules/capture-core/components/WidgetEventEdit/EventChangelogWrapper/EventChangelogWrapper.component.tsx
index da9ff11032..ddfed141fe 100644
--- a/src/core_modules/capture-core/components/WidgetEventEdit/EventChangelogWrapper/EventChangelogWrapper.component.tsx
+++ b/src/core_modules/capture-core/components/WidgetEventEdit/EventChangelogWrapper/EventChangelogWrapper.component.tsx
@@ -5,7 +5,7 @@ import { dataElementTypes } from '../../../metaData';
import type { Props } from './EventChangelogWrapper.types';
import { WidgetEventChangelog } from '../../WidgetsChangelog';
-export const EventChangelogWrapper = ({ formFoundation, eventId, eventData, ...passOnProps }: Props) => {
+export const EventChangelogWrapper = ({ formFoundation, eventId, ...passOnProps }: Props) => {
const dataItemDefinitions = useMemo(() => {
const elements = formFoundation.getElements();
const contextLabels = formFoundation.getLabels();
@@ -62,7 +62,6 @@ export const EventChangelogWrapper = ({ formFoundation, eventId, eventData, ...p
);
diff --git a/src/core_modules/capture-core/components/WidgetEventEdit/EventChangelogWrapper/EventChangelogWrapper.types.ts b/src/core_modules/capture-core/components/WidgetEventEdit/EventChangelogWrapper/EventChangelogWrapper.types.ts
index a5c244f7e9..2ef4d0c471 100644
--- a/src/core_modules/capture-core/components/WidgetEventEdit/EventChangelogWrapper/EventChangelogWrapper.types.ts
+++ b/src/core_modules/capture-core/components/WidgetEventEdit/EventChangelogWrapper/EventChangelogWrapper.types.ts
@@ -8,5 +8,4 @@ type PassOnProps = {
export type Props = PassOnProps & {
formFoundation: RenderFoundation,
- eventData: Record,
};
diff --git a/src/core_modules/capture-core/components/WidgetEventEdit/WidgetEventEdit.container.tsx b/src/core_modules/capture-core/components/WidgetEventEdit/WidgetEventEdit.container.tsx
index b15639cb14..8cbdf41980 100644
--- a/src/core_modules/capture-core/components/WidgetEventEdit/WidgetEventEdit.container.tsx
+++ b/src/core_modules/capture-core/components/WidgetEventEdit/WidgetEventEdit.container.tsx
@@ -102,7 +102,7 @@ const WidgetEventEditPlain = ({
const { currentPageMode } = useEnrollmentEditEventPageMode(eventStatus);
const [changeLogIsOpen, setChangeLogIsOpen] = useState(false);
// "Edit event"-button depends on loadedValues. Delay rendering component until loadedValues has been initialized.
- const loadedValues = useSelector((state: { viewEventPage: { loadedValues: any } }) => state.viewEventPage.loadedValues);
+ const loadedValues = useSelector((state: any) => state.viewEventPage.loadedValues);
const orgUnit = loadedValues?.orgUnit;
const occurredAt = loadedValues?.dataEntryValues?.occurredAt;
const completedAt = loadedValues?.eventContainer?.event?.completedAt;
@@ -205,7 +205,6 @@ const WidgetEventEditPlain = ({
isOpen
setIsOpen={setChangeLogIsOpen}
eventId={loadedValues.eventContainer.id}
- eventData={loadedValues.eventContainer.values}
formFoundation={formFoundation}
/>
)}
diff --git a/src/core_modules/capture-core/components/WidgetProfile/OverflowMenu/TrackedEntityChangelogWrapper/TrackedEntityChangelogWrapper.component.tsx b/src/core_modules/capture-core/components/WidgetProfile/OverflowMenu/TrackedEntityChangelogWrapper/TrackedEntityChangelogWrapper.component.tsx
index d515fa1892..6b8a1f80f7 100644
--- a/src/core_modules/capture-core/components/WidgetProfile/OverflowMenu/TrackedEntityChangelogWrapper/TrackedEntityChangelogWrapper.component.tsx
+++ b/src/core_modules/capture-core/components/WidgetProfile/OverflowMenu/TrackedEntityChangelogWrapper/TrackedEntityChangelogWrapper.component.tsx
@@ -68,7 +68,6 @@ export const TrackedEntityChangelogWrapper = ({
close={() => setIsOpen(false)}
programId={programAPI.id}
dataItemDefinitions={dataItemDefinitions}
- trackedEntityData={transformedTrackedEntityData}
/>
);
};
diff --git a/src/core_modules/capture-core/components/WidgetProfile/WidgetProfile.component.tsx b/src/core_modules/capture-core/components/WidgetProfile/WidgetProfile.component.tsx
index fbfcd015a9..9493be162d 100644
--- a/src/core_modules/capture-core/components/WidgetProfile/WidgetProfile.component.tsx
+++ b/src/core_modules/capture-core/components/WidgetProfile/WidgetProfile.component.tsx
@@ -19,8 +19,7 @@ import {
useTeiDisplayName,
} from './hooks';
import { DataEntry, dataEntryActionTypes, TEI_MODAL_STATE, convertClientToView } from './DataEntry';
-import { ReactQueryAppNamespace } from '../../utils/reactQueryHelpers';
-import { CHANGELOG_ENTITY_TYPES } from '../WidgetsChangelog';
+import { removeTrackedEntityChangelogQueries } from '../WidgetsChangelog';
import { OverflowMenu } from './OverflowMenu';
import {
useDataEntryFormConfig,
@@ -142,7 +141,7 @@ const WidgetProfilePlain = ({
}), [clientAttributesWithSubvalues]);
const onSaveExternal = useCallback(() => {
- queryClient.removeQueries([ReactQueryAppNamespace, 'changelog', CHANGELOG_ENTITY_TYPES.TRACKED_ENTITY, teiId]);
+ removeTrackedEntityChangelogQueries(queryClient, teiId);
}, [queryClient, teiId]);
useEffect(() => {
diff --git a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/SkipAction/SkipAction.tsx b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/SkipAction/SkipAction.tsx
index 2b0706687a..c769d62db2 100644
--- a/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/SkipAction/SkipAction.tsx
+++ b/src/core_modules/capture-core/components/WidgetStagesAndEvents/Stages/Stage/StageDetail/EventRow/SkipAction/SkipAction.tsx
@@ -5,11 +5,12 @@ import {
MenuItem,
IconRedo16,
} from '@dhis2/ui';
-import { useMutation } from '@tanstack/react-query';
+import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useAlert, useDataEngine } from '@dhis2/app-runtime';
import { errorCreator } from 'capture-core-utils';
import type { ApiEnrollmentEvent } from 'capture-core-utils/types/api-types';
import { statusTypes as eventStatuses } from 'capture-core/events/statusTypes';
+import { removeEventChangelogQueries } from '../../../../../../WidgetsChangelog';
import { DirectionalArrow } from '../../../../../../../utils/rtl';
type Props = {
@@ -28,6 +29,7 @@ export const SkipAction = ({
onUpdateEventStatus,
}: Props) => {
const dataEngine = useDataEngine();
+ const queryClient = useQueryClient();
const { show: showError } = useAlert(
({ message }) => message,
{ critical: true },
@@ -55,6 +57,9 @@ export const SkipAction = ({
return { previousStatus };
},
+ onSuccess: () => {
+ removeEventChangelogQueries(queryClient, eventId);
+ },
onError: (error: unknown, payload: { status: string }, context?: { previousStatus: string }) => {
showError({ message: i18n.t('An error occurred when updating event status') });
log.error(errorCreator('An error occurred when updating event status')({ error, payload, context }));
@@ -75,7 +80,7 @@ export const SkipAction = ({
icon={}
label={i18n.t('Unskip')}
onClick={() => handleMenuItemClick(eventStatuses.SCHEDULE)}
- suffix=""
+ suffix={null}
/>
);
}
@@ -86,7 +91,7 @@ export const SkipAction = ({
icon={}
label={i18n.t('Skip')}
onClick={() => handleMenuItemClick(eventStatuses.SKIPPED)}
- suffix=""
+ suffix={null}
/>
);
};
diff --git a/src/core_modules/capture-core/components/WidgetsChangelog/WidgetEventChangelog/WidgetEventChangelog.tsx b/src/core_modules/capture-core/components/WidgetsChangelog/WidgetEventChangelog/WidgetEventChangelog.tsx
index 0db8eb304b..2e95903a55 100644
--- a/src/core_modules/capture-core/components/WidgetsChangelog/WidgetEventChangelog/WidgetEventChangelog.tsx
+++ b/src/core_modules/capture-core/components/WidgetsChangelog/WidgetEventChangelog/WidgetEventChangelog.tsx
@@ -4,7 +4,6 @@ import { Changelog, CHANGELOG_ENTITY_TYPES } from '../common/Changelog';
type Props = {
eventId: string;
- eventData: Record;
dataItemDefinitions: ItemDefinitions;
isOpen: boolean;
setIsOpen: (value: boolean | ((prev: boolean) => boolean)) => void;
@@ -12,7 +11,6 @@ type Props = {
export const WidgetEventChangelog = ({
eventId,
- eventData,
setIsOpen,
...passOnProps
}: Props) => (
@@ -20,7 +18,6 @@ export const WidgetEventChangelog = ({
{...passOnProps}
close={() => setIsOpen(false)}
entityId={eventId}
- entityData={eventData}
entityType={CHANGELOG_ENTITY_TYPES.EVENT}
/>
);
diff --git a/src/core_modules/capture-core/components/WidgetsChangelog/WidgetTrackedEntityChangelog/WidgetTrackedEntityChangelog.tsx b/src/core_modules/capture-core/components/WidgetsChangelog/WidgetTrackedEntityChangelog/WidgetTrackedEntityChangelog.tsx
index 114e0daf26..07b771793d 100644
--- a/src/core_modules/capture-core/components/WidgetsChangelog/WidgetTrackedEntityChangelog/WidgetTrackedEntityChangelog.tsx
+++ b/src/core_modules/capture-core/components/WidgetsChangelog/WidgetTrackedEntityChangelog/WidgetTrackedEntityChangelog.tsx
@@ -8,20 +8,17 @@ type Props = {
dataItemDefinitions: ItemDefinitions;
isOpen: boolean;
close: () => void;
- trackedEntityData: Record;
};
export const WidgetTrackedEntityChangelog = ({
teiId,
programId,
close,
- trackedEntityData,
...passOnProps
}: Props) => (
;
entityType: typeof CHANGELOG_ENTITY_TYPES[keyof typeof CHANGELOG_ENTITY_TYPES];
isOpen: boolean;
close: () => void;
@@ -17,7 +16,6 @@ type Props = {
export const Changelog = ({
entityId,
- entityData,
entityType,
programId,
isOpen,
@@ -38,8 +36,10 @@ export const Changelog = ({
setSortDirection,
filterValue,
setFilterValue,
+ filterParam,
attributeToFilterBy,
setAttributeToFilterBy,
+ dataUpdatedAt: rawDataUpdatedAt,
} = useChangelogData({ entityId, entityType, programId });
const {
@@ -49,12 +49,14 @@ export const Changelog = ({
rawRecords,
dataItemDefinitions,
entityId,
- entityData,
entityType,
programId,
sortDirection,
+ columnToSortBy,
+ filterParam,
page,
pageSize,
+ rawDataUpdatedAt,
});
const loading = (isChangelogLoading || isProcessingLoading);
diff --git a/src/core_modules/capture-core/components/WidgetsChangelog/common/hooks/index.ts b/src/core_modules/capture-core/components/WidgetsChangelog/common/hooks/index.ts
index 2cce8aa7d5..4d2d9163ae 100644
--- a/src/core_modules/capture-core/components/WidgetsChangelog/common/hooks/index.ts
+++ b/src/core_modules/capture-core/components/WidgetsChangelog/common/hooks/index.ts
@@ -1,2 +1,3 @@
export { useChangelogData } from './useChangelogData';
export { useListDataValues } from './useListDataValues';
+export { useCurrentEntityValues } from './useCurrentEntityValues';
diff --git a/src/core_modules/capture-core/components/WidgetsChangelog/common/hooks/useChangelogData.ts b/src/core_modules/capture-core/components/WidgetsChangelog/common/hooks/useChangelogData.ts
index 85e8797145..76cfb6556d 100644
--- a/src/core_modules/capture-core/components/WidgetsChangelog/common/hooks/useChangelogData.ts
+++ b/src/core_modules/capture-core/components/WidgetsChangelog/common/hooks/useChangelogData.ts
@@ -40,7 +40,7 @@ export const useChangelogData = ({ entityId, entityType, programId }: Props) =>
? undefined
: `${columnToSortBy}:${sortDirection}`;
- const { data, isInitialLoading, isError } = useApiDataQuery(
+ const { data, isInitialLoading, isError, dataUpdatedAt } = useApiDataQuery(
[
'changelog',
entityType,
@@ -74,9 +74,11 @@ export const useChangelogData = ({ entityId, entityType, programId }: Props) =>
setAttributeToFilterBy,
filterValue,
setFilterValue,
+ filterParam,
page,
pageSize,
isLoading: isInitialLoading,
isError,
+ dataUpdatedAt,
};
};
diff --git a/src/core_modules/capture-core/components/WidgetsChangelog/common/hooks/useCurrentEntityValues.ts b/src/core_modules/capture-core/components/WidgetsChangelog/common/hooks/useCurrentEntityValues.ts
new file mode 100644
index 0000000000..a45b91b9b5
--- /dev/null
+++ b/src/core_modules/capture-core/components/WidgetsChangelog/common/hooks/useCurrentEntityValues.ts
@@ -0,0 +1,49 @@
+import { useApiDataQuery } from '../../../../utils/reactQueryHelpers';
+import { CHANGELOG_ENTITY_TYPES, QUERY_KEYS_BY_ENTITY_TYPE } from '../Changelog/Changelog.constants';
+
+type Props = {
+ entityId: string;
+ entityType: typeof CHANGELOG_ENTITY_TYPES[keyof typeof CHANGELOG_ENTITY_TYPES];
+ programId?: string;
+ enabled?: boolean;
+};
+
+export type CurrentValues = Record;
+
+const FIELDS_BY_ENTITY_TYPE = Object.freeze({
+ [CHANGELOG_ENTITY_TYPES.EVENT]: 'dataValues[dataElement,value]',
+ [CHANGELOG_ENTITY_TYPES.TRACKED_ENTITY]: 'attributes[attribute,value]',
+});
+
+const NO_VALUES: CurrentValues = Object.freeze({});
+
+export const useCurrentEntityValues = ({ entityId, entityType, programId, enabled = true }: Props) => {
+ const { data, isInitialLoading, dataUpdatedAt } = useApiDataQuery(
+ ['changelog', entityType, entityId, 'currentValues', { programId }],
+ {
+ resource: `tracker/${QUERY_KEYS_BY_ENTITY_TYPE[entityType]}/${entityId}`,
+ params: {
+ program: programId,
+ fields: FIELDS_BY_ENTITY_TYPE[entityType],
+ },
+ },
+ {
+ enabled: !!entityId && enabled,
+ select: (response: any) => {
+ const items = entityType === CHANGELOG_ENTITY_TYPES.EVENT
+ ? response?.dataValues
+ : response?.attributes;
+ return (items ?? []).reduce((acc, { dataElement, attribute, value }) => {
+ acc[dataElement ?? attribute] = value;
+ return acc;
+ }, {});
+ },
+ },
+ );
+
+ return {
+ currentValues: data ?? NO_VALUES,
+ isLoading: isInitialLoading,
+ dataUpdatedAt,
+ };
+};
diff --git a/src/core_modules/capture-core/components/WidgetsChangelog/common/hooks/useListDataValues.ts b/src/core_modules/capture-core/components/WidgetsChangelog/common/hooks/useListDataValues.ts
index d9606dcc0a..2a8d0da53f 100644
--- a/src/core_modules/capture-core/components/WidgetsChangelog/common/hooks/useListDataValues.ts
+++ b/src/core_modules/capture-core/components/WidgetsChangelog/common/hooks/useListDataValues.ts
@@ -11,24 +11,27 @@ import { convertServerToClient } from '../../../../converters';
import { convert as convertClientToList } from '../../../../converters/clientToList';
import { RECORD_TYPE, subValueGetterByElementType } from '../utils/getSubValueForChangelogData';
import { makeQuerySingleResource } from '../../../../utils/api';
+import { useCurrentEntityValues } from './useCurrentEntityValues';
type Props = {
rawRecords: any;
dataItemDefinitions: ItemDefinitions;
entityId: string;
- entityData: any;
entityType: typeof CHANGELOG_ENTITY_TYPES[keyof typeof CHANGELOG_ENTITY_TYPES];
programId?: string;
sortDirection: SortDirection;
+ columnToSortBy: string;
+ filterParam?: string;
page: number;
pageSize: number;
+ rawDataUpdatedAt: number;
};
const fetchFormattedValues = async ({
rawRecords,
dataItemDefinitions,
entityId,
- entityData,
+ currentValues,
entityType,
programId,
absoluteApiPath,
@@ -38,8 +41,7 @@ const fetchFormattedValues = async ({
if (!rawRecords) return [];
const getItemDefinition = (change: Change) => {
- const { dataElement, attribute, field } = change;
- const fieldId = dataElement ?? attribute ?? field;
+ const fieldId = change.dataElement ?? change.attribute ?? change.field;
if (!fieldId) {
log.error('Could not find fieldId in change:', change);
return null;
@@ -89,12 +91,11 @@ const fetchFormattedValues = async ({
return null;
};
+ const isLatestValue = currentValues[metadataElement.id] === change.currentValue;
+
const [previousValueClient, currentValueClient] = await Promise.all([
change.previousValue ? getValue(change.previousValue, false) : null,
- getValue(
- change.currentValue,
- entityData?.[change.attribute ?? change.dataElement]?.value === change.currentValue,
- ),
+ getValue(change.currentValue, isLatestValue),
]);
const { firstName, surname, username } = createdBy;
@@ -123,14 +124,34 @@ export const useListDataValues = ({
rawRecords,
dataItemDefinitions,
entityId,
- entityData,
entityType,
programId,
sortDirection,
+ columnToSortBy,
+ filterParam,
page,
pageSize,
+ rawDataUpdatedAt,
}: Props) => {
const dataEngine = useDataEngine();
+ const hasFileOrImageField = useMemo(
+ () => Object.values(dataItemDefinitions ?? {}).some(
+ (definition: any) =>
+ definition?.type === dataElementTypes.FILE_RESOURCE ||
+ definition?.type === dataElementTypes.IMAGE,
+ ),
+ [dataItemDefinitions],
+ );
+ const {
+ currentValues,
+ isLoading: isCurrentValuesLoading,
+ dataUpdatedAt: currentValuesUpdatedAt,
+ } = useCurrentEntityValues({
+ entityId,
+ entityType,
+ programId,
+ enabled: hasFileOrImageField,
+ });
const { baseUrl, apiVersion } = useConfig();
const { fromServerDate } = useTimeZoneConversion();
const absoluteApiPath = buildUrl(baseUrl, `api/${apiVersion}`);
@@ -146,7 +167,16 @@ export const useListDataValues = ({
entityType,
entityId,
'formattedData',
- { sortDirection, page, pageSize, programId, rawRecords },
+ {
+ columnToSortBy,
+ sortDirection,
+ page,
+ pageSize,
+ programId,
+ filterParam,
+ rawDataUpdatedAt,
+ currentValuesUpdatedAt,
+ },
];
const { data: processedRecords, isError, isInitialLoading } = useQuery(
@@ -155,7 +185,7 @@ export const useListDataValues = ({
rawRecords,
dataItemDefinitions,
entityId,
- entityData,
+ currentValues,
entityType,
programId,
absoluteApiPath,
@@ -163,12 +193,12 @@ export const useListDataValues = ({
fromServerDate,
}),
{
- enabled: !!rawRecords && !!dataItemDefinitions && !!entityId && !!entityType,
+ enabled: !!rawRecords && !!dataItemDefinitions && !!entityId && !!entityType && !isCurrentValuesLoading,
keepPreviousData: true,
staleTime: Infinity,
cacheTime: Infinity,
},
);
- return { processedRecords, isLoading: isInitialLoading, isError };
+ return { processedRecords, isLoading: isInitialLoading || isCurrentValuesLoading, isError };
};
diff --git a/src/core_modules/capture-core/components/WidgetsChangelog/common/utils/removeChangelogQueries.ts b/src/core_modules/capture-core/components/WidgetsChangelog/common/utils/removeChangelogQueries.ts
new file mode 100644
index 0000000000..fb7f824ade
--- /dev/null
+++ b/src/core_modules/capture-core/components/WidgetsChangelog/common/utils/removeChangelogQueries.ts
@@ -0,0 +1,22 @@
+import type { QueryClient } from '@tanstack/react-query';
+import { ReactQueryAppNamespace } from '../../../../utils/reactQueryHelpers';
+import { CHANGELOG_ENTITY_TYPES } from '../Changelog/Changelog.constants';
+
+type ChangelogEntityType = typeof CHANGELOG_ENTITY_TYPES[keyof typeof CHANGELOG_ENTITY_TYPES];
+
+const removeChangelogQueries = (
+ queryClient: QueryClient,
+ entityType: ChangelogEntityType,
+ entityId?: string,
+) => {
+ const queryKey = entityId
+ ? [ReactQueryAppNamespace, 'changelog', entityType, entityId]
+ : [ReactQueryAppNamespace, 'changelog', entityType];
+ queryClient.removeQueries(queryKey);
+};
+
+export const removeEventChangelogQueries = (queryClient: QueryClient, eventId?: string) =>
+ removeChangelogQueries(queryClient, CHANGELOG_ENTITY_TYPES.EVENT, eventId);
+
+export const removeTrackedEntityChangelogQueries = (queryClient: QueryClient, teiId: string) =>
+ removeChangelogQueries(queryClient, CHANGELOG_ENTITY_TYPES.TRACKED_ENTITY, teiId);
diff --git a/src/core_modules/capture-core/components/WidgetsChangelog/index.ts b/src/core_modules/capture-core/components/WidgetsChangelog/index.ts
index eb2bbde779..8d7cf09691 100644
--- a/src/core_modules/capture-core/components/WidgetsChangelog/index.ts
+++ b/src/core_modules/capture-core/components/WidgetsChangelog/index.ts
@@ -1,3 +1,7 @@
export { CHANGELOG_ENTITY_TYPES } from './common/Changelog';
export { WidgetEventChangelog } from './WidgetEventChangelog';
export { WidgetTrackedEntityChangelog } from './WidgetTrackedEntityChangelog';
+export {
+ removeEventChangelogQueries,
+ removeTrackedEntityChangelogQueries,
+} from './common/utils/removeChangelogQueries';
diff --git a/src/core_modules/capture-core/components/WorkingLists/EventWorkingListsCommon/EventBulkActions/Actions/CompleteAction/hooks/useBulkCompleteEvents.ts b/src/core_modules/capture-core/components/WorkingLists/EventWorkingListsCommon/EventBulkActions/Actions/CompleteAction/hooks/useBulkCompleteEvents.ts
index f15e825c93..57e41feef4 100644
--- a/src/core_modules/capture-core/components/WorkingLists/EventWorkingListsCommon/EventBulkActions/Actions/CompleteAction/hooks/useBulkCompleteEvents.ts
+++ b/src/core_modules/capture-core/components/WorkingLists/EventWorkingListsCommon/EventBulkActions/Actions/CompleteAction/hooks/useBulkCompleteEvents.ts
@@ -1,8 +1,9 @@
import { useCallback, useEffect, useMemo } from 'react';
import i18n from '@dhis2/d2-i18n';
-import { useMutation } from '@tanstack/react-query';
+import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useAlert, useDataEngine } from '@dhis2/app-runtime';
import { useApiDataQuery } from '../../../../../../../utils/reactQueryHelpers';
+import { removeEventChangelogQueries } from '../../../../../../WidgetsChangelog';
import { handleAPIResponse, REQUESTED_ENTITIES } from '../../../../../../../utils/api';
type Props = {
@@ -23,6 +24,7 @@ export const useBulkCompleteEvents = ({
programId,
}: Props) => {
const dataEngine = useDataEngine();
+ const queryClient = useQueryClient();
const { show: showAlert } = useAlert(
({ message }) => message,
{ critical: true },
@@ -87,9 +89,11 @@ export const useBulkCompleteEvents = ({
.find(errorReport => errorReport.uid === eventId),
);
+ removeEventChangelogQueries(queryClient);
removeRowsFromSelection(validEventIds);
onUpdateList(true);
} else {
+ removeEventChangelogQueries(queryClient);
onUpdateList();
setIsCompleteDialogOpen(false);
}
diff --git a/src/core_modules/capture-core/components/WorkingLists/TrackerWorkingLists/TrackedEntityBulkActions/Actions/CompleteAction/hooks/useCompleteBulkEnrollments.ts b/src/core_modules/capture-core/components/WorkingLists/TrackerWorkingLists/TrackedEntityBulkActions/Actions/CompleteAction/hooks/useCompleteBulkEnrollments.ts
index aa7388e5bc..d464d8bc02 100644
--- a/src/core_modules/capture-core/components/WorkingLists/TrackerWorkingLists/TrackedEntityBulkActions/Actions/CompleteAction/hooks/useCompleteBulkEnrollments.ts
+++ b/src/core_modules/capture-core/components/WorkingLists/TrackerWorkingLists/TrackedEntityBulkActions/Actions/CompleteAction/hooks/useCompleteBulkEnrollments.ts
@@ -7,6 +7,7 @@ import { errorCreator } from 'capture-core-utils';
import { ReactQueryAppNamespace, useApiDataQuery } from '../../../../../../../utils/reactQueryHelpers';
import { handleAPIResponse, REQUESTED_ENTITIES } from '../../../../../../../utils/api';
import type { ProgramStage } from '../../../../../../../metaData';
+import { removeEventChangelogQueries } from '../../../../../../WidgetsChangelog';
type Props = {
selectedRows: Record;
@@ -154,7 +155,10 @@ export const useCompleteBulkEnrollments = ({
} = useMutation(
({ enrollments }: any) => importValidEnrollments({ dataEngine, enrollments }),
{
- onSuccess: () => {
+ onSuccess: (_, { enrollments }: any) => {
+ if (enrollments.some(e => e.events?.length > 0)) {
+ removeEventChangelogQueries(queryClient);
+ }
onUpdateList();
removeQueries();
},
@@ -178,7 +182,10 @@ export const useCompleteBulkEnrollments = ({
} = useMutation(
({ enrollments }: any) => importValidEnrollments({ dataEngine, enrollments }),
{
- onSuccess: (serverResponse, { enrollments }) => {
+ onSuccess: (_, { enrollments }) => {
+ if (enrollments.some(e => e.events?.length > 0)) {
+ removeEventChangelogQueries(queryClient);
+ }
const enrollmentIds = enrollments.map(enrollment => enrollment.trackedEntity);
removeRowsFromSelection(enrollmentIds);
removeQueries();