diff --git a/i18n/en.pot b/i18n/en.pot
index 3bee26bc80..5fb403e3d7 100644
--- a/i18n/en.pot
+++ b/i18n/en.pot
@@ -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: 2024-10-14T14:53:34.553Z\n"
-"PO-Revision-Date: 2024-10-14T14:53:34.553Z\n"
+"POT-Creation-Date: 2024-10-25T18:18:11.518Z\n"
+"PO-Revision-Date: 2024-10-25T18:18:11.518Z\n"
msgid "Choose one or more dates..."
msgstr "Choose one or more dates..."
@@ -1133,6 +1133,9 @@ msgstr "Mark as cancelled"
msgid "Mark incomplete"
msgstr "Mark incomplete"
+msgid "You do not have access to delete this enrollment"
+msgstr "You do not have access to delete this enrollment"
+
msgid "Delete enrollment"
msgstr "Delete enrollment"
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/WidgetEventEdit/WidgetEventEdit.container.js b/src/core_modules/capture-core/components/WidgetEventEdit/WidgetEventEdit.container.js
index f953852223..b39bb89c7c 100644
--- a/src/core_modules/capture-core/components/WidgetEventEdit/WidgetEventEdit.container.js
+++ b/src/core_modules/capture-core/components/WidgetEventEdit/WidgetEventEdit.container.js
@@ -32,7 +32,7 @@ import { EventChangelogWrapper } from './EventChangelogWrapper';
import { FEATURES, useFeature } from '../../../capture-core-utils';
import { inMemoryFileStore } from '../DataEntry/file/inMemoryFileStore';
import { eventStatuses } from './constants/status.const';
-import { useAuthorities } from './hooks';
+import { useAuthorities } from '../../utils/authority/useAuthorities';
const styles = {
header: {
@@ -101,8 +101,8 @@ export const WidgetEventEditPlain = ({
const loadedValues = useSelector(({ viewEventPage }) => viewEventPage.loadedValues);
const eventAccess = getProgramEventAccess(programId, stageId);
- const { canEditCompletedEvent } = useAuthorities();
- const blockEntryForm = stage.blockEntryForm && !canEditCompletedEvent && eventStatus === eventStatuses.COMPLETED;
+ const { hasAuthority } = useAuthorities({ authorities: ['F_UNCOMPLETE_EVENT'] });
+ const blockEntryForm = stage.blockEntryForm && !hasAuthority && eventStatus === eventStatuses.COMPLETED;
const disableEdit = !eventAccess?.write || blockEntryForm;
const tooltipContent = blockEntryForm ?
diff --git a/src/core_modules/capture-core/components/WidgetEventEdit/hooks/index.js b/src/core_modules/capture-core/components/WidgetEventEdit/hooks/index.js
deleted file mode 100644
index edcfc4f241..0000000000
--- a/src/core_modules/capture-core/components/WidgetEventEdit/hooks/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-// @flow
-export { useAuthorities } from './useAuthorities';
diff --git a/src/core_modules/capture-core/components/WidgetProfile/OverflowMenu/OverflowMenu.container.js b/src/core_modules/capture-core/components/WidgetProfile/OverflowMenu/OverflowMenu.container.js
index f2b4fca631..031f7fd462 100644
--- a/src/core_modules/capture-core/components/WidgetProfile/OverflowMenu/OverflowMenu.container.js
+++ b/src/core_modules/capture-core/components/WidgetProfile/OverflowMenu/OverflowMenu.container.js
@@ -1,8 +1,8 @@
// @flow
import React from 'react';
+import { useAuthorities } from 'capture-core/utils/authority/useAuthorities';
import type { Props } from './OverflowMenu.types';
import { OverflowMenuComponent } from './OverflowMenu.component';
-import { useAuthorities } from './hooks';
export const OverflowMenu = ({
trackedEntityTypeName,
@@ -13,13 +13,13 @@ export const OverflowMenu = ({
teiId,
programAPI,
}: Props) => {
- const { canCascadeDeleteTei } = useAuthorities();
+ const { hasAuthority } = useAuthorities({ authorities: ['F_TEI_CASCADE_DELETE'] });
return (
{
- const queryKey = ['authorities'];
- const queryFn = {
- resource: 'me.json',
- params: {
- fields: 'authorities',
- },
- };
- const queryOptions = {
- select: ({ authorities }) =>
- authorities &&
- authorities.some(authority => authority === auth.ALL || authority === auth.F_TEI_CASCADE_DELETE),
- };
- const { data } = useApiMetadataQuery(queryKey, queryFn, queryOptions);
-
- return {
- canCascadeDeleteTei: Boolean(data),
- };
-};
diff --git a/src/core_modules/capture-core/components/WidgetEventEdit/hooks/useAuthorities.js b/src/core_modules/capture-core/utils/authority/useAuthorities.js
similarity index 54%
rename from src/core_modules/capture-core/components/WidgetEventEdit/hooks/useAuthorities.js
rename to src/core_modules/capture-core/utils/authority/useAuthorities.js
index 78de4ab612..0bea301f9e 100644
--- a/src/core_modules/capture-core/components/WidgetEventEdit/hooks/useAuthorities.js
+++ b/src/core_modules/capture-core/utils/authority/useAuthorities.js
@@ -2,11 +2,10 @@
import { useApiMetadataQuery } from 'capture-core/utils/reactQueryHelpers';
const auth = Object.freeze({
- F_UNCOMPLETE_EVENT: 'F_UNCOMPLETE_EVENT',
ALL: 'ALL',
});
-export const useAuthorities = () => {
+export const useAuthorities = ({ authorities }: { authorities: Array }) => {
const queryKey = ['authorities'];
const queryFn = {
resource: 'me.json',
@@ -15,13 +14,15 @@ export const useAuthorities = () => {
},
};
const queryOptions = {
- select: ({ authorities }) =>
- authorities &&
- authorities.some(authority => authority === auth.ALL || authority === auth.F_UNCOMPLETE_EVENT),
+ select: ({ authorities: userAuthorities }) =>
+ userAuthorities &&
+ authorities.some(
+ authority => userAuthorities.includes(auth.ALL) || userAuthorities.includes(authority),
+ ),
};
const { data } = useApiMetadataQuery(queryKey, queryFn, queryOptions);
return {
- canEditCompletedEvent: Boolean(data),
+ hasAuthority: Boolean(data),
};
};