Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into hv/fix/DHIS2-17101_…
Browse files Browse the repository at this point in the history
…ConsiderPreventAddingEventsToStageProgramRule
  • Loading branch information
henrikmv committed Jul 12, 2024
2 parents a02a66c + 42ee692 commit 63403f9
Show file tree
Hide file tree
Showing 22 changed files with 326 additions and 33 deletions.
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
## [100.70.9](https://github.com/dhis2/capture-app/compare/v100.70.8...v100.70.9) (2024-07-10)


### Bug Fixes

* [DHIS2-8814] Table in custom form overflows container with no scrollbar ([#3655](https://github.com/dhis2/capture-app/issues/3655)) ([c39c397](https://github.com/dhis2/capture-app/commit/c39c397ec078b7a8e765a3847d48881ebd720005))

## [100.70.8](https://github.com/dhis2/capture-app/compare/v100.70.7...v100.70.8) (2024-07-09)


### Bug Fixes

* [DHIS2-17398] improve unique ID search ([#3688](https://github.com/dhis2/capture-app/issues/3688)) ([183e419](https://github.com/dhis2/capture-app/commit/183e419000245173a5020a965e4d681ab0cfdf7f))

## [100.70.7](https://github.com/dhis2/capture-app/compare/v100.70.6...v100.70.7) (2024-07-09)


### Bug Fixes

* [BETA-116][DHIS2-15896] validate values assigned from the rules engine ([#3612](https://github.com/dhis2/capture-app/issues/3612)) ([459ab9a](https://github.com/dhis2/capture-app/commit/459ab9a7fc0b0f3c3ce98e19a7acf213b35eb6e8))

## [100.70.6](https://github.com/dhis2/capture-app/compare/v100.70.5...v100.70.6) (2024-07-05)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ Then the user see the following text: Low-dose acetylsalicylic acid given
When the user sets Plurality assessed to Singleton
Then the user don't see the following text: Low-dose acetylsalicylic acid given

# DHIS2-17730
@skip
Scenario: User can modify and save the data in the form
Given you land on the enrollment event page with selected Person by having typed /#/enrollmentEventEdit?orgUnitId=DiszpKrYNg8&eventId=V1CerIi3sdL
Then the user see the following text: Enrollment: View Event
Expand Down
3 changes: 0 additions & 3 deletions i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -850,9 +850,6 @@ msgstr "Choose the {{missingCategories}} to start reporting"
msgid "Save as new"
msgstr "Save as new"

msgid "View enrollment"
msgstr "View enrollment"

msgid "New"
msgstr "New"

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": "100.70.6",
"version": "100.70.9",
"cacheVersion": "7",
"serverVersion": "38",
"license": "BSD-3-Clause",
Expand All @@ -10,7 +10,7 @@
"packages/rules-engine"
],
"dependencies": {
"@dhis2/rules-engine-javascript": "100.70.6",
"@dhis2/rules-engine-javascript": "100.70.9",
"@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": "100.70.6",
"version": "100.70.9",
"license": "BSD-3-Clause",
"main": "./build/cjs/index.js",
"scripts": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ class D2SectionPlain extends React.PureComponent<Props> {

return (<div
data-test="d2-section"
style={{ overflowX: 'scroll' }}
className={applyCustomFormClass ? this.props.classes.containerCustomForm : ''}
>
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// @flow
/* eslint-disable complexity */
import i18n from '@dhis2/d2-i18n';
import { isEqual } from 'lodash';
import log from 'loglevel';
import { v4 as uuid } from 'uuid';
import * as React from 'react';
Expand Down Expand Up @@ -40,6 +41,7 @@ type FieldUI = {
errorType?: ?string,
errorData?: ErrorData,
validatingMessage?: ?string,
pendingValidation?: ?boolean,
};

type RenderDividerFn = (index: number, fieldsCount: number, field: FieldConfig) => React.Node;
Expand Down Expand Up @@ -108,6 +110,7 @@ export class FormBuilder extends React.Component<Props> {
if (!validators || validators.length === 0) {
return {
valid: true,
pendingValidation: false,
};
}

Expand Down Expand Up @@ -139,11 +142,16 @@ export class FormBuilder extends React.Component<Props> {
errorMessage: validatorResult.message,
errorType: validatorResult.type,
errorData: validatorResult.data,
pendingValidation: false,
};
}

return {
valid: true,
errorMessage: null,
errorType: null,
errorData: null,
pendingValidation: false,
};
}

Expand Down Expand Up @@ -180,17 +188,19 @@ export class FormBuilder extends React.Component<Props> {
}, asyncUIState);
}

static executeValidateAllFields(
static executeValidateFields(
props: Props,
fieldsValidatingPromiseContainer: FieldsValidatingPromiseContainer,
customFields?: Array<FieldConfig>,
) {
const {
id,
fields,
fields: allFields,
values,
onGetValidationContext,
onIsValidating,
} = props;
const fields = customFields || allFields || [];
const validationContext = onGetValidationContext && onGetValidationContext();
const validationPromises = fields
.map(async (field) => {
Expand Down Expand Up @@ -233,6 +243,7 @@ export class FormBuilder extends React.Component<Props> {
valid: false,
errorMessage: [i18n.t('error encountered during field validation')],
errorType: i18n.t('error'),
pendingValidation: false,
};
log.error({ reason, field });
}
Expand Down Expand Up @@ -268,7 +279,7 @@ export class FormBuilder extends React.Component<Props> {
this.commitUpdateTriggeredForFields = {};

if (this.props.validateIfNoUIData) {
this.validateAllFields(this.props);
this.validateFields(this.props);
}
}

Expand All @@ -277,14 +288,27 @@ export class FormBuilder extends React.Component<Props> {
this.asyncUIState = FormBuilder.getAsyncUIState(this.props.fieldsUI);
this.commitUpdateTriggeredForFields = {};
if (this.props.validateIfNoUIData) {
this.validateAllFields(newProps);
this.validateFields(newProps);
}
} else {
this.asyncUIState =
FormBuilder.updateAsyncUIState(this.props.fieldsUI, newProps.fieldsUI, this.asyncUIState);
}
}

componentDidUpdate(prevProps: Props) {
const { fieldsUI, fields } = this.props;

if (!isEqual(prevProps.fieldsUI, fieldsUI)) {
const pendingValidationFields = Object.keys(fieldsUI).filter(key => fieldsUI[key].pendingValidation);

if (pendingValidationFields.length !== 0 && !this.validateAllCancelablePromise) {
const fieldsToValidate = fields.filter(field => pendingValidationFields.includes(field.id));
this.validateFields(this.props, fieldsToValidate);
}
}
}

getCleanUpData() {
const remainingCompleteUids: Array<string> = Object
.keys(this.fieldsValidatingPromiseContainer)
Expand All @@ -300,12 +324,13 @@ export class FormBuilder extends React.Component<Props> {
return remainingCompleteUids;
}

validateAllFields(
validateFields(
props: Props,
customFields?: Array<FieldConfig>,
) {
this.validateAllCancelablePromise && this.validateAllCancelablePromise.cancel();
this.validateAllCancelablePromise = makeCancelablePromise(
FormBuilder.executeValidateAllFields(props, this.fieldsValidatingPromiseContainer),
FormBuilder.executeValidateFields(props, this.fieldsValidatingPromiseContainer, customFields),
);

this.validateAllCancelablePromise
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ type PreEnrollmentDataEntryProps = {
teiId?: ?string,
firstStageMetaData?: ?{ stage: ProgramStage },
formFoundation: RenderFoundation,
enrollmentMetadata: Enrollment,
};

class PreEnrollmentDataEntryPure extends React.PureComponent<Object> {
Expand All @@ -411,6 +412,7 @@ export class EnrollmentDataEntryComponent extends React.Component<PreEnrollmentD
programId,
orgUnitId: orgUnit.id,
trackedEntityInstanceId: teiId,
trackedEntityTypeId: this.props.enrollmentMetadata.trackedEntityType.id,
onGetUnsavedAttributeValues,
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ const RegistrationDataEntryPlain = ({
programId,
}))}
>
{programId ? i18n.t('View enrollment') : i18n.t('View dashboard')}
{i18n.t('View dashboard')}
</Button>
);
}, []);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ const RegisterTeiPlain = ({
onCancel,
onGetUnsavedAttributeValues,
trackedEntityName,
trackedEntityTypeId,
newRelationshipProgramId,
classes,
}: Props) => {
Expand Down Expand Up @@ -111,6 +112,7 @@ const RegisterTeiPlain = ({
renderDuplicatesDialogActions={renderDuplicatesDialogActions}
renderDuplicatesCardActions={renderDuplicatesCardActions}
ExistingUniqueValueDialogActions={ExistingUniqueValueDialogActions}
trackedEntityTypeId={trackedEntityTypeId}
/>
</div>
<DataEntryWidgetOutput
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const RegisterTei = ({ onLink, onSave, onCancel, onGetUnsavedAttributeVal
const itemId = useSelector(({ dataEntries }) => dataEntries[dataEntryId]?.itemId);
const error = useSelector(({ newRelationshipRegisterTei }) => (newRelationshipRegisterTei.error));
const newRelationshipProgramId = useNewRelationshipScopeId();
const { trackedEntityName } = useScopeInfo(newRelationshipProgramId);
const { trackedEntityName, tetId: trackedEntityTypeId } = useScopeInfo(newRelationshipProgramId);

return (
<RegisterTeiComponent
Expand All @@ -33,6 +33,7 @@ export const RegisterTei = ({ onLink, onSave, onCancel, onGetUnsavedAttributeVal
onCancel={onCancel}
onGetUnsavedAttributeValues={onGetUnsavedAttributeValues}
trackedEntityName={trackedEntityName}
trackedEntityTypeId={trackedEntityTypeId}
newRelationshipProgramId={newRelationshipProgramId}
error={error}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ type PropsFromRedux = {|
dataEntryId: string,
itemId: string,
trackedEntityName: ?string,
trackedEntityTypeId: ?string,
newRelationshipProgramId: string,
error: string,
|};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const actionTypes = {
TEI_EDIT_SEARCH: 'RelationshipsWidget.TeiEditSearch',
TEI_SEARCH_RESULTS_CHANGE_PAGE: 'RelationshipsWidget.TeiSearchResultsChangePage',
TEI_SEARCH_SET_OPEN_SEARCH_GROUP_SECTION: 'RelationshipsWidget.TeiSearchSetOpenSearchGroupSection',
SEARCH_TE_IN_TET_SCOPE: 'RelationshipsWidget.SearchTrackedEntityInTETScope',
};


Expand All @@ -32,6 +33,27 @@ export const requestSearchTei = (
) =>
actionCreator(actionTypes.REQUEST_SEARCH_TEI)({ formId, searchGroupId, searchId, resultsPageSize });

export const searchViaUniqueIdOnScopeTrackedEntityType = ({
formId,
searchGroupId,
searchId,
selectedProgramId,
programQueryArgs,
}: {
formId: string,
searchGroupId: string,
searchId: string,
selectedProgramId: string,
programQueryArgs: any,
}) =>
actionCreator(actionTypes.SEARCH_TE_IN_TET_SCOPE)({
formId,
searchGroupId,
searchId,
selectedProgramId,
programQueryArgs,
});

export const searchTeiFailed = (
formId: string,
searchGroupId: string,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
searchTeiResultRetrieved,
searchTeiFailed,
setProgramAndTrackedEntityType,
searchViaUniqueIdOnScopeTrackedEntityType,
} from '../actions/teiSearch.actions';
import {
actionTypes as programSelectorActionTypes,
Expand Down Expand Up @@ -43,6 +44,32 @@ const getContextQueryArgs = (programId: ?string, trackedEntityTypeId: string) =>

const getPagingQueryArgs = (pageNumber: ?number = 1) => ({ page: pageNumber, pageSize: 5 });

export const searchTeiByTETIdEpic = (
action$: InputObservable,
store: ReduxStore,
{ absoluteApiPath, querySingleResource }: ApiUtils,
) =>
action$.pipe(
ofType(actionTypes.SEARCH_TE_IN_TET_SCOPE),
switchMap((action) => {
const { selectedProgramId, searchId, formId, searchGroupId, programQueryArgs } = action.payload;
const { attributes, trackedEntityType } = getTrackerProgram(selectedProgramId);
const { program, ...restQueryArgs } = programQueryArgs;
const queryArgs = { ...restQueryArgs, trackedEntityType: trackedEntityType.id };
return from(getTrackedEntityInstances(queryArgs, attributes, absoluteApiPath, querySingleResource)).pipe(
map(
({ trackedEntityInstanceContainers, pagingData }) =>
searchTeiResultRetrieved(
{ trackedEntityInstanceContainers, currentPage: pagingData.currentPage },
formId,
searchGroupId,
searchId,
),
catchError(() => of(searchTeiFailed(formId, searchGroupId, searchId))),
),
);
}),
);

const searchTei = ({
state,
Expand Down Expand Up @@ -100,16 +127,25 @@ const searchTei = ({
getTrackerProgram(selectedProgramId).attributes :
getTrackedEntityType(selectedTrackedEntityTypeId).attributes;

return from(
getTrackedEntityInstances(queryArgs, attributes, absoluteApiPath, querySingleResource, selectedProgramId),
).pipe(
map(({ trackedEntityInstanceContainers, pagingData }) =>
searchTeiResultRetrieved(
return from(getTrackedEntityInstances(queryArgs, attributes, absoluteApiPath, querySingleResource, selectedProgramId)).pipe(
map(({ trackedEntityInstanceContainers, pagingData }) => {
if (searchGroup.unique && trackedEntityInstanceContainers.length === 0 && queryArgs.program) {
return searchViaUniqueIdOnScopeTrackedEntityType({
selectedProgramId,
searchId,
formId,
searchGroupId,
programQueryArgs: queryArgs,
});
}

return searchTeiResultRetrieved(
{ trackedEntityInstanceContainers, currentPage: pagingData.currentPage },
formId,
searchGroupId,
searchId,
)),
);
}),
catchError(() => of(searchTeiFailed(formId, searchGroupId, searchId))),
);
};
Expand Down
Loading

0 comments on commit 63403f9

Please sign in to comment.