diff --git a/src/components/Inputs/AtomicMode.js b/src/components/Inputs/AtomicMode.js
index e0165a2f2..468061c8b 100644
--- a/src/components/Inputs/AtomicMode.js
+++ b/src/components/Inputs/AtomicMode.js
@@ -4,7 +4,7 @@ import { RadioGroupField } from '../index.js'
const atomicModeOptions = [
{ value: 'ALL', label: i18n.t('Do not import') },
- { value: 'NONE', label: i18n.t('Import') },
+ { value: 'OBJECT', label: i18n.t('Import') },
]
const defaultAtomicModeOption = atomicModeOptions[0].value
diff --git a/src/components/Inputs/EndDate.js b/src/components/Inputs/EndDate.js
index 164f3b097..0ddd4656c 100644
--- a/src/components/Inputs/EndDate.js
+++ b/src/components/Inputs/EndDate.js
@@ -1,5 +1,6 @@
import i18n from '@dhis2/d2-i18n'
import { hasValue, composeValidators } from '@dhis2/ui'
+import PropTypes from 'prop-types'
import React from 'react'
import { DATE_VALIDATOR } from '../DatePicker/DatePickerField.js'
import { DatePickerField } from '../index.js'
@@ -9,13 +10,18 @@ const DATATEST = 'input-end-date'
const LABEL = i18n.t('End date')
const VALIDATOR = composeValidators(hasValue, DATE_VALIDATOR)
-const EndDate = () => (
+const EndDate = ({ name, label }) => (
)
+EndDate.propTypes = {
+ label: PropTypes.string,
+ name: PropTypes.string,
+}
+
export { EndDate }
diff --git a/src/components/Inputs/FollowUpStatus.js b/src/components/Inputs/FollowUpStatus.js
index d09234ab0..1fc2383d0 100644
--- a/src/components/Inputs/FollowUpStatus.js
+++ b/src/components/Inputs/FollowUpStatus.js
@@ -5,12 +5,12 @@ import { RadioGroupField } from '../index.js'
const followUpStatusOptions = [
{ value: 'ALL', label: i18n.t('All') },
- { value: 'TRUE', label: i18n.t('Marked for follow-up') },
- { value: 'FALSE', label: i18n.t('Not marked for follow-up') },
+ { value: 'true', label: i18n.t('Marked for follow-up') },
+ { value: 'false', label: i18n.t('Not marked for follow-up') },
]
const defaultFollowUpStatusOption = followUpStatusOptions[0].value
-const NAME = 'followUpStatus'
+const NAME = 'followup'
const DATATEST = 'input-follow-up-status'
const LABEL = i18n.t('Include only entities with follow-up status')
diff --git a/src/components/Inputs/LastUpdatedDuration.js b/src/components/Inputs/LastUpdatedDuration.js
index 08b24dd51..21fc074c3 100644
--- a/src/components/Inputs/LastUpdatedDuration.js
+++ b/src/components/Inputs/LastUpdatedDuration.js
@@ -5,7 +5,7 @@ import React from 'react'
import { DURATION_VALIDATOR } from '../Duration/DurationField.js'
import { DurationField } from '../index.js'
-const NAME = 'lastUpdatedDuration'
+const NAME = 'updatedWithin'
const DATATEST = 'input-last-updated-duration'
const LABEL = i18n.t('Last updated duration')
const VALIDATOR = composeValidators(hasValue, DURATION_VALIDATOR)
diff --git a/src/components/Inputs/LastUpdatedEndDate.js b/src/components/Inputs/LastUpdatedEndDate.js
index f765fc732..0bd558b66 100644
--- a/src/components/Inputs/LastUpdatedEndDate.js
+++ b/src/components/Inputs/LastUpdatedEndDate.js
@@ -5,7 +5,7 @@ import React from 'react'
import { OPTIONAL_DATE_VALIDATOR } from '../DatePicker/DatePickerField.js'
import { DatePickerField } from '../index.js'
-const NAME = 'lastUpdatedEndDate'
+const NAME = 'updatedBefore'
const DATATEST = 'input-last-updated-end-date'
const LABEL = i18n.t('Last updated end date')
const VALIDATOR = composeValidators(OPTIONAL_DATE_VALIDATOR)
diff --git a/src/components/Inputs/LastUpdatedStartDate.js b/src/components/Inputs/LastUpdatedStartDate.js
index 9a99ae208..d38735480 100644
--- a/src/components/Inputs/LastUpdatedStartDate.js
+++ b/src/components/Inputs/LastUpdatedStartDate.js
@@ -5,7 +5,7 @@ import React from 'react'
import { OPTIONAL_DATE_VALIDATOR } from '../DatePicker/DatePickerField.js'
import { DatePickerField } from '../index.js'
-const NAME = 'lastUpdatedStartDate'
+const NAME = 'updatedAfter'
const DATATEST = 'input-last-updated-start-date'
const LABEL = i18n.t('Last updated start date')
const VALIDATOR = composeValidators(OPTIONAL_DATE_VALIDATOR)
diff --git a/src/components/Inputs/ProgramEndDate.js b/src/components/Inputs/ProgramEndDate.js
index e2f65738d..f1dcd137a 100644
--- a/src/components/Inputs/ProgramEndDate.js
+++ b/src/components/Inputs/ProgramEndDate.js
@@ -5,7 +5,7 @@ import React from 'react'
import { OPTIONAL_DATE_VALIDATOR } from '../DatePicker/DatePickerField.js'
import { DatePickerField } from '../index.js'
-const NAME = 'programEndDate'
+const NAME = 'enrollmentEnrolledBefore'
const DATATEST = 'input-program-end-date'
const LABEL = i18n.t('End date')
const VALIDATOR = composeValidators(OPTIONAL_DATE_VALIDATOR)
diff --git a/src/components/Inputs/ProgramStartDate.js b/src/components/Inputs/ProgramStartDate.js
index 35e035fb8..7757048c4 100644
--- a/src/components/Inputs/ProgramStartDate.js
+++ b/src/components/Inputs/ProgramStartDate.js
@@ -5,7 +5,7 @@ import React from 'react'
import { OPTIONAL_DATE_VALIDATOR } from '../DatePicker/DatePickerField.js'
import { DatePickerField } from '../index.js'
-const NAME = 'programStartDate'
+const NAME = 'enrollmentEnrolledAfter'
const DATATEST = 'input-program-start-date'
const LABEL = i18n.t('Start date')
const VALIDATOR = composeValidators(OPTIONAL_DATE_VALIDATOR)
diff --git a/src/components/Inputs/StartDate.js b/src/components/Inputs/StartDate.js
index 8b77968f8..23c41904e 100644
--- a/src/components/Inputs/StartDate.js
+++ b/src/components/Inputs/StartDate.js
@@ -1,5 +1,6 @@
import i18n from '@dhis2/d2-i18n'
import { hasValue, composeValidators } from '@dhis2/ui'
+import PropTypes from 'prop-types'
import React from 'react'
import { DATE_VALIDATOR } from '../DatePicker/DatePickerField.js'
import { DatePickerField } from '../index.js'
@@ -9,13 +10,17 @@ const DATATEST = 'input-start-date'
const LABEL = i18n.t('Start date')
const VALIDATOR = composeValidators(hasValue, DATE_VALIDATOR)
-const StartDate = () => (
+const StartDate = ({ name, label }) => (
)
+StartDate.propTypes = {
+ label: PropTypes.string,
+ name: PropTypes.string,
+}
export { StartDate }
diff --git a/src/components/Inputs/TEITypeFilter.js b/src/components/Inputs/TEITypeFilter.js
index f440f0478..822e9956f 100644
--- a/src/components/Inputs/TEITypeFilter.js
+++ b/src/components/Inputs/TEITypeFilter.js
@@ -3,7 +3,6 @@ import React from 'react'
import { RadioGroupField } from '../index.js'
const teiTypeFilterOptions = [
- { value: 'NONE', label: i18n.t('None') },
{ value: 'PROGRAM', label: i18n.t('Program') },
{ value: 'TE', label: i18n.t('Tracked entity type') },
]
diff --git a/src/components/JobSummary/SingleSummary/SingleSummary.js b/src/components/JobSummary/SingleSummary/SingleSummary.js
index f54ae56cd..001bf54d1 100644
--- a/src/components/JobSummary/SingleSummary/SingleSummary.js
+++ b/src/components/JobSummary/SingleSummary/SingleSummary.js
@@ -20,6 +20,7 @@ const SingleSummary = ({
status,
description,
conflicts,
+ validationReport,
id,
}) => (
@@ -29,7 +30,7 @@ const SingleSummary = ({
name="summary"
>
<>
- {status && (
+ {status && description && (
- {importCount.imported}
- {importCount.deleted}
- {importCount.ignored}
- {importCount.updated}
- {importCount.total}
+
+ {importCount?.imported ?? '0'}
+
+ {importCount?.deleted}
+ {importCount?.ignored}
+ {importCount?.updated}
+ {importCount?.total}
>
+ {!!validationReport?.errorReports?.length && (
+
+
+
+
+ {i18n.t('UID')}
+
+ {i18n.t('Error Code')}
+
+ {i18n.t('Message')}
+
+ {i18n.t('Tracker Type')}
+
+ {/* {i18n.t('')} */}
+
+
+
+ {validationReport.errorReports.map((c, i) => (
+
+ {c.uid}
+
+
+ {c.warningCode ?? c.errorCode}
+
+
+ {c.message}
+ {c.trackerType}
+
+ ))}
+
+
+
+ )}
{conflicts && (
{
importCount={importCount}
status={summary.status}
description={summary.description}
+ validationReport={summary.validationReport}
conflicts={
summary.conflicts &&
(summary.conflicts.length || null) &&
diff --git a/src/components/JobSummary/__test__/__snapshots__/Summary.test.js.snap b/src/components/JobSummary/__test__/__snapshots__/Summary.test.js.snap
index 08e40e253..92bad399b 100644
--- a/src/components/JobSummary/__test__/__snapshots__/Summary.test.js.snap
+++ b/src/components/JobSummary/__test__/__snapshots__/Summary.test.js.snap
@@ -172,51 +172,6 @@ exports[`different job type summaries matches snapshot - EVENT_IMPORT 1`] = `
>
Summary
-
-
-
-
- Status
- |
-
- Description
- |
-
-
-
-
-
- ERROR
- |
- |
-
-
-
Summary
-
-
-
-
- Status
- |
-
- Description
- |
-
-
-
-
-
- OK
- |
- |
-
-
-
+ >
+ 0
+
| ,
}
const teiImportPage = {
- name: i18n.t('TEI import'),
+ name: i18n.t('Tracked entity import'),
code: 'tei-import',
path: '/import/tei',
icon: ,
@@ -88,7 +88,7 @@ const metadataExportPage = {
}
const teiExportPage = {
- name: i18n.t('TEI export'),
+ name: i18n.t('Tracked entity export'),
code: 'tei-export',
path: '/export/tei',
icon: ,
diff --git a/src/hooks/useTasks.js b/src/hooks/useTasks.js
index 7dfcc606c..7b52c2794 100644
--- a/src/hooks/useTasks.js
+++ b/src/hooks/useTasks.js
@@ -16,6 +16,20 @@ const jobSummaryQuery = {
},
}
+const trackerEventQuery = {
+ events: {
+ resource: 'tracker/jobs/',
+ id: ({ taskId }) => `${taskId}`,
+ },
+}
+
+const trackerSummaryQuery = {
+ summary: {
+ resource: 'tracker/jobs/',
+ id: ({ taskId }) => `${taskId}/report`,
+ },
+}
+
const defaultTasks = {
data: {},
event: {},
@@ -39,13 +53,20 @@ const createFetchEvents =
}
const newTask = { ...task }
- const { events, error } = await engine.query(jobEventQuery, {
+ const query =
+ task.importType === 'TRACKER_IMPORT_JOB'
+ ? trackerEventQuery
+ : jobEventQuery
+
+ const response = await engine.query(query, {
variables: {
type: task.importType,
taskId: task.id,
},
})
+ const { events, error } = response
+
if (error) {
console.error('fetchEvents error: ', error)
return
@@ -90,13 +111,24 @@ const createFetchEvents =
const createFetchSummary = (engine, setTasks) => async (type, id, task) => {
const newTask = { ...task }
- const { summary, error } = await engine.query(jobSummaryQuery, {
+ // we could still keep one query here (the jobs query), but tracker provides a facade to these
+ // and even though this branches the logic unnecessarily, we should stick to
+ // trackers' endpoint for tracker imports and they could abstract some job-related details
+ // more details here: https://docs.dhis2.org/en/develop/using-the-api/dhis-core-version-master/tracker.html#webapi_nti_import_summary
+ const query =
+ task.importType === 'TRACKER_IMPORT_JOB'
+ ? trackerSummaryQuery
+ : jobSummaryQuery
+
+ const response = await engine.query(query, {
variables: {
type: task.importType,
taskId: task.id,
},
})
+ const { summary, error } = response
+
if (error) {
console.error('fetchSummary error: ', error)
return
diff --git a/src/pages/DataExport/form-helper.js b/src/pages/DataExport/form-helper.js
index 03c350735..216b7793d 100644
--- a/src/pages/DataExport/form-helper.js
+++ b/src/pages/DataExport/form-helper.js
@@ -56,7 +56,8 @@ const onExport = (baseUrl, setExportEnabled) => async (values) => {
const filename = `${endpoint}.${fileExtension}`
const downloadUrlParams = valuesToParams(values, filename)
const url = `${apiBaseUrl}${endpoint}?${downloadUrlParams}`
- locationAssign(url, setExportEnabled)
+ locationAssign(url)
+ setExportEnabled(true)
// log for debugging purposes
console.log('data-export:', { url, params: downloadUrlParams })
diff --git a/src/pages/EventExport/EventExport.js b/src/pages/EventExport/EventExport.js
index e88f1fef5..eb1d8e860 100644
--- a/src/pages/EventExport/EventExport.js
+++ b/src/pages/EventExport/EventExport.js
@@ -14,7 +14,6 @@ import {
OrgUnitTree,
ProgramPicker,
Format,
- formatOptions,
defaultFormatOption,
Compression,
defaultCompressionOption,
@@ -32,6 +31,7 @@ import {
defaultOrgUnitIdSchemeOption,
IdScheme,
defaultIdSchemeOption,
+ formatNoXmlOptions,
} from '../../components/Inputs/index.js'
import { jsDateToISO8601 } from '../../utils/helper.js'
import { onExport, validate } from './form-helper.js'
@@ -41,7 +41,7 @@ const { Form } = ReactFinalForm
// PAGE INFO
export const PAGE_NAME = i18n.t('Event export')
export const PAGE_DESCRIPTION = i18n.t(
- 'Export event data for programs, stages and tracked entities to JSON, CSV, or DXF2 format.'
+ 'Export event data for programs, stages and tracked entities to JSON or CSV format.'
)
const PAGE_ICON =
@@ -58,13 +58,14 @@ const initialValues = {
programStage: undefined,
format: defaultFormatOption,
compression: defaultCompressionOption,
- startDate: jsDateToISO8601(threeMonthsBeforeToday),
- endDate: jsDateToISO8601(today),
+ occurredAfter: jsDateToISO8601(threeMonthsBeforeToday),
+ occurredBefore: jsDateToISO8601(today),
includeDeleted: false,
dataElementIdScheme: defaultDataElementIdSchemeOption,
orgUnitIdScheme: defaultOrgUnitIdSchemeOption,
idScheme: defaultIdSchemeOption,
inclusion: defaultInclusionOption,
+ skipPaging: true,
}
const EventExport = () => {
@@ -100,10 +101,10 @@ const EventExport = () => {
-
-
+
+
-
+
diff --git a/src/pages/EventExport/form-helper.js b/src/pages/EventExport/form-helper.js
index bdecb8ff4..898d104c4 100644
--- a/src/pages/EventExport/form-helper.js
+++ b/src/pages/EventExport/form-helper.js
@@ -14,8 +14,8 @@ const onExport = (baseUrl, setExportEnabled) => (values) => {
programStage,
format,
compression,
- startDate,
- endDate,
+ occurredAfter,
+ occurredBefore,
includeDeleted,
dataElementIdScheme,
orgUnitIdScheme,
@@ -24,7 +24,7 @@ const onExport = (baseUrl, setExportEnabled) => (values) => {
} = values
// generate URL and redirect
- const apiBaseUrl = `${baseUrl}/api/`
+ const apiBaseUrl = `${baseUrl}/api/tracker/`
const endpoint = `events`
const endpointExtension = compression ? `${format}.${compression}` : format
const filename = `${endpoint}.${endpointExtension}`
@@ -38,8 +38,8 @@ const onExport = (baseUrl, setExportEnabled) => (values) => {
`orgUnitIdScheme=${orgUnitIdScheme}`,
`idScheme=${idScheme}`,
`attachment=${filename}`,
- `startDate=${startDate}`,
- `endDate=${endDate}`,
+ `occurredAfter=${occurredAfter}`,
+ `occurredBefore=${occurredBefore}`,
`ouMode=${inclusion}`,
`format=${format}`,
programStage != ALL_VALUE ? `programStage=${programStage}` : '',
@@ -47,7 +47,8 @@ const onExport = (baseUrl, setExportEnabled) => (values) => {
.filter((s) => s != '')
.join('&')
const url = `${apiBaseUrl}${endpoint}.${endpointExtension}?${downloadUrlParams}`
- locationAssign(url, setExportEnabled)
+ locationAssign(url)
+ setExportEnabled(true)
// log for debugging purposes
console.log('event-export:', { url, params: downloadUrlParams })
diff --git a/src/pages/EventImport/EventImport.js b/src/pages/EventImport/EventImport.js
index 4f9e867f9..ef0c66139 100644
--- a/src/pages/EventImport/EventImport.js
+++ b/src/pages/EventImport/EventImport.js
@@ -14,7 +14,6 @@ import {
import {
FileUpload,
Format,
- formatOptions,
defaultFormatOption,
DataElementIdScheme,
defaultDataElementIdSchemeOption,
@@ -26,6 +25,7 @@ import {
defaultOrgUnitIdSchemeOption,
ImportButtonStrip,
FormAlerts,
+ formatNoXmlOptions,
} from '../../components/Inputs/index.js'
import { TaskContext, getNewestTask } from '../../contexts/index.js'
import { getPrevJobDetails } from '../../utils/helper.js'
@@ -34,7 +34,7 @@ import { onImport } from './form-helper.js'
// PAGE INFO
export const PAGE_NAME = i18n.t('Event import')
export const PAGE_DESCRIPTION = i18n.t(
- 'Import event data for programs, stages and tracked entities to JSON, CSV, or DXF2 format.'
+ 'Import event data for programs, stages and tracked entities from JSON or CSV format.'
)
const PAGE_ICON =
@@ -95,14 +95,14 @@ const EventImport = () => {
',
}
)}
/>
diff --git a/src/pages/EventImport/form-helper.js b/src/pages/EventImport/form-helper.js
index af0ce5664..5dd6c3a1f 100644
--- a/src/pages/EventImport/form-helper.js
+++ b/src/pages/EventImport/form-helper.js
@@ -12,32 +12,27 @@ const onImport =
format,
dataElementIdScheme,
orgUnitIdScheme,
- eventIdScheme,
idScheme,
} = values
// send xhr
- const apiBaseUrl = `${baseUrl}/api/`
- const endpoint = 'events.json'
+ const apiBaseUrl = `${baseUrl}/api/tracker`
const params = [
- 'skipFirst=true',
`async=${isAsync}`,
- `dryRun=${dryRun}`,
+ `importMode=${dryRun ? 'validate' : 'commit'}`,
`dataElementIdScheme=${dataElementIdScheme}`,
`orgUnitIdScheme=${orgUnitIdScheme}`,
- `eventIdScheme=${eventIdScheme}`,
`idScheme=${idScheme}`,
- `payloadFormat=${format}`,
].join('&')
- const url = `${apiBaseUrl}${endpoint}?${params}`
+ const url = `${apiBaseUrl}?${params}`
try {
await uploadFile({
url,
file: files[0],
format: format,
- type: 'EVENT_IMPORT',
- isAsync: isAsync,
+ type: 'TRACKER_IMPORT_JOB',
+ isAsync,
setProgress,
addEntry: (id, entry) =>
addTask('event', id, { ...entry, jobDetails: values }),
diff --git a/src/pages/Home/pages.js b/src/pages/Home/pages.js
index fbacd067a..dd60f360d 100644
--- a/src/pages/Home/pages.js
+++ b/src/pages/Home/pages.js
@@ -81,7 +81,7 @@ const exportPages = capitalizePages([
{
name: TEI_EXPORT_PAGE_NAME,
description: TEI_EXPORT_DESCRIPTION,
- linkText: i18n.t('Export tracked entity instances'),
+ linkText: i18n.t('Export tracked entities'),
to: '/export/tei',
},
])
@@ -120,7 +120,7 @@ const importPages = capitalizePages([
{
name: TEI_IMPORT_PAGE_NAME,
description: TEI_IMPORT_DESCRIPTION,
- linkText: i18n.t('Import tracked entity instances'),
+ linkText: i18n.t('Import tracked entities'),
to: '/import/tei',
},
])
diff --git a/src/pages/MetadataDependencyExport/form-helper.js b/src/pages/MetadataDependencyExport/form-helper.js
index ee5e77dca..ca7dc2526 100644
--- a/src/pages/MetadataDependencyExport/form-helper.js
+++ b/src/pages/MetadataDependencyExport/form-helper.js
@@ -11,7 +11,8 @@ const onExport = (baseUrl, setExportEnabled) => (values) => {
const endpointExtension = compression ? `${format}.${compression}` : format
const downloadUrlParams = `skipSharing=${skipSharing}&download=true`
const url = `${apiBaseUrl}${endpoint}.${endpointExtension}?${downloadUrlParams}`
- locationAssign(url, setExportEnabled)
+ locationAssign(url)
+ setExportEnabled(true)
// log for debugging purposes
console.log('metadata-dependency-export:', {
diff --git a/src/pages/MetadataExport/form-helper.js b/src/pages/MetadataExport/form-helper.js
index 879f3889a..63a1cbe0b 100644
--- a/src/pages/MetadataExport/form-helper.js
+++ b/src/pages/MetadataExport/form-helper.js
@@ -12,7 +12,8 @@ const onExport = (baseUrl, setExportEnabled) => (values) => {
const schemaParams = checkedSchemas.map((name) => `${name}=true`).join('&')
const downloadUrlParams = `skipSharing=${skipSharing}&download=true&${schemaParams}`
const url = `${apiBaseUrl}${endpoint}.${endpointExtension}?${downloadUrlParams}`
- locationAssign(url, setExportEnabled)
+ locationAssign(url)
+ setExportEnabled(true)
// log for debugging purposes
console.log('metadata-export:', { url, params: downloadUrlParams })
diff --git a/src/pages/TEIExport/TEIExport.js b/src/pages/TEIExport/TEIExport.js
index c870c13b9..2acefc9df 100644
--- a/src/pages/TEIExport/TEIExport.js
+++ b/src/pages/TEIExport/TEIExport.js
@@ -12,7 +12,6 @@ import {
} from '../../components/index.js'
import {
Format,
- formatOptions,
defaultFormatOption,
OrgUnitMode,
defaultOrgUnitSelectionModeOption,
@@ -36,7 +35,6 @@ import {
AssignedUserMode,
defaultAssignedUserModeOption,
IncludeDeleted,
- IncludeAllAttributes,
DataElementIdScheme,
defaultDataElementIdSchemeOption,
EventIdScheme,
@@ -47,15 +45,16 @@ import {
defaultOrgUnitIdSchemeOption,
ExportButton,
FormAlerts,
+ formatNoXmlOptions,
} from '../../components/Inputs/index.js'
import { onExport, validate } from './form-helper.js'
const { Form } = ReactFinalForm
// PAGE INFO
-export const PAGE_NAME = i18n.t('Tracked entity instances export')
+export const PAGE_NAME = i18n.t('Tracked entities export')
export const PAGE_DESCRIPTION = i18n.t(
- 'Export tracked entity instances in JSON, CSV, or DXF2 format.'
+ 'Export tracked entities in JSON or CSV format.'
)
const PAGE_ICON =
@@ -69,18 +68,17 @@ const initialValues = {
inclusion: defaultInclusionOption,
teiTypeFilter: defaultTEITypeFilterOption,
programStatus: defaultProgramStatusOption,
- followUpStatus: defaultFollowUpStatusOption,
- programStartDate: '',
- programEndDate: '',
+ followup: defaultFollowUpStatusOption,
+ enrollmentEnrolledAfter: '',
+ enrollmentEnrolledBefore: '',
compression: '', // disable compression until it is properly implemented in the backend
lastUpdatedFilter: defaultLastUpdatedFilterOption,
- lastUpdatedStartDate: '',
- lastUpdatedEndDate: '',
- lastUpdatedDuration: '',
+ updatedAfter: '',
+ updatedBefore: '',
+ updatedWithin: '',
assignedUserModeFilter: false,
assignedUserMode: defaultAssignedUserModeOption,
includeDeleted: false,
- includeAllAttributes: false,
dataElementIdScheme: defaultDataElementIdSchemeOption,
eventIdScheme: defaultEventIdSchemeOption,
orgUnitIdScheme: defaultOrgUnitIdSchemeOption,
@@ -136,7 +134,7 @@ const TEIExport = () => {
-
+
@@ -147,7 +145,6 @@ const TEIExport = () => {
-
@@ -157,9 +154,7 @@ const TEIExport = () => {
diff --git a/src/pages/TEIExport/form-helper.js b/src/pages/TEIExport/form-helper.js
index 5f19cb647..8c9ba7e21 100644
--- a/src/pages/TEIExport/form-helper.js
+++ b/src/pages/TEIExport/form-helper.js
@@ -17,7 +17,6 @@ const valuesToParams = (
inclusion,
format,
includeDeleted,
- includeAllAttributes,
dataElementIdScheme,
eventIdScheme,
orgUnitIdScheme,
@@ -26,13 +25,13 @@ const valuesToParams = (
assignedUserMode,
teiTypeFilter,
programStatus,
- followUpStatus,
- programStartDate,
- programEndDate,
+ followup,
+ enrollmentEnrolledAfter,
+ enrollmentEnrolledBefore,
lastUpdatedFilter,
- lastUpdatedStartDate,
- lastUpdatedEndDate,
- lastUpdatedDuration,
+ updatedAfter,
+ updatedBefore,
+ updatedWithin,
},
filename
) => {
@@ -40,18 +39,18 @@ const valuesToParams = (
ouMode: ouMode,
format: format,
includeDeleted: includeDeleted.toString(),
- includeAllAttributes: includeAllAttributes.toString(),
dataElementIdScheme: dataElementIdScheme,
eventIdScheme: eventIdScheme,
orgUnitIdScheme: orgUnitIdScheme,
idScheme: idScheme,
attachment: filename,
+ skipPaging: true,
}
// include selected org.units only when manual selection is selected
// ouMode is then stored in the `inclusion` field
if (ouMode === OU_MODE_MANUAL_VALUE) {
- minParams.ou = selectedOrgUnits.map((o) => pathToId(o)).join(';')
+ minParams.orgUnit = selectedOrgUnits.map((o) => pathToId(o)).join(';')
minParams.ouMode = inclusion
}
@@ -71,14 +70,16 @@ const valuesToParams = (
minParams.programStatus = programStatus
}
- minParams.followUpStatus = followUpStatus
+ if (followup !== 'ALL') {
+ minParams.followup = followup
+ }
- if (programStartDate) {
- minParams.programStartDate = programStartDate
+ if (enrollmentEnrolledAfter) {
+ minParams.enrollmentEnrolledAfter = enrollmentEnrolledAfter
}
- if (programEndDate) {
- minParams.programEndDate = programEndDate
+ if (enrollmentEnrolledBefore) {
+ minParams.enrollmentEnrolledBefore = enrollmentEnrolledBefore
}
}
@@ -87,17 +88,17 @@ const valuesToParams = (
}
if (lastUpdatedFilter == 'DATE') {
- if (lastUpdatedStartDate) {
- minParams.lastUpdatedStartDate = lastUpdatedStartDate
+ if (updatedAfter) {
+ minParams.updatedAfter = updatedAfter
}
- if (lastUpdatedEndDate) {
- minParams.lastUpdatedEndDate = lastUpdatedEndDate
+ if (updatedBefore) {
+ minParams.updatedBefore = updatedBefore
}
}
if (lastUpdatedFilter == 'DURATION') {
- minParams.lastUpdatedDuration = lastUpdatedDuration
+ minParams.updatedWithin = updatedWithin
}
return Object.keys(minParams)
@@ -111,12 +112,13 @@ const onExport = (baseUrl, setExportEnabled) => async (values) => {
const { format } = values
// generate URL and redirect
- const apiBaseUrl = `${baseUrl}/api/`
- const endpoint = `trackedEntityInstances`
+ const apiBaseUrl = `${baseUrl}/api/tracker/`
+ const endpoint = `trackedEntities`
const filename = `${endpoint}.${format}`
const downloadUrlParams = valuesToParams(values, filename)
const url = `${apiBaseUrl}${endpoint}.${format}?${downloadUrlParams}`
- locationAssign(url, setExportEnabled)
+ locationAssign(url)
+ setExportEnabled(true)
// log for debugging purposes
console.log('tei-export:', { url, params: downloadUrlParams })
@@ -127,40 +129,40 @@ const validate = (values) => {
if (
values.teiTypeFilter == 'PROGRAM' &&
- values.programStartDate &&
- values.programEndDate
+ values.enrollmentEnrolledAfter &&
+ values.enrollmentEnrolledBefore
) {
- errors.programStartDate = DATE_BEFORE_VALIDATOR(
- values.programStartDate,
- values.programEndDate
+ errors.enrollmentEnrolledAfter = DATE_BEFORE_VALIDATOR(
+ values.enrollmentEnrolledAfter,
+ values.enrollmentEnrolledBefore
)
- errors.programEndDate = DATE_AFTER_VALIDATOR(
- values.programEndDate,
- values.programStartDate
+ errors.enrollmentEnrolledBefore = DATE_AFTER_VALIDATOR(
+ values.enrollmentEnrolledBefore,
+ values.enrollmentEnrolledAfter
)
}
if (
values.lastUpdatedFilter == 'DATE' &&
- values.lastUpdatedStartDate &&
- values.lastUpdatedEndDate
+ values.updatedAfter &&
+ values.updatedBefore
) {
- errors.lastUpdatedStartDate = DATE_BEFORE_VALIDATOR(
- values.lastUpdatedStartDate,
- values.lastUpdatedEndDate
+ errors.updatedAfter = DATE_BEFORE_VALIDATOR(
+ values.updatedAfter,
+ values.updatedBefore
)
- errors.lastUpdatedEndDate = DATE_AFTER_VALIDATOR(
- values.lastUpdatedEndDate,
- values.lastUpdatedStartDate
+ errors.updatedBefore = DATE_AFTER_VALIDATOR(
+ values.updatedBefore,
+ values.updatedAfter
)
}
if (
values.lastUpdatedFilter == 'DATE' &&
- !values.lastUpdatedStartDate &&
- !values.lastUpdatedEndDate
+ !values.updatedAfter &&
+ !values.updatedBefore
) {
- errors.lastUpdatedEndDate = i18n.t(
+ errors.updatedBefore = i18n.t(
"At least one of the 'last updated' date fields must be specified"
)
}
diff --git a/src/pages/TEIImport/TEIImport.js b/src/pages/TEIImport/TEIImport.js
index 3daed9cf9..aeb5c11d5 100644
--- a/src/pages/TEIImport/TEIImport.js
+++ b/src/pages/TEIImport/TEIImport.js
@@ -14,7 +14,6 @@ import {
import {
FileUpload,
Format,
- formatNoCsvOptions,
defaultFormatOption,
Identifier,
defaultIdentifierOption,
@@ -46,6 +45,7 @@ import {
defaultIdSchemeOption,
OrgUnitIdScheme,
defaultOrgUnitIdSchemeOption,
+ formatNoXmlNoCsvOptions,
} from '../../components/Inputs/index.js'
import { TaskContext, getNewestTask } from '../../contexts/index.js'
import { getPrevJobDetails, getInitialBoolValue } from '../../utils/helper.js'
@@ -54,9 +54,9 @@ import { onImport } from './form-helper.js'
const { Form } = ReactFinalForm
// PAGE INFO
-export const PAGE_NAME = i18n.t('Tracked entity instances import')
+export const PAGE_NAME = i18n.t('Tracked entities import')
export const PAGE_DESCRIPTION = i18n.t(
- 'Import tracked entity instances using JSON or DXF2 format.'
+ 'Import tracked entities using JSON format.'
)
const PAGE_ICON =
@@ -81,9 +81,7 @@ const createInitialValues = (prevJobDetails) => ({
prevJobDetails.skipValidation,
defaultSkipValidationOption
),
- // disable async until it is fully implemented for this resource
- // (expected 2.36)
- isAsync: false,
+ isAsync: true,
dataElementIdScheme:
prevJobDetails.dataElementIdScheme || defaultDataElementIdSchemeOption,
orgUnitIdScheme:
@@ -136,14 +134,14 @@ const TEIImport = () => {
',
}
)}
/>
diff --git a/src/pages/TEIImport/form-helper.js b/src/pages/TEIImport/form-helper.js
index d7386cbb0..ed3b60cba 100644
--- a/src/pages/TEIImport/form-helper.js
+++ b/src/pages/TEIImport/form-helper.js
@@ -26,8 +26,7 @@ const onImport =
} = values
// send xhr
- const apiBaseUrl = `${baseUrl}/api/`
- const endpoint = 'trackedEntityInstances.json'
+ const apiBaseUrl = `${baseUrl}/api/tracker/`
const params = [
`importMode=${dryRun ? 'VALIDATE' : 'COMMIT'}`,
`identifier=${identifier}`,
@@ -49,18 +48,19 @@ const onImport =
]
.filter((s) => s != '')
.join('&')
- const url = `${apiBaseUrl}${endpoint}?${params}`
+ const url = `${apiBaseUrl}?${params}`
try {
await uploadFile({
url,
file: files[0],
format: format,
- type: 'TEI_IMPORT',
+ type: 'TRACKER_IMPORT_JOB',
isAsync: isAsync,
setProgress,
- addEntry: (id, entry) =>
- addTask('tei', id, { ...entry, jobDetails: values }),
+ addEntry: (id, entry) => {
+ addTask('tei', id, { ...entry, jobDetails: values })
+ },
})
return jobStartedMessage
} catch (e) {
diff --git a/src/utils/helper.js b/src/utils/helper.js
index 5db84c3f2..853274c24 100644
--- a/src/utils/helper.js
+++ b/src/utils/helper.js
@@ -101,7 +101,8 @@ const uploadFile = ({
url,
upload: file,
type,
- onResponse: ({ error, id, msg, typeReports }) => {
+ onResponse: (response) => {
+ const { error, id, msg, typeReports } = response
let entry
if (!isAsync) {
// we are done
@@ -149,12 +150,14 @@ const uploadFile = ({
created: new Date(),
lastUpdated: new Date(),
completed: false,
- events: [msg],
+ events: [{ ...msg, date: new Date() }], // this is a workaround for the initial message date coming as invalid
+
summary: undefined,
error: false,
importType: type,
}
}
+
addEntry(entry.id, entry)
if (error) {
@@ -169,7 +172,7 @@ const uploadFile = ({
const response = JSON.parse(ev.target.response)
message = response.message
} catch (e2) {
- message = genericErrorMessage
+ message = ev
}
console.error('sendFile error', message)
reject(errF(message))
@@ -193,7 +196,7 @@ const downloadWindowHtml = `
`
// call stub function if available
-const locationAssign = (url, setExportEnabled) => {
+const locationAssign = (url) => {
if (window.locationAssign) {
window.locationAssign(url)
} else {
@@ -201,11 +204,6 @@ const locationAssign = (url, setExportEnabled) => {
downloadWindow.document.title = downloadWindowTitle
downloadWindow.document.body.innerHTML = downloadWindowHtml // does not work in Chrome
-
- const enableExport = () => setExportEnabled(true)
- downloadWindow.onbeforeunload = enableExport
- downloadWindow.onabort = enableExport
- downloadWindow.onerror = enableExport
}
}
diff --git a/src/utils/tasks.js b/src/utils/tasks.js
index b68ca447f..1179012a4 100644
--- a/src/utils/tasks.js
+++ b/src/utils/tasks.js
@@ -43,7 +43,7 @@ const categoryTypes = [
key: 'tei',
importType: 'TEI_IMPORT',
icon: ,
- label: i18n.t('TEI'),
+ label: i18n.t('Tracked entity'),
},
]