Skip to content

Commit da15a0c

Browse files
committed
feat: refactor event edit permissions and authority management
1 parent a9d409e commit da15a0c

23 files changed

Lines changed: 111 additions & 155 deletions

File tree

i18n/en.pot

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ msgstr ""
55
"Content-Type: text/plain; charset=utf-8\n"
66
"Content-Transfer-Encoding: 8bit\n"
77
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
8-
"POT-Creation-Date: 2026-08-13T14:51:01.572Z\n"
9-
"PO-Revision-Date: 2026-08-13T14:51:01.572Z\n"
8+
"POT-Creation-Date: 2026-08-14T16:34:23.443Z\n"
9+
"PO-Revision-Date: 2026-08-14T16:34:23.443Z\n"
1010

1111
msgid "The application could not be loaded."
1212
msgstr "The application could not be loaded."

src/core_modules/capture-core/components/EventOverflowMenu/MenuItems/DeleteMenuItem.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export const DeleteActionButton = ({
3636
const { isWithinValidPeriod: isEventWithinValidPeriod } = isValidPeriod(occurredAtClient, expiryPeriod ?? null);
3737

3838
const {
39-
canEditCompletedEvent,
39+
isFormBlockedByCompletion,
4040
canEditEvent,
4141
} = useEventEditPermissions({
4242
programId,
@@ -53,7 +53,7 @@ export const DeleteActionButton = ({
5353
interpolation: { escapeValue: false },
5454
});
5555
}
56-
if (!canEditCompletedEvent) {
56+
if (isFormBlockedByCompletion) {
5757
return i18n.t('This event has been completed');
5858
}
5959
return i18n.t('This event is outside the edit period');

src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/EnrollmentEditEventPage.container.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,8 @@ const EnrollmentEditEventPageWithContextPlain = ({
268268

269269
const eventAccess = getProgramEventAccess(programId, stageId ?? null);
270270
const {
271-
canEditExpiredEvent,
272-
canEditCompletedEvent,
271+
isEventBlockedByExpiry,
272+
isFormBlockedByCompletion,
273273
} = useEventEditPermissions({
274274
programId,
275275
stage: programStage,
@@ -312,8 +312,8 @@ const EnrollmentEditEventPageWithContextPlain = ({
312312
program={program}
313313
currentStageId={stageId}
314314
trackedEntityInactive={trackedEntityInactive}
315-
canEditExpiredEvent={canEditExpiredEvent}
316-
canEditCompletedEvent={canEditCompletedEvent}
315+
isEventBlockedByExpiry={isEventBlockedByExpiry}
316+
isFormBlockedByCompletion={isFormBlockedByCompletion}
317317
>
318318
<EnrollmentEditEventPageComponent
319319
pageLayout={pageLayout}

src/core_modules/capture-core/components/Pages/ViewEvent/ViewEventComponent/ViewEvent.component.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ export const ViewEventPlain = (props: Props & WithStyles<typeof getStyles>) => {
9898
const completedAt = useSelector((state: any) => state.viewEventPage.loadedValues?.eventContainer?.event?.completedAt);
9999

100100
const {
101-
canEditExpiredEvent,
102-
canEditCompletedEvent,
101+
isEventBlockedByExpiry,
102+
isFormBlockedByCompletion,
103103
canEditEvent,
104104
} = useEventEditPermissions({
105105
programId,
@@ -122,8 +122,8 @@ export const ViewEventPlain = (props: Props & WithStyles<typeof getStyles>) => {
122122
/>
123123
<ViewEventReadOnlyBadge
124124
eventAccess={eventAccess}
125-
canEditExpiredEvent={canEditExpiredEvent}
126-
canEditCompletedEvent={canEditCompletedEvent}
125+
isEventBlockedByExpiry={isEventBlockedByExpiry}
126+
isFormBlockedByCompletion={isFormBlockedByCompletion}
127127
/>
128128
</div>
129129
<div className={classes.contentContainer}>

src/core_modules/capture-core/components/Pages/ViewEvent/ViewEventReadOnlyBadge/ViewEventReadOnlyBadge.component.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@ import { ReadOnlyBadge } from '../../../ReadOnlyBadge';
33

44
type Props = {
55
eventAccess: { read: boolean; write: boolean };
6-
canEditExpiredEvent: boolean;
7-
canEditCompletedEvent: boolean;
6+
isEventBlockedByExpiry: boolean;
7+
isFormBlockedByCompletion: boolean;
88
};
99

1010
export const ViewEventReadOnlyBadge = ({
1111
eventAccess,
12-
canEditExpiredEvent,
13-
canEditCompletedEvent,
12+
isEventBlockedByExpiry,
13+
isFormBlockedByCompletion,
1414
}: Props) => (
1515
<ReadOnlyBadge
1616
programWriteAccess={eventAccess.write}
17-
canEditExpiredEvent={canEditExpiredEvent}
18-
canEditCompletedEvent={canEditCompletedEvent}
17+
isEventBlockedByExpiry={isEventBlockedByExpiry}
18+
isFormBlockedByCompletion={isFormBlockedByCompletion}
1919
inlineLabel
2020
/>
2121
);

src/core_modules/capture-core/components/Pages/common/EnrollmentOverviewDomain/EnrollmentAccessContext/EnrollmentAccessContext.tsx

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ export type EnrollmentAccessContextValue = {
1818
showWidgetBadge: boolean;
1919
trackedEntityInactive: boolean;
2020
canToggleTrackedEntityStatus: boolean;
21-
canEditExpiredEvent?: boolean;
22-
canEditCompletedEvent?: boolean;
21+
isEventBlockedByExpiry?: boolean;
22+
isFormBlockedByCompletion?: boolean;
2323
};
2424

2525
const fallback: EnrollmentAccessContextValue = {
@@ -44,8 +44,8 @@ type ProviderProps = {
4444
program?: TrackerProgram;
4545
currentStageId?: string;
4646
trackedEntityInactive?: boolean;
47-
canEditExpiredEvent?: boolean;
48-
canEditCompletedEvent?: boolean;
47+
isEventBlockedByExpiry?: boolean;
48+
isFormBlockedByCompletion?: boolean;
4949
children: React.ReactNode;
5050
};
5151

@@ -64,8 +64,8 @@ const computeContextValue = (
6464
program: TrackerProgram,
6565
currentStageId: string | undefined,
6666
trackedEntityInactive: boolean,
67-
canEditExpiredEvent?: boolean,
68-
canEditCompletedEvent?: boolean,
67+
isEventBlockedByExpiry?: boolean,
68+
isFormBlockedByCompletion?: boolean,
6969
): EnrollmentAccessContextValue => {
7070
const { rawStageWriteAccessById, stageReadAccessById } = buildStageAccessMaps(program);
7171
const rawProgramWriteAccess = Boolean(program.access?.data?.write);
@@ -98,17 +98,17 @@ const computeContextValue = (
9898
showWidgetBadge: !isEventPage && !allWriteAccessMissing,
9999
trackedEntityInactive,
100100
canToggleTrackedEntityStatus: rawTrackedEntityTypeWriteAccess,
101-
canEditExpiredEvent,
102-
canEditCompletedEvent,
101+
isEventBlockedByExpiry,
102+
isFormBlockedByCompletion,
103103
};
104104
};
105105

106106
export const EnrollmentAccessProvider = ({
107107
program,
108108
currentStageId,
109109
trackedEntityInactive = false,
110-
canEditExpiredEvent,
111-
canEditCompletedEvent,
110+
isEventBlockedByExpiry,
111+
isFormBlockedByCompletion,
112112
children,
113113
}: ProviderProps) => {
114114
const value = useMemo<EnrollmentAccessContextValue>(
@@ -117,8 +117,8 @@ export const EnrollmentAccessProvider = ({
117117
program,
118118
currentStageId,
119119
trackedEntityInactive,
120-
canEditExpiredEvent,
121-
canEditCompletedEvent,
120+
isEventBlockedByExpiry,
121+
isFormBlockedByCompletion,
122122
)
123123
: {
124124
...fallback,
@@ -136,8 +136,8 @@ export const EnrollmentAccessProvider = ({
136136
program,
137137
currentStageId,
138138
trackedEntityInactive,
139-
canEditExpiredEvent,
140-
canEditCompletedEvent,
139+
isEventBlockedByExpiry,
140+
isFormBlockedByCompletion,
141141
],
142142
);
143143

src/core_modules/capture-core/components/Pages/common/EnrollmentOverviewDomain/EnrollmentPageLayout/EnrollmentReadOnlyBadge/EnrollmentReadOnlyBadge.component.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,16 @@ export const EnrollmentReadOnlyBadge = () => {
1212
anyStageReadAccess,
1313
trackedEntityTypeName,
1414
trackedEntityInactive,
15-
canEditExpiredEvent,
16-
canEditCompletedEvent,
15+
isEventBlockedByExpiry,
16+
isFormBlockedByCompletion,
1717
} = useEnrollmentAccessContext();
1818

1919
if (isEventPage) {
2020
return (
2121
<ReadOnlyBadge
2222
programStageWriteAccess={currentStageWriteAccess}
23-
canEditExpiredEvent={canEditExpiredEvent}
24-
canEditCompletedEvent={canEditCompletedEvent}
23+
isEventBlockedByExpiry={isEventBlockedByExpiry}
24+
isFormBlockedByCompletion={isFormBlockedByCompletion}
2525
trackedEntityName={trackedEntityTypeName}
2626
trackedEntityInactive={trackedEntityInactive}
2727
inlineLabel

src/core_modules/capture-core/components/ReadOnlyBadge/ReadOnlyBadge.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,26 +36,26 @@ const getReadOnlyMessage = ({
3636
access,
3737
trackedEntityName,
3838
multipleStages,
39-
canEditExpiredEvent,
40-
canEditCompletedEvent,
39+
isEventBlockedByExpiry,
40+
isFormBlockedByCompletion,
4141
trackedEntityInactive,
4242
}: ReadOnlyMessageInput): string => {
4343
if (trackedEntityInactive) return getDeactivatedMessage(trackedEntityName);
4444
if (!access.program && !access.trackedEntityType && !access.programStage) return getEnrollmentMessage();
4545
if (!access.program) return getProgramMessage();
4646
if (!access.trackedEntityType) return getTrackedEntityMessage(trackedEntityName);
4747
if (!access.programStage) return getProgramStageMessage(multipleStages);
48-
if (!canEditExpiredEvent) return getExpiredMessage();
49-
if (!canEditCompletedEvent) return getCompletedEventMessage();
48+
if (isEventBlockedByExpiry) return getExpiredMessage();
49+
if (isFormBlockedByCompletion) return getCompletedEventMessage();
5050
return '';
5151
};
5252

5353
const ReadOnlyBadgePlain = ({
5454
programWriteAccess = true,
5555
trackedEntityTypeWriteAccess = true,
5656
programStageWriteAccess = true,
57-
canEditExpiredEvent = true,
58-
canEditCompletedEvent = true,
57+
isEventBlockedByExpiry = false,
58+
isFormBlockedByCompletion = false,
5959
multipleStages = false,
6060
trackedEntityName,
6161
trackedEntityInactive = false,
@@ -71,8 +71,8 @@ const ReadOnlyBadgePlain = ({
7171
access,
7272
trackedEntityName,
7373
multipleStages,
74-
canEditExpiredEvent,
75-
canEditCompletedEvent,
74+
isEventBlockedByExpiry,
75+
isFormBlockedByCompletion,
7676
trackedEntityInactive,
7777
});
7878
if (!message) return null;

src/core_modules/capture-core/components/ReadOnlyBadge/ReadOnlyBadge.types.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ export type Props = {
22
programWriteAccess?: boolean;
33
trackedEntityTypeWriteAccess?: boolean;
44
programStageWriteAccess?: boolean;
5-
canEditExpiredEvent?: boolean;
6-
canEditCompletedEvent?: boolean;
5+
isEventBlockedByExpiry?: boolean;
6+
isFormBlockedByCompletion?: boolean;
77
multipleStages?: boolean;
88
trackedEntityName?: string;
99
trackedEntityInactive?: boolean;
@@ -20,7 +20,7 @@ export type ReadOnlyMessageInput = {
2020
access: Access;
2121
trackedEntityName: string | undefined;
2222
multipleStages: boolean;
23-
canEditExpiredEvent: boolean;
24-
canEditCompletedEvent: boolean;
23+
isEventBlockedByExpiry: boolean;
24+
isFormBlockedByCompletion: boolean;
2525
trackedEntityInactive: boolean;
2626
};

src/core_modules/capture-core/components/WidgetEnrollment/Actions/Actions.container.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import { ActionsComponent } from './Actions.component';
33
import type { Props } from './actions.types';
44
import { useUpdateEnrollment, useDeleteEnrollment } from '../dataMutation/dataMutation';
55
import { useUpdateOwnership } from './Transfer/hooks';
6-
import { useAuthorities } from '../../../utils/authority/useAuthorities';
6+
import { useAuthority } from '../../../utils/authority/useAuthority';
7+
import { Authorities } from '../../../utils/authority/authorities';
78

89
export const Actions = ({
910
enrollment = {},
@@ -21,7 +22,7 @@ export const Actions = ({
2122
}: Props) => {
2223
const { updateMutation, updateLoading } = useUpdateEnrollment(refetchEnrollment, refetchTEI, onError, onSuccess);
2324
const { deleteMutation, deleteLoading } = useDeleteEnrollment(onDelete, onError, onSuccess);
24-
const { hasAuthority } = useAuthorities({ authorities: ['F_ENROLLMENT_CASCADE_DELETE'] });
25+
const { hasAuthority } = useAuthority(Authorities.ENROLLMENT_CASCADE_DELETE);
2526
const { updateEnrollmentOwnership, isTransferLoading } = useUpdateOwnership({
2627
teiId: enrollment.trackedEntity,
2728
programId: enrollment.program,

0 commit comments

Comments
 (0)