Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/dhis2/capture-app into hv…
Browse files Browse the repository at this point in the history
…/feat/DHIS2-17792_OrgUnitContextInForms
  • Loading branch information
henrikmv committed Oct 14, 2024
2 parents 2b908da + ff859dc commit c0ca615
Show file tree
Hide file tree
Showing 13 changed files with 67 additions and 37 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## [101.10.1](https://github.com/dhis2/capture-app/compare/v101.10.0...v101.10.1) (2024-10-14)


### Bug Fixes

* [DHIS2-18028] User is able to add invalid related stages event ([#3795](https://github.com/dhis2/capture-app/issues/3795)) ([301585e](https://github.com/dhis2/capture-app/commit/301585ed17379900db642a05e0157d52107f96a2))

# [101.10.0](https://github.com/dhis2/capture-app/compare/v101.9.1...v101.10.0) (2024-10-14)


Expand Down
3 changes: 3 additions & 0 deletions cypress/e2e/NewPage/NewPage.feature
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,9 @@ Feature: User creates a new entries from the registration page
And you fill the Malaria case diagnosis registration form with values
And you click the save malaria entity submit button
Then you see the enrollment event Edit page
# Cleanup
And you delete the recently added malaria entity


## New enrollment of existing TEI

Expand Down
15 changes: 13 additions & 2 deletions cypress/e2e/NewPage/NewPage.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Given, When, Then, defineStep as And } from '@badeball/cypress-cucumber-preprocessor';
import { defineStep as And, Given, Then, When } from '@badeball/cypress-cucumber-preprocessor';
import moment from 'moment';
import { getCurrentYear } from '../../support/date';

Expand All @@ -17,7 +17,7 @@ And('there should be informative message explaining you need to select an organi
});

