diff --git a/cypress/e2e/WidgetsForEnrollmentPages/WidgetProfile/index.js b/cypress/e2e/WidgetsForEnrollmentPages/WidgetProfile/index.js
index 31370a0606..0ec69710cd 100644
--- a/cypress/e2e/WidgetsForEnrollmentPages/WidgetProfile/index.js
+++ b/cypress/e2e/WidgetsForEnrollmentPages/WidgetProfile/index.js
@@ -1,4 +1,4 @@
-import { Then } from '@badeball/cypress-cucumber-preprocessor';
+import { Then, Given, When } from '@badeball/cypress-cucumber-preprocessor';
import '../../sharedSteps';
Then('the profile details should be displayed', () => {
@@ -31,3 +31,40 @@ Then(/^the user sees the edit profile modal/, () =>
cy.contains('Cancel without saving').should('exist');
}),
);
+
+Given('you add a new tracked entity in the Malaria focus investigation program', () => {
+ cy.visit('/#/new?programId=M3xtLkYBlKI&orgUnitId=DiszpKrYNg8');
+ cy.get('[data-test="capture-ui-input"]')
+ .eq(2)
+ .type(`Local id-${Math.round((new Date()).getTime() / 1000)}`)
+ .blur();
+ cy.contains('Save focus area')
+ .click();
+ cy.url().should('include', 'enrollmentEventEdit?');
+});
+
+When('you open the overflow menu and click the "Delete Focus area" button', () => {
+ cy.get('[data-test="widget-profile-overflow-menu"]')
+ .click();
+ cy.contains('Delete Focus area')
+ .click();
+});
+
+Then('you see the delete tracked entity confirmation modal', () => {
+ cy.get('[data-test="widget-profile-delete-modal"]').within(() => {
+ cy.contains(
+ 'Are you sure you want to delete this Focus area? This will permanently remove the Focus area and all its associated enrollments and events in all programs.',
+ ).should('exist');
+ });
+});
+
+When('you confirm by clicking the "Yes, delete Focus area" button', () => {
+ cy.get('[data-test="widget-profile-delete-modal"]').within(() => {
+ cy.contains('Yes, delete Focus area')
+ .click();
+ });
+});
+
+Then('you are redirected to the home page', () => {
+ cy.url().should('include', 'selectedTemplateId=M3xtLkYBlKI');
+});
diff --git a/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentAddEventPage.feature b/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentAddEventPage.feature
index 2a07ab2658..b076a66d1f 100644
--- a/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentAddEventPage.feature
+++ b/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentAddEventPage.feature
@@ -38,6 +38,15 @@ Feature: The user interacts with the widgets on the enrollment add event page
And the user sees the owner organisation unit
And the user sees the last update date
+ Scenario: You can delete a tracked entity from the profile widget
+ Given you add a new tracked entity in the Malaria focus investigation program
+ When the user clicks the "Back to all stages and events" button
+ When the user clicks the "New Event" button
+ When you open the overflow menu and click the "Delete Focus area" button
+ Then you see the delete tracked entity confirmation modal
+ When you confirm by clicking the "Yes, delete Focus area" button
+ Then you are redirected to the home page
+
# TODO DHIS2-11482 - The test cases related with enrollment status edit are flaky. Move them to unit tests.
# Scenario: User can modify the enrollment from Active to Complete
# Given you land on the enrollment add event page by having typed #/enrollmentEventNew?programId=IpHINAT79UW&orgUnitId=DiszpKrYNg8&teiId=EaOyKGOIGRp&enrollmentId=wBU0RAsYjKE&stageId=A03MvHHogjR
diff --git a/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentAddEventPage/index.js b/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentAddEventPage/index.js
index 547b242c5a..ebb0f1293a 100644
--- a/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentAddEventPage/index.js
+++ b/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentAddEventPage/index.js
@@ -1,4 +1,4 @@
-import { Then } from '@badeball/cypress-cucumber-preprocessor';
+import { When, Then } from '@badeball/cypress-cucumber-preprocessor';
import '../sharedSteps';
import '../WidgetEnrollment';
import '../WidgetProfile';
@@ -14,3 +14,17 @@ Then('you can assign a user when scheduling the event', () => {
cy.get('[data-test="dhis2-uicore-chip"]').contains('Tracker demo User').should('exist');
});
});
+
+When(/^the user clicks the "Back to all stages and events" button/, () =>
+ cy
+ .get('[data-test="widget-enrollment-event"]')
+ .contains('Back to all stages and events')
+ .click(),
+);
+
+When(/^the user clicks the "New Event" button/, () =>
+ cy
+ .get('[data-test="quick-action-button-report"]')
+ .contains('New Event')
+ .click(),
+);
diff --git a/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentDashboard.feature b/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentDashboard.feature
index 120fe05e12..a7cd50a090 100644
--- a/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentDashboard.feature
+++ b/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentDashboard.feature
@@ -75,6 +75,14 @@ Feature: The user interacts with the widgets on the enrollment dashboard
Then the profile widget attributes list contains the text Maria
And the scope selector list contains the text Maria
+ Scenario: You can delete a tracked entity from the profile widget
+ Given you add a new tracked entity in the Malaria focus investigation program
+ When the user clicks the "Back to all stages and events" button
+ When you open the overflow menu and click the "Delete Focus area" button
+ Then you see the delete tracked entity confirmation modal
+ When you confirm by clicking the "Yes, delete Focus area" button
+ Then you are redirected to the home page
+
Scenario: User can close the Enrollment Widget
Given you land on the enrollment dashboard page by having typed #/enrollment?enrollmentId=wBU0RAsYjKE
And the enrollment widget should be opened
diff --git a/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentDashboard/index.js b/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentDashboard/index.js
index c0fa3ca18e..27f0a0d365 100644
--- a/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentDashboard/index.js
+++ b/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentDashboard/index.js
@@ -49,3 +49,11 @@ Then(/^the scope selector list contains the text (.*)$/, (name) => {
cy.contains(name).should('exist');
});
});
+
+When(/^the user clicks the "Back to all stages and events" button/, () =>
+ cy
+ .get('[data-test="widget-enrollment-event"]')
+ .contains('Back to all stages and events')
+ .click(),
+);
+
diff --git a/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentEditEvent.feature b/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentEditEvent.feature
index ca66bb8663..5e2c3c33f5 100644
--- a/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentEditEvent.feature
+++ b/cypress/e2e/WidgetsForEnrollmentPages/WidgetsForEnrollmentEditEvent.feature
@@ -38,6 +38,13 @@ Feature: The user interacts with the widgets on the enrollment edit event
And the user sees the owner organisation unit
And the user sees the last update date
+ Scenario: You can delete a tracked entity from the profile widget
+ Given you add a new tracked entity in the Malaria focus investigation program
+ When you open the overflow menu and click the "Delete Focus area" button
+ Then you see the delete tracked entity confirmation modal
+ When you confirm by clicking the "Yes, delete Focus area" button
+ Then you are redirected to the home page
+
# TODO DHIS2-11482 - The test cases related with enrollment status edit are flaky. Move them to unit tests.
# Scenario: User can modify the enrollment from Active to Complete
# Given you land on the enrollment edit event page by having typed #/enrollmentEventEdit?programId=IpHINAT79UW&orgUnitId=DiszpKrYNg8&teiId=EaOyKGOIGRp&enrollmentId=wBU0RAsYjKE&stageId=A03MvHHogjR
diff --git a/docs/user/resources/images/enrollment-dash-tei-profile-widget-delete.png b/docs/user/resources/images/enrollment-dash-tei-profile-widget-delete.png
new file mode 100644
index 0000000000..df79cc9c1b
Binary files /dev/null and b/docs/user/resources/images/enrollment-dash-tei-profile-widget-delete.png differ
diff --git a/docs/user/using-the-capture-app.md b/docs/user/using-the-capture-app.md
index 45210cff87..7e8a9c0449 100644
--- a/docs/user/using-the-capture-app.md
+++ b/docs/user/using-the-capture-app.md
@@ -1039,6 +1039,10 @@ Click the **Edit** button to make changes to the tracked entity instance profile
![](resources/images/enrollment-dash-tei-profile-widget-edit.png)
+Click the **Delete ${tracked entity type}** button to delete the tracked entity. You can confirm the action from the dialog. Once confirmed, tracked entity and all its associated enrollment and events across all programs will be deleted. To delete a tracked entity that has any enrollments, the user needs the authority **Delete tracked entity instance and associated enrollments and events**.
+
+![](resources/images/enrollment-dash-tei-profile-widget-delete.png)
+
### Feedback widget
![](resources/images/enrollment-dash-feedback-widget-1.png)
diff --git a/i18n/en.pot b/i18n/en.pot
index c228a599d3..dfcf6a5bf2 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-03-05T07:44:33.812Z\n"
-"PO-Revision-Date: 2024-03-05T07:44:33.812Z\n"
+"POT-Creation-Date: 2024-03-05T12:36:05.806Z\n"
+"PO-Revision-Date: 2024-03-05T12:36:05.806Z\n"
msgid "Choose one or more dates..."
msgstr "Choose one or more dates..."
@@ -1392,11 +1392,35 @@ msgstr "Try again or contact your system administrator for support"
msgid "Fix errors in the form to continue."
msgstr "Fix errors in the form to continue."
+msgid "You do not have access to delete this {{trackedEntityTypeName}}"
+msgstr "You do not have access to delete this {{trackedEntityTypeName}}"
+
+msgid "Delete {{trackedEntityTypeName}}"
+msgstr "Delete {{trackedEntityTypeName}}"
+
+msgid ""
+"Are you sure you want to delete this {{trackedEntityTypeName}}? This will "
+"permanently remove the {{trackedEntityTypeName}} and all its associated "
+"enrollments and events in all programs."
+msgstr ""
+"Are you sure you want to delete this {{trackedEntityTypeName}}? This will "
+"permanently remove the {{trackedEntityTypeName}} and all its associated "
+"enrollments and events in all programs."
+
+msgid "There was a problem deleting the {{trackedEntityTypeName}}"
+msgstr "There was a problem deleting the {{trackedEntityTypeName}}"
+
+msgid "Yes, delete {{trackedEntityTypeName}}"
+msgstr "Yes, delete {{trackedEntityTypeName}}"
+
+msgid "View changelog"
+msgstr "View changelog"
+
msgid "Profile widget could not be loaded. Please try again later"
msgstr "Profile widget could not be loaded. Please try again later"
-msgid "{{TETName}} profile"
-msgstr "{{TETName}} profile"
+msgid "{{trackedEntityTypeName}} profile"
+msgstr "{{trackedEntityTypeName}} profile"
msgid "tracked entity instance"
msgstr "tracked entity instance"
diff --git a/src/core_modules/capture-core/components/Buttons/OverflowButton.component.js b/src/core_modules/capture-core/components/Buttons/OverflowButton.component.js
new file mode 100644
index 0000000000..b0d1585df2
--- /dev/null
+++ b/src/core_modules/capture-core/components/Buttons/OverflowButton.component.js
@@ -0,0 +1,68 @@
+// @flow
+import * as React from 'react';
+import { useRef, useState } from 'react';
+import { Button, Layer, Popper } from '@dhis2/ui';
+
+type Props = {
+ label?: string,
+ primary?: boolean,
+ secondary?: boolean,
+ icon?: React.Node,
+ onClick?: () => void,
+ open?: boolean,
+ component: React.Node,
+ dataTest?: string,
+ small?: boolean,
+ large?: boolean,
+ className: string,
+};
+
+export const OverflowButton = ({
+ label,
+ primary,
+ secondary,
+ small,
+ large,
+ onClick: handleClick,
+ open: propsOpen,
+ icon,
+ dataTest,
+ component,
+ className,
+}: Props) => {
+ const [isOpen, setIsOpen] = useState(false);
+ const anchorRef = useRef(null);
+ const open = propsOpen !== undefined ? propsOpen : isOpen;
+
+ const toggle = () => {
+ if (propsOpen === undefined) {
+ setIsOpen(prev => !prev);
+ }
+ handleClick && handleClick();
+ };
+
+ return (
+
+ {i18n.t(
+ 'Are you sure you want to delete this {{trackedEntityTypeName}}? This will permanently remove the {{trackedEntityTypeName}} and all its associated enrollments and events in all programs.',
+ {
+ trackedEntityTypeName,
+ interpolation: { escapeValue: false },
+ },
+ )}
+