Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
fb5a5ab
feat: batch data entry widget and plugin entry point
simonadomnisoru Mar 13, 2025
c8aef0d
feat: batch data entry widget and plugin entry point
simonadomnisoru Mar 13, 2025
e5e4d7d
feat: batch data entry widget and plugin entry point
simonadomnisoru Mar 13, 2025
6fcb410
chore: rename variable to pluginSource
simonadomnisoru Mar 17, 2025
33219da
feat: use react query to get batchDataEntryFromIndexedDB
simonadomnisoru Mar 19, 2025
7d37a5b
Merge branch 'master' into DHIS2-18889
simonadomnisoru Mar 19, 2025
a929baa
chore: handle all page statuses in the main page container
simonadomnisoru Mar 26, 2025
9fee265
chore: handle all page statuses in the main page container
simonadomnisoru Mar 26, 2025
8ea4c6f
chore: apply css styles from detailed design
simonadomnisoru Mar 27, 2025
77456bb
chore: rename batch to bulk
simonadomnisoru Mar 27, 2025
dc294d1
chore: handle long titles in active mode
simonadomnisoru Mar 31, 2025
6afd618
chore: simplify cachedBulkDataEntry checks
simonadomnisoru Apr 3, 2025
3699028
feat: replace ' list' with 'Program overview' as the Breadcrumbs orig…
simonadomnisoru Apr 14, 2025
480a81d
chore: flow
simonadomnisoru Apr 16, 2025
4a79b78
feat: add tracked entities from WL to bulk data entry
simonadomnisoru Apr 22, 2025
518ee9f
fix: sonarcube warnings
simonadomnisoru Apr 22, 2025
4f6e222
feat: add tracked entities from WL to bulk data entry
simonadomnisoru Apr 22, 2025
afd33e2
fix: uncaught runtime error
simonadomnisoru Apr 24, 2025
328462a
chore: increese cacheVersion
simonadomnisoru Apr 24, 2025
3551341
chore: fix cypress selectors
simonadomnisoru Apr 28, 2025
40219c6
Merge branch 'master' into DHIS2-18889
simonadomnisoru Apr 28, 2025
d038129
Merge branch 'DHIS2-18889' into DHIS2-19024
simonadomnisoru Apr 28, 2025
59c2151
docs: add Bulk data entry Plugin developer portal docs
simonadomnisoru Apr 30, 2025
95208cc
chore: improve css
simonadomnisoru Apr 30, 2025
1ad3c4a
feat: make useActiveBulkDataEntryList responsible for updating the da…
simonadomnisoru May 5, 2025
5576959
Merge branch 'master' into DHIS2-18889
simonadomnisoru May 5, 2025
3e61417
Merge branch 'DHIS2-18889' into DHIS2-19024
simonadomnisoru May 5, 2025
8b16dd0
chore: improve bulkDataEntryIsActive
simonadomnisoru May 5, 2025
7db181c
Merge branch 'DHIS2-19024' into DHIS2-18603
simonadomnisoru May 6, 2025
51163da
chore: fix typos and title case
simonadomnisoru May 6, 2025
b71aa44
feat: validate the datastore config using zod & add version to config
simonadomnisoru May 13, 2025
b406a15
Merge branch 'master' into DHIS2-18889
simonadomnisoru May 13, 2025
0bc12c6
Merge branch 'DHIS2-18889' into DHIS2-19024
simonadomnisoru May 13, 2025
5b29e88
chore: refactor useBulkDataEntryConfigurations hook
simonadomnisoru May 19, 2025
5da7f11
chore: move common files to components/common/bulkDataEntry/
simonadomnisoru May 19, 2025
b5614da
chore: do not expose isError
simonadomnisoru May 19, 2025
f119b2d
fix: fill the screen vertically with the Plugin contents
simonadomnisoru May 19, 2025
074efee
Merge branch 'master' into DHIS2-18889
simonadomnisoru May 19, 2025
571d853
Merge branch 'DHIS2-18889' into DHIS2-19024
simonadomnisoru May 19, 2025
3cf9dfe
fix: unify callbacks into onOpenBulkDataEntryPlugin and onCloseBulkDa…
simonadomnisoru May 20, 2025
6e14789
chore: move BulkActionBar from WorkingListsBase to WorkingListsCommon
simonadomnisoru May 20, 2025
01a403f
chore: fix breadcrumb default label
simonadomnisoru May 20, 2025
18868dc
Merge branch 'DHIS2-18889' into DHIS2-19024
simonadomnisoru May 20, 2025
ccc4004
chore: renames customTopBarActions & bulkDataEntryTrackedEntityIds & …
simonadomnisoru May 21, 2025
4795dd6
chore: split injectSelectedRowsToBulkDataEntryPlugin
simonadomnisoru May 21, 2025
5192d30
chore: improve the Plugin interface
simonadomnisoru May 21, 2025
6a4aca5
Merge branch 'master' into DHIS2-18889
simonadomnisoru May 21, 2025
434b166
Merge branch 'DHIS2-18889' into DHIS2-19024
simonadomnisoru May 21, 2025
d68f8ef
chore: fix sonarqube warnings
simonadomnisoru May 21, 2025
648b202
Merge branch 'DHIS2-19024' into DHIS2-18603
simonadomnisoru May 21, 2025
31fbedf
docs: update with lastest Plugin interface and DataStore config
simonadomnisoru May 22, 2025
19538a2
docs: apply PR suggetions
simonadomnisoru Jun 3, 2025
1e92c1d
chore: norwegian translation
simonadomnisoru Jun 5, 2025
da7559b
docs: improve pluginSource
simonadomnisoru Jun 18, 2025
d089388
Merge branch 'master' into DHIS2-18603
simonadomnisoru Jul 9, 2025
eb73da7
chore: improve wording
simonadomnisoru Jul 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions docs/developer/bulk-data-entry-plugin/developer-details.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
title: Developer Details (Bulk Data Entry Plugin)
sidebar_label: Developer details
id: developer-details
---