And('you select tracked entity type person', () => {
cy.get('[data-test="dhis2-uicore-select"')
cy.get('[data-test="dhis2-uicore-select"]')
.click();
cy.get('[data-test="dhis2-uicore-singleselectoption"]')
.contains('Person')
Expand Down Expand Up @@ -645,6 +645,17 @@ And('you delete the recently added tracked entity', () => {
cy.url().should('include', 'selectedTemplateId=IpHINAT79UW');
});

And('you delete the recently added malaria entity', () => {
cy.get('[data-test="widget-profile-overflow-menu"]')
.click();
cy.contains('Delete Malaria Entity')
.click();
cy.get('[data-test="widget-profile-delete-modal"]').within(() => {
cy.contains('Yes, delete Malaria Entity')
.click();
});
});

And(/^you select (.*) from the available tracked entity types/, (selection) => {
cy.get('[data-test="dhis2-uicore-select-input"]')
.click();
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "capture-app",
"homepage": ".",
"version": "101.10.0",
"version": "101.10.1",
"cacheVersion": "7",
"serverVersion": "38",
"license": "BSD-3-Clause",
Expand All @@ -10,7 +10,7 @@
"packages/rules-engine"
],
"dependencies": {
"@dhis2/rules-engine-javascript": "101.10.0",
"@dhis2/rules-engine-javascript": "101.10.1",
"@dhis2/app-runtime": "^3.9.3",
"@dhis2/d2-i18n": "^1.1.0",
"@dhis2/d2-icons": "^1.0.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/rules-engine/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dhis2/rules-engine-javascript",
"version": "101.10.0",
"version": "101.10.1",
"license": "BSD-3-Clause",
"main": "./build/cjs/index.js",
"scripts": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const getEventDetailsByLinkMode = ({
linkedEvent: {
...baseEventDetails,
scheduledAt: convertFn(clientRequestEvent.scheduledAt, dataElementTypes.DATE),
orgUnit: convertFn(clientRequestEvent.orgUnit, dataElementTypes.ORGANISATION_UNIT),
orgUnit: clientRequestEvent.orgUnit,
},
linkedEventId: baseEventDetails.event,
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
// @flow
import React from 'react';
import i18n from '@dhis2/d2-i18n';
import {
SingleSelectField,
SingleSelectOption,
spacers,
} from '@dhis2/ui';
import { SingleSelectField, SingleSelectOption, spacers } from '@dhis2/ui';
import { withStyles } from '@material-ui/core';
import type { LinkToExistingProps } from './LinkToExisting.types';

Expand Down Expand Up @@ -58,13 +54,15 @@ export const LinkToExistingPlain = ({
error={saveAttempted && !!errorMessages.linkedEventId}
validationText={saveAttempted && errorMessages.linkedEventId}
>
{linkableEvents.map(event => (
<SingleSelectOption
key={event.id}
value={event.id}
label={event.label}
/>
))}
{linkableEvents
.map(event => (
<SingleSelectOption
key={event.id}
value={event.id}
label={event.label}
/>
))
}
</SingleSelectField>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
// @flow

import type { ErrorMessagesForRelatedStages, LinkableEvent } from '../RelatedStagesActions/RelatedStagesActions.types';
import type {
ErrorMessagesForRelatedStages,
RelatedStagesEvents,
} from '../RelatedStagesActions/RelatedStagesActions.types';
import type { RelatedStageDataValueStates } from '../WidgetRelatedStages.types';

export type LinkToExistingProps = {|
relatedStagesDataValues: RelatedStageDataValueStates,
setRelatedStagesDataValues: (RelatedStageDataValueStates) => void,
linkableEvents: Array<LinkableEvent>,
linkableEvents: Array<RelatedStagesEvents>,
errorMessages: ErrorMessagesForRelatedStages,
saveAttempted: boolean,
linkableStageLabel: string,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// @flow
import React, { type ComponentType, useMemo } from 'react';
import i18n from '@dhis2/d2-i18n';
import { Radio, colors, spacers, spacersNum, IconInfo16, Button } from '@dhis2/ui';
import { Button, colors, IconInfo16, Radio, spacers, spacersNum } from '@dhis2/ui';
import { withStyles } from '@material-ui/core';
import { ConditionalTooltip } from 'capture-core/components/Tooltips/ConditionalTooltip';
import { actions as RelatedStagesActionTypes, mainOptionTranslatedTexts, relatedStageStatus } from '../constants';
Expand Down Expand Up @@ -53,6 +53,7 @@ export const RelatedStagesActionsPlain = ({
type,
relationshipName,
scheduledLabel,
events,
linkableEvents,
relatedStagesDataValues,
setRelatedStagesDataValues,
Expand All @@ -71,7 +72,7 @@ export const RelatedStagesActionsPlain = ({
linkMode: action,
}));
};
const canAddNewEventToStage = useCanAddNewEventToStage(programStage, linkableEvents);
const canAddNewEventToStage = useCanAddNewEventToStage(programStage, events);

if (!programStage) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,19 @@ export type ErrorMessagesForRelatedStages = {|
linkedEventId?: ?string,
|}

export type LinkableEvent = {
export type RelatedStagesEvents = {
id: string,
label: string,
isLinkable: boolean,
status: string,
}

export type Props = {|
type: string,
relationshipName: string,
relatedStagesDataValues: RelatedStageDataValueStates,
linkableEvents: Array<LinkableEvent>,
events: Array<RelatedStagesEvents>,
linkableEvents: Array<RelatedStagesEvents>,
scheduledLabel: string,
saveAttempted: boolean,
errorMessages: ErrorMessagesForRelatedStages,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useState } from 'react';
import { useRelatedStages } from './useRelatedStages';
import type { Props, RelatedStageDataValueStates } from './WidgetRelatedStages.types';
import type { ErrorMessagesForRelatedStages } from './RelatedStagesActions';
import { RelatedStagesActions } from './RelatedStagesActions';
import { relatedStageStatus } from './constants';
import { useStageLabels } from './hooks/useStageLabels';
import type { ErrorMessagesForRelatedStages } from './RelatedStagesActions';
import { relatedStageWidgetIsValid } from './relatedStageEventIsValid/relatedStageEventIsValid';
import { useAvailableRelatedStageEvents } from './hooks/useAvailableRelatedStageEvents';
import { useRelatedStageEvents } from './hooks/useRelatedStageEvents';

const WidgetRelatedStagesPlain = ({
programId,
Expand All @@ -21,7 +21,7 @@ const WidgetRelatedStagesPlain = ({
programId,
});
const { scheduledLabel, occurredLabel } = useStageLabels(programId, constraint?.programStage?.id);
const { linkableEvents, isLoading: isLoadingEvents } = useAvailableRelatedStageEvents({
const { events, linkableEvents, isLoading: isLoadingEvents } = useRelatedStageEvents({
stageId: constraint?.programStage?.id,
relationshipTypeId: selectedRelationshipType?.id,
scheduledLabel,
Expand Down Expand Up @@ -90,6 +90,7 @@ const WidgetRelatedStagesPlain = ({
relationshipName={selectedRelationshipType.displayName}
scheduledLabel={scheduledLabel}
type={currentRelatedStagesStatus}
events={events}
linkableEvents={linkableEvents}
relatedStagesDataValues={relatedStageDataValues}
setRelatedStagesDataValues={setRelatedStageDataValues}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
import { useMemo } from 'react';
import { useSelector } from 'react-redux';
import { ProgramStage } from '../../../metaData';
import type { LinkableEvent } from '../RelatedStagesActions/RelatedStagesActions.types';
import type { RelatedStagesEvents } from '../RelatedStagesActions/RelatedStagesActions.types';

export const useCanAddNewEventToStage = (programStage: ?ProgramStage, existingRelatedEvents: LinkableEvent[]) => {
export const useCanAddNewEventToStage = (programStage: ?ProgramStage, existingRelatedEvents: RelatedStagesEvents[]) => {
const hiddenProgramStages = useSelector(({ rulesEffectsHiddenProgramStageDesc }) =>
rulesEffectsHiddenProgramStageDesc?.['enrollmentEvent-newEvent'],
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// @flow
import { useMemo } from 'react';
import { convertDateObjectToDateFormatString } from '../../../utils/converters/date';
import type { LinkableEvent } from '../RelatedStagesActions/RelatedStagesActions.types';
import type { RelatedStagesEvents } from '../RelatedStagesActions/RelatedStagesActions.types';
import { useApiDataQuery } from '../../../utils/reactQueryHelpers';
import { handleAPIResponse, REQUESTED_ENTITIES } from '../../../utils/api';

Expand All @@ -15,12 +15,13 @@ type Props = {
}

type ReturnType = {
linkableEvents: Array<LinkableEvent>,
events: Array<RelatedStagesEvents>,
linkableEvents: Array<RelatedStagesEvents>,
isLoading: boolean,
isError: boolean,
}

export const useAvailableRelatedStageEvents = ({
export const useRelatedStageEvents = ({
stageId,
enrollmentId,
relationshipTypeId,
Expand All @@ -36,7 +37,7 @@ export const useAvailableRelatedStageEvents = ({
fields: 'event,occurredAt,scheduledAt,status,relationships',
},
}), [stageId, enrollmentId]);
const { data, isLoading, isError } = useApiDataQuery<Array<LinkableEvent>>(
const { data, isLoading, isError } = useApiDataQuery<Array<RelatedStagesEvents>>(
['availableRelatedStageEvents', stageId, enrollmentId, relationshipTypeId],
query,
{
Expand All @@ -45,19 +46,20 @@ export const useAvailableRelatedStageEvents = ({
staleTime: 0,
select: (response: any) => {
const events = handleAPIResponse(REQUESTED_ENTITIES.events, response);

if (events.length === 0) return [];

return events
.filter(event => !event.relationships ||
!event.relationships.some(relationship => relationship.relationshipType === relationshipTypeId))
.map((event) => {
const isLinkable = !event.relationships
?.some(relationship => relationship.relationshipType === relationshipTypeId);
const label = event.occurredAt
? `${occurredLabel}: ${convertDateObjectToDateFormatString(new Date(event.occurredAt))}`
: `${scheduledLabel}: ${convertDateObjectToDateFormatString(new Date(event.scheduledAt))}`;

return ({
id: event.event,
status: event.status,
isLinkable,
label,
});
});
Expand All @@ -66,7 +68,8 @@ export const useAvailableRelatedStageEvents = ({
);

return {
linkableEvents: data ?? [],
events: data ?? [],
linkableEvents: data?.filter(event => event.isLinkable) ?? [],
isLoading,
isError,
};
Expand Down

0 comments on commit c0ca615

Please sign in to comment.