From 8cfb4a655a45420f714d4c12d5d91ce4a90475c9 Mon Sep 17 00:00:00 2001 From: henrikmv Date: Fri, 25 Oct 2024 19:50:36 +0200 Subject: [PATCH] fix: disable button and add tooltip --- i18n/en.pot | 7 +++-- .../Actions/Actions.component.js | 2 ++ .../Actions/Actions.container.js | 3 +++ .../Actions/Delete/Delete.component.js | 12 ++++++--- .../Actions/Delete/delete.types.js | 1 + .../WidgetEnrollment/Actions/actions.types.js | 1 + .../WidgetEnrollment/hooks/useAuthorities.js | 27 +++++++++++++++++++ 7 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 src/core_modules/capture-core/components/WidgetEnrollment/hooks/useAuthorities.js diff --git a/i18n/en.pot b/i18n/en.pot index a5500f1058..2abc5dec9d 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-25T14:57:43.514Z\n" -"PO-Revision-Date: 2024-10-25T14:57:43.514Z\n" +"POT-Creation-Date: 2024-10-25T17:42:56.394Z\n" +"PO-Revision-Date: 2024-10-25T17:42:56.394Z\n" msgid "Choose one or more dates..." msgstr "Choose one or more dates..." @@ -1136,6 +1136,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..84b330bad5 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 '../hooks/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 { canCasacdeDeleteEnrollment } = useAuthorities(); const { updateEnrollmentOwnership, isTransferLoading } = useUpdateOwnership({ teiId: enrollment.trackedEntity, programId: enrollment.program, @@ -52,6 +54,7 @@ export const Actions = ({ onUpdate={updateMutation} onUpdateStatus={handleUpdateStatus} onDelete={deleteMutation} + canCascadeDeleteEnrollment={canCasacdeDeleteEnrollment} 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..b15f78e972 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, useMemo } 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 = useMemo(() => !canCascadeDeleteEnrollment, [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/hooks/useAuthorities.js b/src/core_modules/capture-core/components/WidgetEnrollment/hooks/useAuthorities.js new file mode 100644 index 0000000000..d15dd9a226 --- /dev/null +++ b/src/core_modules/capture-core/components/WidgetEnrollment/hooks/useAuthorities.js @@ -0,0 +1,27 @@ +// @flow +import { useApiMetadataQuery } from 'capture-core/utils/reactQueryHelpers'; + +const auth = Object.freeze({ + F_ENROLLMENT_CASCADE_DELETE: 'F_ENROLLMENT_CASCADE_DELETE', + ALL: 'ALL', +}); + +export const useAuthorities = () => { + 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_ENROLLMENT_CASCADE_DELETE), + }; + const { data } = useApiMetadataQuery(queryKey, queryFn, queryOptions); + + return { + canCasacdeDeleteEnrollment: Boolean(data), + }; +};