void,
-|}>;
-
-export type PlainProps = $ReadOnly<{|
- ...PassOnProps,
setShowAccessible: () => void,
MainPageStatus: boolean,
selectedTemplateId: string,
- showMainPage: boolean,
- ...CssClasses,
-|}>;
-
-export type Props = $ReadOnly<{|
- ...PassOnProps,
- ...PlainProps,
error: boolean,
ready: boolean,
- trackedEntityTypeId?: string,
- displayFrontPageList?: boolean,
- selectedCategories: ?{ [categoryId: string]: { writeAccess: boolean } },
+|}
+>;
+
+export type Props = $ReadOnly<{|
+ ...ContainerProps,
+ ...CssClasses
|}>;
diff --git a/src/core_modules/capture-core/components/Pages/New/NewPage.component.js b/src/core_modules/capture-core/components/Pages/New/NewPage.component.js
index a7b070193b..35939b44f6 100644
--- a/src/core_modules/capture-core/components/Pages/New/NewPage.component.js
+++ b/src/core_modules/capture-core/components/Pages/New/NewPage.component.js
@@ -7,7 +7,7 @@ import withStyles from '@material-ui/core/styles/withStyles';
import { OrgUnitFetcher } from 'capture-core/components/OrgUnitFetcher';
import i18n from '@dhis2/d2-i18n';
import { Button } from '@dhis2/ui';
-import { TopBar } from './TopBar.container';
+
import type { ContainerProps, Props } from './NewPage.types';
import { withErrorMessageHandler, withLoadingIndicator } from '../../../HOC';
import { NEW_TEI_DATA_ENTRY_ID, newPageStatuses } from './NewPage.constants';
@@ -36,11 +36,7 @@ const NewPagePlain = ({
categoryOptionIsInvalidForOrgUnit,
missingCategoriesInProgramSelection,
orgUnitSelectionIncomplete,
- isUserInteractionInProgress,
- programId,
- teiId,
trackedEntityName,
- teiDisplayName,
trackedEntityInstanceAttributes,
}: Props) => {
const { scopeType } = useScopeInfo(currentScopeId);
@@ -72,16 +68,7 @@ const NewPagePlain = ({
]);
const orgUnitId = useSelector(({ currentSelections }) => currentSelections.orgUnitId);
- return (<>
-
+ return (
{
!writeAccess ?
@@ -154,7 +141,7 @@ const NewPagePlain = ({
}
- >);
+ );
};
export const NewPageComponent: ComponentType
=
diff --git a/src/core_modules/capture-core/components/Pages/New/NewPage.container.js b/src/core_modules/capture-core/components/Pages/New/NewPage.container.js
index 8ea87c19e2..4286ee2c70 100644
--- a/src/core_modules/capture-core/components/Pages/New/NewPage.container.js
+++ b/src/core_modules/capture-core/components/Pages/New/NewPage.container.js
@@ -9,7 +9,7 @@ import {
showDefaultViewOnNewPage,
showMessageToSelectProgramCategoryOnNewPage, showMessageThatCategoryOptionIsInvalidForOrgUnit,
} from './NewPage.actions';
-import { typeof newPageStatuses } from './NewPage.constants';
+import { newPageStatuses } from './NewPage.constants';
import { buildUrlQueryString, useLocationQuery } from '../../../utils/routing';
import { getScopeFromScopeId, TrackerProgram, TrackedEntityType } from '../../../metaData';
import { useMissingCategoriesInProgramSelection } from '../../../hooks/useMissingCategoriesInProgramSelection';
@@ -18,6 +18,7 @@ import { useTrackedEntityInstances } from './hooks';
import { deriveTeiName } from '../common/EnrollmentOverviewDomain/useTeiDisplayName';
import { programCollection } from '../../../metaDataMemoryStores/programCollection/programCollection';
import { useCategoryOptionIsValidForOrgUnit } from '../../../hooks/useCategoryComboIsValidForOrgUnit';
+import { TopBar } from './TopBar.container';
const useUserWriteAccess = (scopeId) => {
const scope = getScopeFromScopeId(scopeId);
@@ -89,7 +90,7 @@ export const NewPage: ComponentType<{||}> = () => {
({ currentSelections }) => !currentSelections.orgUnitId && !currentSelections.complete,
);
- const newPageStatus: $Keys =
+ const newPageStatus: $Keys =
useSelector(({ newPage }) => newPage.newPageStatus);
const handleMainPageNavigation = () => {
@@ -108,26 +109,34 @@ export const NewPage: ComponentType<{||}> = () => {
);
return (
- );
+ <>
+
+
+ >
+ );
};
diff --git a/src/core_modules/capture-core/components/Pages/New/NewPage.types.js b/src/core_modules/capture-core/components/Pages/New/NewPage.types.js
index 438b61a88f..9004f99945 100644
--- a/src/core_modules/capture-core/components/Pages/New/NewPage.types.js
+++ b/src/core_modules/capture-core/components/Pages/New/NewPage.types.js
@@ -29,7 +29,6 @@ export type ContainerProps = $ReadOnly<{|
writeAccess: boolean,
error: boolean,
ready: boolean,
- isUserInteractionInProgress: boolean,
programId?: string,
teiId?: string,
trackedEntityName?: string,
diff --git a/src/core_modules/capture-core/components/Pages/NewRelationship/RegisterTei/RegistrationSection/RegUnitSelector/RegUnitSelector.component.js b/src/core_modules/capture-core/components/Pages/NewRelationship/RegisterTei/RegistrationSection/RegUnitSelector/RegUnitSelector.component.js
index ea39476d43..fc4f52cfa5 100644
--- a/src/core_modules/capture-core/components/Pages/NewRelationship/RegisterTei/RegistrationSection/RegUnitSelector/RegUnitSelector.component.js
+++ b/src/core_modules/capture-core/components/Pages/NewRelationship/RegisterTei/RegistrationSection/RegUnitSelector/RegUnitSelector.component.js
@@ -47,7 +47,7 @@ class RegUnitSelectorPlain extends React.Component {
return;
}
- onUpdateSelectedOrgUnit(orgUnit, program.organisationUnits ? !program.organisationUnits[orgUnit.id] : false);
+ onUpdateSelectedOrgUnit(orgUnit, program?.organisationUnits ? !program.organisationUnits[orgUnit.id] : false);
}
render() {
diff --git a/src/core_modules/capture-core/components/Pages/ViewEvent/epics/getCategoriesDataFromEvent.js b/src/core_modules/capture-core/components/Pages/ViewEvent/epics/getCategoriesDataFromEvent.js
index c3609baa25..1f98cf8bcd 100644
--- a/src/core_modules/capture-core/components/Pages/ViewEvent/epics/getCategoriesDataFromEvent.js
+++ b/src/core_modules/capture-core/components/Pages/ViewEvent/epics/getCategoriesDataFromEvent.js
@@ -25,7 +25,7 @@ export async function getCategoriesDataFromEventAsync(
const program = getProgramFromProgramIdThrowIfNotFound(event.programId);
- const categoryCombination = program.categoryCombination;
+ const categoryCombination = program?.categoryCombination;
if (!categoryCombination) {
return null;
}
diff --git a/src/core_modules/capture-core/components/Pages/common/TEIRelationshipsWidget/RegisterTei/RegistrationSection/RegUnitSelector/RegUnitSelector.component.js b/src/core_modules/capture-core/components/Pages/common/TEIRelationshipsWidget/RegisterTei/RegistrationSection/RegUnitSelector/RegUnitSelector.component.js
index e75b8513ea..42cba9027f 100644
--- a/src/core_modules/capture-core/components/Pages/common/TEIRelationshipsWidget/RegisterTei/RegistrationSection/RegUnitSelector/RegUnitSelector.component.js
+++ b/src/core_modules/capture-core/components/Pages/common/TEIRelationshipsWidget/RegisterTei/RegistrationSection/RegUnitSelector/RegUnitSelector.component.js
@@ -47,7 +47,7 @@ class RegUnitSelectorPlain extends React.Component {
return;
}
- onUpdateSelectedOrgUnit(orgUnit, program.organisationUnits ? !program.organisationUnits[orgUnit.id] : false);
+ onUpdateSelectedOrgUnit(orgUnit, program?.organisationUnits ? !program.organisationUnits[orgUnit.id] : false);
}
render() {
diff --git a/src/core_modules/capture-core/components/ScopeSelector/QuickSelector/QuickSelector.types.js b/src/core_modules/capture-core/components/ScopeSelector/QuickSelector/QuickSelector.types.js
index 3b8451471c..148a0b7bfd 100644
--- a/src/core_modules/capture-core/components/ScopeSelector/QuickSelector/QuickSelector.types.js
+++ b/src/core_modules/capture-core/components/ScopeSelector/QuickSelector/QuickSelector.types.js
@@ -3,7 +3,7 @@ import type { Node } from 'react';
export type Props = {
selectedOrgUnitId?: string,
- selectedProgramId?: string,
+ selectedProgramId?: ?string,
selectedCategories: Object,
selectedOrgUnit: Object,
previousOrgUnitId?: string,
diff --git a/src/core_modules/capture-core/components/ScopeSelector/ScopeSelector.types.js b/src/core_modules/capture-core/components/ScopeSelector/ScopeSelector.types.js
index e92d91a8a2..09faa0ece8 100644
--- a/src/core_modules/capture-core/components/ScopeSelector/ScopeSelector.types.js
+++ b/src/core_modules/capture-core/components/ScopeSelector/ScopeSelector.types.js
@@ -5,7 +5,7 @@ export type OwnProps = $ReadOnly<{|
isUserInteractionInProgress?: boolean,
pageToPush?: string,
selectedOrgUnitId?: string,
- selectedProgramId?: string,
+ selectedProgramId?: ?string,
previousOrgUnitId?: string,
selectedCategories?: { [categoryId: string]: { writeAccess: boolean } },
onSetProgramId?: (id: string) => void,
diff --git a/src/core_modules/capture-core/components/TopBarActions/TopBarActions.types.js b/src/core_modules/capture-core/components/TopBarActions/TopBarActions.types.js
index 0f13e109f2..249ab2faa9 100644
--- a/src/core_modules/capture-core/components/TopBarActions/TopBarActions.types.js
+++ b/src/core_modules/capture-core/components/TopBarActions/TopBarActions.types.js
@@ -1,13 +1,13 @@
// @flow
export type Props = {
- selectedProgramId?: string,
+ selectedProgramId?: ?string,
selectedOrgUnitId?: string,
isUserInteractionInProgress?: boolean,
};
export type PlainProps = {
- selectedProgramId?: string,
+ selectedProgramId?: ?string,
onNewClick: () => void,
onNewClickWithoutProgramId: () => void,
onFindClick: () => void,
diff --git a/src/core_modules/capture-core/components/WidgetEnrollment/Actions/Actions.component.js b/src/core_modules/capture-core/components/WidgetEnrollment/Actions/Actions.component.js
index d95f39c8fb..e3e08de57d 100644
--- a/src/core_modules/capture-core/components/WidgetEnrollment/Actions/Actions.component.js
+++ b/src/core_modules/capture-core/components/WidgetEnrollment/Actions/Actions.component.js
@@ -39,6 +39,7 @@ export const ActionsPlain = ({
onUpdate,
onDelete,
onUpdateOwnership,
+ canCascadeDeleteEnrollment,
isTransferLoading,
onAddNew,
loading,
@@ -115,6 +116,7 @@ export const ActionsPlain = ({
onUpdate={handleOnUpdateStatus}
/>
diff --git a/src/core_modules/capture-core/components/WidgetEnrollment/Actions/Actions.container.js b/src/core_modules/capture-core/components/WidgetEnrollment/Actions/Actions.container.js
index 79df428da7..b7ad956d52 100644
--- a/src/core_modules/capture-core/components/WidgetEnrollment/Actions/Actions.container.js
+++ b/src/core_modules/capture-core/components/WidgetEnrollment/Actions/Actions.container.js
@@ -4,6 +4,7 @@ import { ActionsComponent } from './Actions.component';
import type { Props } from './actions.types';
import { useUpdateEnrollment, useDeleteEnrollment } from '../dataMutation/dataMutation';
import { useUpdateOwnership } from './Transfer/hooks';
+import { useAuthorities } from '../../../utils/authority/useAuthorities';
export const Actions = ({
enrollment = {},
@@ -20,6 +21,7 @@ export const Actions = ({
}: Props) => {
const { updateMutation, updateLoading } = useUpdateEnrollment(refetchEnrollment, refetchTEI, onError, onSuccess);
const { deleteMutation, deleteLoading } = useDeleteEnrollment(onDelete, onError, onSuccess);
+ const { hasAuthority } = useAuthorities({ authorities: ['F_ENROLLMENT_CASCADE_DELETE'] });
const { updateEnrollmentOwnership, isTransferLoading } = useUpdateOwnership({
teiId: enrollment.trackedEntity,
programId: enrollment.program,
@@ -52,6 +54,7 @@ export const Actions = ({
onUpdate={updateMutation}
onUpdateStatus={handleUpdateStatus}
onDelete={deleteMutation}
+ canCascadeDeleteEnrollment={hasAuthority}
loading={updateLoading || deleteLoading || updateStatusLoading}
onUpdateOwnership={updateEnrollmentOwnership}
isTransferLoading={isTransferLoading}
diff --git a/src/core_modules/capture-core/components/WidgetEnrollment/Actions/Delete/Delete.component.js b/src/core_modules/capture-core/components/WidgetEnrollment/Actions/Delete/Delete.component.js
index d301326dc7..f870ed9197 100644
--- a/src/core_modules/capture-core/components/WidgetEnrollment/Actions/Delete/Delete.component.js
+++ b/src/core_modules/capture-core/components/WidgetEnrollment/Actions/Delete/Delete.component.js
@@ -1,4 +1,5 @@
// @flow
+import React, { useState } from 'react';
import {
IconDelete16,
MenuItem,
@@ -9,18 +10,21 @@ import {
ButtonStrip,
Button,
} from '@dhis2/ui';
-import React, { useState } from 'react';
import i18n from '@dhis2/d2-i18n';
import type { Props } from './delete.types';
+import { ConditionalTooltip } from '../../../Tooltips/ConditionalTooltip/';
-export const Delete = ({ enrollment, onDelete }: Props) => {
+export const Delete = ({ canCascadeDeleteEnrollment, enrollment, onDelete }: Props) => {
const [toggle, setToggle] = useState(false);
+ const disabled = !canCascadeDeleteEnrollment;
+ const tooltipContent = i18n.t('You do not have access to delete this enrollment');
return (
-
+
}
destructive
label={i18n.t('Delete')}
@@ -54,6 +58,6 @@ export const Delete = ({ enrollment, onDelete }: Props) => {
)}
-
+
);
};
diff --git a/src/core_modules/capture-core/components/WidgetEnrollment/Actions/Delete/delete.types.js b/src/core_modules/capture-core/components/WidgetEnrollment/Actions/Delete/delete.types.js
index 7cd649b391..71b637983f 100644
--- a/src/core_modules/capture-core/components/WidgetEnrollment/Actions/Delete/delete.types.js
+++ b/src/core_modules/capture-core/components/WidgetEnrollment/Actions/Delete/delete.types.js
@@ -1,6 +1,7 @@
// @flow
export type Props = {|
+ canCascadeDeleteEnrollment: boolean,
enrollment: Object,
onDelete: (arg: Object) => void,
|};
diff --git a/src/core_modules/capture-core/components/WidgetEnrollment/Actions/actions.types.js b/src/core_modules/capture-core/components/WidgetEnrollment/Actions/actions.types.js
index e6da45629d..b40adc2282 100644
--- a/src/core_modules/capture-core/components/WidgetEnrollment/Actions/actions.types.js
+++ b/src/core_modules/capture-core/components/WidgetEnrollment/Actions/actions.types.js
@@ -32,6 +32,7 @@ export type PlainProps = {|
onDelete: (arg: Object) => void,
onAddNew: (arg: Object) => void,
onUpdateOwnership: UpdateEnrollmentOwnership,
+ canCascadeDeleteEnrollment: boolean,
isTransferLoading: boolean,
loading: boolean,
canAddNew: boolean,
diff --git a/src/core_modules/capture-core/components/WidgetEnrollment/WidgetEnrollment.component.js b/src/core_modules/capture-core/components/WidgetEnrollment/WidgetEnrollment.component.js
index 00c44c0a6e..1cd597f02d 100644
--- a/src/core_modules/capture-core/components/WidgetEnrollment/WidgetEnrollment.component.js
+++ b/src/core_modules/capture-core/components/WidgetEnrollment/WidgetEnrollment.component.js
@@ -136,7 +136,9 @@ export const WidgetEnrollmentPlain = ({
- {i18n.t('Started at: ')}
+ {i18n.t('Started at{{escape}}', {
+ escape: ':',
+ })}
{convertValue(orgUnitClientValue, type)}
@@ -144,7 +146,9 @@ export const WidgetEnrollmentPlain = ({