Skip to content
Open
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
4 changes: 2 additions & 2 deletions i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -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-08-12T10:41:50.939Z\n"
"PO-Revision-Date: 2026-08-12T10:41:50.939Z\n"
"POT-Creation-Date: 2026-08-13T12:59:32.261Z\n"
"PO-Revision-Date: 2026-08-13T12:59:32.261Z\n"

msgid "The application could not be loaded."
msgstr "The application could not be loaded."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ 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 { errorCreator } from 'capture-core-utils';
import { statusTypes as eventStatuses } from 'capture-core/events/statusTypes';
import { removeEventChangelogQueries } from '../../WidgetsChangelog';

type Props = {
eventId: string;
Expand All @@ -25,6 +26,7 @@ export const CompletionMenuItem = ({
onClose,
}: Props) => {
const dataEngine = useDataEngine();
const queryClient = useQueryClient();
const { show: showError } = useAlert(
({ message }) => message,
{ critical: true },
Expand Down Expand Up @@ -65,6 +67,7 @@ export const CompletionMenuItem = ({
onError?.();
},
onSuccess: () => {
removeEventChangelogQueries(queryClient, eventId);
onSuccess?.(newStatus);
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -181,7 +184,8 @@ export const EnrollmentPageDefault = () => {
);
const onUpdateEnrollmentStatusSuccess = useCallback(() => {
dispatch(commitEnrollmentAndEvents());
}, [dispatch]);
removeEventChangelogQueries(queryClient);
}, [dispatch, queryClient]);

const onBackToMainPage = useCallback(() => {
navigate(`/?${buildUrlQueryString({ orgUnitId, programId })}`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -245,8 +244,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]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 } from '../../../../hooks';
Expand Down Expand Up @@ -63,7 +62,6 @@ const EventDetailsSectionPlain = (props: PlainProps & { classes: any }) => {
const {
classes,
eventId,
eventData,
onOpenEditEvent,
isEditEventPage,
programStage,
Expand All @@ -84,8 +82,7 @@ const EventDetailsSectionPlain = (props: PlainProps & { classes: any }) => {
const { hasAuthority: canUncompleteEvent } = useAuthorities({ authorities: ['F_UNCOMPLETE_EVENT'] });

const onSaveExternal = useCallback(() => {
const queryKey = [ReactQueryAppNamespace, 'changelog', CHANGELOG_ENTITY_TYPES.EVENT, eventId];
queryClient.removeQueries(queryKey);
removeEventChangelogQueries(queryClient, eventId);
onBackToAllEvents();
}, [eventId, queryClient, onBackToAllEvents]);

Expand Down Expand Up @@ -183,7 +180,6 @@ const EventDetailsSectionPlain = (props: PlainProps & { classes: any }) => {
<EventChangelogWrapper
isOpen
setIsOpen={setChangeLogIsOpen}
eventData={eventData?.eventContainer?.values}
eventId={eventId}
formFoundation={programStage.stageForm}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -62,7 +62,6 @@ export const EventChangelogWrapper = ({ formFoundation, eventId, eventData, ...p
<WidgetEventChangelog
{...passOnProps}
eventId={eventId}
eventData={eventData}
dataItemDefinitions={dataItemDefinitions}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,4 @@ type PassOnProps = {

export type Props = PassOnProps & {
formFoundation: RenderFoundation,
eventData: Record<string, unknown>,
};
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@ const WidgetEventEditPlain = ({
isOpen
setIsOpen={setChangeLogIsOpen}
eventId={loadedValues.eventContainer.id}
eventData={loadedValues.eventContainer.values}
formFoundation={formFoundation}
/>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ export const TrackedEntityChangelogWrapper = ({
close={() => setIsOpen(false)}
programId={programAPI.id}
dataItemDefinitions={dataItemDefinitions}
trackedEntityData={transformedTrackedEntityData}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand All @@ -28,6 +29,7 @@ export const SkipAction = ({
onUpdateEventStatus,
}: Props) => {
const dataEngine = useDataEngine();
const queryClient = useQueryClient();
const { show: showError } = useAlert(
({ message }) => message,
{ critical: true },
Expand Down Expand Up @@ -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 }));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,20 @@ import { Changelog, CHANGELOG_ENTITY_TYPES } from '../common/Changelog';

type Props = {
eventId: string;
eventData: Record<string, unknown>;
dataItemDefinitions: ItemDefinitions;
isOpen: boolean;
setIsOpen: (value: boolean | ((prev: boolean) => boolean)) => void;
};

export const WidgetEventChangelog = ({
eventId,
eventData,
setIsOpen,
...passOnProps
}: Props) => (
<Changelog
{...passOnProps}
close={() => setIsOpen(false)}
entityId={eventId}
entityData={eventData}
entityType={CHANGELOG_ENTITY_TYPES.EVENT}
/>
);
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,17 @@ type Props = {
dataItemDefinitions: ItemDefinitions;
isOpen: boolean;
close: () => void;
trackedEntityData: Record<string, unknown>;
};

export const WidgetTrackedEntityChangelog = ({
teiId,
programId,
close,
trackedEntityData,
...passOnProps
}: Props) => (
<Changelog
{...passOnProps}
close={close}
entityData={trackedEntityData}
entityId={teiId}
programId={programId}
entityType={CHANGELOG_ENTITY_TYPES.TRACKED_ENTITY}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import type { ItemDefinitions } from './Changelog.types';

type Props = {
entityId: string;
entityData: Record<string, any>;
entityType: typeof CHANGELOG_ENTITY_TYPES[keyof typeof CHANGELOG_ENTITY_TYPES];
isOpen: boolean;
close: () => void;
Expand All @@ -17,7 +16,6 @@ type Props = {

export const Changelog = ({
entityId,
entityData,
entityType,
programId,
isOpen,
Expand All @@ -38,8 +36,10 @@ export const Changelog = ({
setSortDirection,
filterValue,
setFilterValue,
filterParam,
attributeToFilterBy,
setAttributeToFilterBy,
dataUpdatedAt: rawDataUpdatedAt,
} = useChangelogData({ entityId, entityType, programId });

const {
Expand All @@ -49,12 +49,14 @@ export const Changelog = ({
rawRecords,
dataItemDefinitions,
entityId,
entityData,
entityType,
programId,
sortDirection,
columnToSortBy,
filterParam,
page,
pageSize,
rawDataUpdatedAt,
});

const loading = (isChangelogLoading || isProcessingLoading);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { useChangelogData } from './useChangelogData';
export { useListDataValues } from './useListDataValues';
export { useCurrentEntityValues } from './useCurrentEntityValues';
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -74,9 +74,11 @@ export const useChangelogData = ({ entityId, entityType, programId }: Props) =>
setAttributeToFilterBy,
filterValue,
setFilterValue,
filterParam,
page,
pageSize,
isLoading: isInitialLoading,
isError,
dataUpdatedAt,
};
};
Original file line number Diff line number Diff line change
@@ -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<string, any>;

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<CurrentValues>(
['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,
};
};
Loading
Loading