Here are some details for developers who want to develop a bulk data entry plugin for the DHIS2 Capture app.

## Plugin Interface

The plugin receives the following props:

```ts
type BulkDataEntryPluginProps = {|
pluginSource: string,
configKey: string,
dataKey?: string,
onComplete: () => void,
onDefer: () => void,
trackedEntityIds?: Array<string>,
|};
```

### Exiting the Plugin

To exit the Plugin and return to the Program overview or Search pages, use the `onDefer` function provided as a prop. This will place the Plugin in an idle state until further action is taken.

```ts
onDefer();
```

### Closing the Plugin

To ensure proper cleanup and resource management, use the `onComplete` function provided as a prop to close the plugin. This will clear the selected configuration from `IndexedDB`.
```ts
onComplete();
```
16 changes: 16 additions & 0 deletions docs/developer/bulk-data-entry-plugin/introduction.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
title: What is the Bulk Data Entry Plugin?
sidebar_label: Introduction
id: introduction
---

The Bulk Data Entry Plugin is an extension point that can be accessed through the Search page or Working list page in Capture app. This extension point enables developers to create and configure plugins for custom bulk operations on tracked entities carried over from the working list page or added manually in the plugin itself.
The main reason for developing this extension point in the DHIS2 Capture app was to support a plugin for bulk data entry in a grid form, adding new events to all tracked entities in a list, including applying same values for a column or copy and pasting values from a row to another. The aim is to reduce time spent on data entry, for example secondary from paper forms.

Some plugin use cases for the extension point can include:

1. Enter data for multiple tracked entities at the same time (Forthcoming core Capture plugin)
2. Validate and update data across multiple tracked entity records simultaneously
3. Update the status of multiple events in one go
4. Merging or deduplicating tracked entities
5. Any other custom bulk operations or changes your workflow might require
108 changes: 108 additions & 0 deletions docs/developer/bulk-data-entry-plugin/manual-setup.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
---
title: Manual Setup (Bulk Data Entry Plugin)
sidebar_label: Manual setup
id: manual-setup
---

To enable bulk data entry functionality, you need to configure the data store in your DHIS2 instance. Follow these steps:

