diff --git a/src/utils/helper.js b/src/utils/helper.js
index 853274c2..71c80067 100644
--- a/src/utils/helper.js
+++ b/src/utils/helper.js
@@ -188,22 +188,53 @@ const uploadFile = ({
})
}
-const downloadWindowTitle = i18n.t('Loading exported data')
-const downloadWindowHtml = `
-
-
${downloadWindowTitle}
-
-`
+const propsToInclude = [
+ 'program',
+ 'ouMode',
+ 'orgUnits',
+ 'orgUnit',
+ 'trackedEntityType',
+]
+const getParamsForFileName = (url) => {
+ const params = [...new URL(url).searchParams.entries()]
+ return params
+ .filter(([prop]) => propsToInclude.includes(prop))
+ .map(([prop, val]) => `${prop}_${val}`)
+ .join('__')
+}
// call stub function if available
-const locationAssign = (url) => {
+const locationAssign = (relativeUrl) => {
if (window.locationAssign) {
- window.locationAssign(url)
+ window.locationAssign(relativeUrl)
} else {
- const downloadWindow = window.open(url, '_blank')
+ try {
+ const url = relativeUrl.startsWith('..')
+ ? new URL(relativeUrl, document.baseURI).href
+ : relativeUrl
+
+ const requestParams = getParamsForFileName(url)
+
+ const urlFilePart = new URL(url).pathname.split('/').pop()
+ const [, file, extension] = urlFilePart.match(/(^[^.]+)(\..+$)/)
- downloadWindow.document.title = downloadWindowTitle
- downloadWindow.document.body.innerHTML = downloadWindowHtml // does not work in Chrome
+ const timeStamp = new Intl.DateTimeFormat('en-CA').format(
+ new Date()
+ ) // en-CA is yyyy-MM-dd
+
+ const downloadedFileName = `${file}_${timeStamp}_${requestParams}${extension}`
+
+ const link = document.createElement('a')
+ link.href = url
+ link.download = downloadedFileName
+ link.target = '_blank'
+ link.click()
+
+ return link
+ } catch (err) {
+ console.error(err)
+ window.open(relativeUrl, '_blank')
+ }
}
}
diff --git a/src/utils/helper.test.js b/src/utils/helper.test.js
new file mode 100644
index 00000000..b9854cb3
--- /dev/null
+++ b/src/utils/helper.test.js
@@ -0,0 +1,59 @@
+import { locationAssign } from "./helper.js"
+
+describe('locationAssign', () => {
+ beforeEach(() => {
+ jest.useFakeTimers('modern');
+ jest.setSystemTime(new Date(2024, 2, 12));
+ });
+
+ afterEach(() => {
+ jest.useRealTimers();
+ });
+
+ it('should create a file name based on the params', () => {
+ const url = 'https://debug.dhis2.org/dev/api/tracker/trackedEntities.json?ouMode=CAPTURE&format=json&includeDeleted=false&dataElementIdScheme=UID&eventIdScheme=UID&orgUnitIdScheme=UID&idScheme=UID&attachment=trackedEntities.json&paging=false&totalPages=false&program=lxAQ7Zs9VYR'
+ const link = locationAssign(url)
+ expect(link.download).toEqual('trackedEntities_2024-03-12_ouMode_CAPTURE__program_lxAQ7Zs9VYR.json')
+
+ })
+ it('should create url with orgUnits', () => {
+ const url = 'https://debug.dhis2.org/dev/api/tracker/trackedEntities.json?ouMode=SELECTED&includeDeleted=false&dataElementIdScheme=UID&eventIdScheme=UID&orgUnitIdScheme=UID&idScheme=UID&attachment=trackedEntities.json&paging=false&totalPages=false&orgUnits=O6uvpzGd5pu,fdc6uOvgoji&program=kla3mAPgvCH';
+ const link = locationAssign(url)
+ expect(link.download).toEqual('trackedEntities_2024-03-12_ouMode_SELECTED__orgUnits_O6uvpzGd5pu,fdc6uOvgoji__program_kla3mAPgvCH.json')
+ })
+ it('should create url with tracked entities', () => {
+ const url = 'https://debug.dhis2.org/dev/api/tracker/trackedEntities.json?ouMode=SELECTED&includeDeleted=false&dataElementIdScheme=UID&eventIdScheme=UID&orgUnitIdScheme=UID&idScheme=UID&attachment=trackedEntities.json&paging=false&totalPages=false&orgUnits=ImspTQPwCqd&trackedEntityType=bVkFYAvoUCP';
+ const link = locationAssign(url)
+ expect(link.download).toEqual('trackedEntities_2024-03-12_ouMode_SELECTED__orgUnits_ImspTQPwCqd__trackedEntityType_bVkFYAvoUCP.json')
+ })
+ it('should create url with CSV', () => {
+ const url = 'https://debug.dhis2.org/dev/api/tracker/trackedEntities.csv?ouMode=SELECTED&includeDeleted=false&dataElementIdScheme=UID&eventIdScheme=UID&orgUnitIdScheme=UID&idScheme=UID&attachment=trackedEntities.csv&paging=false&totalPages=false&orgUnits=ImspTQPwCqd&program=lxAQ7Zs9VYR';
+ const link = locationAssign(url)
+ expect(link.download).toEqual('trackedEntities_2024-03-12_ouMode_SELECTED__orgUnits_ImspTQPwCqd__program_lxAQ7Zs9VYR.csv')
+ })
+
+ it('should create url with events zip', () => {
+ const url = 'https://debug.dhis2.org/dev/api/tracker/events.json.zip?links=false&paging=false&totalPages=false&orgUnit=fwH9ipvXde9&program=VBqh0ynB2wv&includeDeleted=false&dataElementIdScheme=UID&orgUnitIdScheme=UID&idScheme=UID&attachment=events.json.zip&occurredAfter=2023-12-12&occurredBefore=2024-03-12&ouMode=CHILDREN&format=json';
+ const link = locationAssign(url)
+ expect(link.download).toEqual('events_2024-03-12_orgUnit_fwH9ipvXde9__program_VBqh0ynB2wv__ouMode_CHILDREN.json.zip')
+ })
+
+ it('should create url with events gzip', () => {
+ const url = 'https://debug.dhis2.org/dev/api/tracker/events.json.gz?links=false&paging=false&totalPages=false&orgUnit=ImspTQPwCqd&program=lxAQ7Zs9VYR&includeDeleted=false&dataElementIdScheme=UID&orgUnitIdScheme=UID&idScheme=UID&attachment=events.json.gz&occurredAfter=2023-12-12&occurredBefore=2024-03-12&ouMode=SELECTED&format=json';
+ const link = locationAssign(url)
+ expect(link.download).toEqual('events_2024-03-12_orgUnit_ImspTQPwCqd__program_lxAQ7Zs9VYR__ouMode_SELECTED.json.gz')
+ })
+ it('should work with relative URLs when bundled in DHIS2', () => {
+ Object.defineProperty(global.document, 'baseURI', { value: 'http://localhost:8080/dhis-web-import-export/index.html#/export/tei' });
+ const url = '../api/tracker/trackedEntities.json?ouMode=SELECTED&includeDeleted=false&dataElementIdScheme=UID&eventIdScheme=UID&orgUnitIdScheme=UID&idScheme=UID&attachment=trackedEntities.json&paging=false&totalPages=false&orgUnits=ImspTQPwCqd&program=lxAQ7Zs9VYR'
+ const link = locationAssign(url)
+ expect(link.download).toEqual('trackedEntities_2024-03-12_ouMode_SELECTED__orgUnits_ImspTQPwCqd__program_lxAQ7Zs9VYR.json')
+ })
+ it('should work with relative URLs when bundled in DHIS2 for zip', () => {
+ Object.defineProperty(global.document, 'baseURI', { value: 'http://localhost:8080/dhis-web-import-export/index.html#/export/tei' });
+ const url ='../api/tracker/events.json.zip?links=false&paging=false&totalPages=false&orgUnit=ImspTQPwCqd&program=lxAQ7Zs9VYR&includeDeleted=false&dataElementIdScheme=UID&orgUnitIdScheme=UID&idScheme=UID&attachment=events.json.zip&occurredAfter=2023-12-12&occurredBefore=2024-03-12&ouMode=SELECTED&format=json'
+ const link = locationAssign(url)
+ expect(link.download).toEqual('trackedEntities_2024-03-12_ouMode_SELECTED__orgUnits_ImspTQPwCqd__program_lxAQ7Zs9VYR.json')
+ })
+
+})
\ No newline at end of file