1. Access your DHIS2 Data Store Management app
2. Create a new key called `bulkDataEntry` in the `capture` namespace
3. The data store interface should look similar to this:

![Data store management app](../resources/data-store-management-bulk-data-entry-empty.png)

## Configuration Structure

In the `bulkDataEntry` key you created, you can store your bulk data entry form configurations. The structure is as follows:

```json title="capture/bulkDataEntry"
{
"version": 1,
"config": []
}
```

The `version` field indicates the configuration version as a number. The `config` array contains one or more bulk data entry configuration objects. Below is an example showcasing three different configurations:

```json title="capture/bulkDataEntry"
{
"version": 1,
"config": [
{
"title": {
"en": "Routine visit"
},
"dataKey": "routineVisit",
"subtitle": {
"en": "Covers all patient visit forms"
},
"configKey": "routineVisit",
"programId": "IpHINAT79UW",
"pluginSource": "https://debug.dhis2.org/dev/api/apps/routine-visit/plugin.html"
},
{
"title": {
"es": "Tratamiento",
"en": "Treatment",
"fr": "Traitement",
"nb": "Behandling"
},
"configKey": "treatment",
"programId": "IpHINAT79UW",
"pluginSource": "https://debug.dhis2.org/dev/api/apps/treatment/plugin.html"
},
{
"title": {
"en": "Case based surveillance"
},
"subtitle": {
"en": "Covers ad-hoc visits and RMNCH238972"
},
"configKey": "caseBasedSurveillance",
"programId": "uy2gU8kT1jF",
"pluginSource": "https://debug.dhis2.org/dev/api/apps/case-based-surveillance/plugin.html"
}
]
}
```

### Configuration Fields

Each configuration object requires the following fields:

| Field | Required | Description |
|-------|----------|-------------|
| `configKey` | Yes | An identifier for the configuration. Must be unique per `programId`. Will be passed to the plugin. |
| `programId` | Yes | The identifier of the program where this bulk data entry will be available. |
| `pluginSource` | Yes | The URL of the plugin. Must point to a valid plugin installed on the instance and follow the pattern: https://{instance-url}/api/apps/{plugin-name}/plugin.html. |
| `title` | Yes | The display title of the configuration. Supports multiple languages using locale codes (e.g., "en", "es"). |
| `subtitle` | No | An optional subtitle for the configuration. Supports multiple languages using locale codes. |
| `dataKey` | No | An optional identifier that is not used internally by the app but is passed through to the plugin. This property is intended for advanced usage and can be used by the plugin to maintain separate in-progress caches for a given `configKey`. |

## Selecting a Plugin Configuration

Once configured, bulk data entry plugins are accessible in multiple locations throughout the Capture app. You'll find them displayed as widgets on both the Program overview and Search pages:

![Widget bulk data entry main page](../resources/widget-bulk-data-entry-main-page.png)
![Widget bulk data entry search page](../resources/widget-bulk-data-entry-search-page.png)

The plugins can also be accessed via dropdown menus from the tracked entities working lists or the program stages working lists:

![Dropdown menu bulk data entry program stage working lists](../resources/dropdown-menu-bulk-data-entry-program-stage-working-lists.png)
![Dropdown menu bulk data entry tracked entities working lists](../resources/dropdown-menu-bulk-data-entry-tracked-entities-working-lists.png)

After the user selects a plugin configuration, it is stored in `IndexedDB` for the duration of use.

### Passing Tracked Entities to the Plugin

The plugin receives tracked entities through the `trackedEntityIds` prop - an array containing the IDs of selected tracked entities.

### Cleanup and Disposal

To exit the Plugin and return to the Program overview or Search pages, use the `onDefer` function provided as a prop. This will place the Plugin in an idle state until further action is taken.

![Widget bulk data entry main page](../resources/widget-bulk-data-entry-main-page-idle.png)
![Widget bulk data entry search page](../resources/widget-bulk-data-entry-search-page-idle.png)

To ensure proper cleanup and resource management, use the `onComplete` function provided as a prop to close the plugin. This will clear the selected configuration from `IndexedDB`.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading