Skip to content

Commit 5ec3aa5

Browse files
pawelangelowvalkirilov
authored andcommitted
RI-7799: Fix download report for electron (#5293)
1 parent d89e35b commit 5ec3aa5

File tree

3 files changed

+37
-3
lines changed

3 files changed

+37
-3
lines changed

redisinsight/api/src/modules/bulk-actions/bulk-actions.service.spec.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,10 @@ describe('BulkActionsService', () => {
167167
'Content-Disposition',
168168
`attachment; filename="${expectedFilename}"`,
169169
);
170+
expect(mockResponse.setHeader).toHaveBeenCalledWith(
171+
'Access-Control-Expose-Headers',
172+
'Content-Disposition',
173+
);
170174
expect(mockResponse.setHeader).toHaveBeenCalledWith(
171175
'Transfer-Encoding',
172176
'chunked',

redisinsight/api/src/modules/bulk-actions/bulk-actions.service.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ export class BulkActionsService {
7575
'Content-Disposition',
7676
`attachment; filename="bulk-delete-report-${timestamp}.txt"`,
7777
);
78+
res.setHeader('Access-Control-Expose-Headers', 'Content-Disposition');
7879
res.setHeader('Transfer-Encoding', 'chunked');
7980

8081
// Attach the response stream to the bulk action
Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,41 @@
1+
import { CustomHeaders } from 'uiSrc/constants/api'
2+
13
/**
2-
* Triggers a file download from a URL by creating a temporary link element
4+
* Triggers a file download from a URL using fetch with proper headers
5+
* This is necessary for Electron app where window ID authentication is required
36
* @param url The full URL to download from
47
*/
5-
export const triggerDownloadFromUrl = (url: string): void => {
8+
export const triggerDownloadFromUrl = async (url: string): Promise<void> => {
9+
const headers: Record<string, string> = {}
10+
11+
// Add window ID header for Electron app authentication
12+
if (window.windowId) {
13+
headers[CustomHeaders.WindowId] = window.windowId
14+
}
15+
16+
const response = await fetch(url, { headers })
17+
18+
if (!response.ok) {
19+
throw new Error(`Download failed: ${response.statusText}`)
20+
}
21+
22+
// Extract filename from Content-Disposition header
23+
const contentDisposition = response.headers.get('content-disposition') || ''
24+
const filenameMatch = contentDisposition.match(/filename="?([^";\n]+)"?/)
25+
const filename = filenameMatch?.[1] || 'download'
26+
27+
// Convert response to blob and trigger download
28+
const blob = await response.blob()
29+
const blobUrl = URL.createObjectURL(blob)
30+
631
const link = document.createElement('a')
7-
link.href = url
32+
link.href = blobUrl
33+
link.download = filename
834
link.style.display = 'none'
935
document.body.appendChild(link)
1036
link.click()
1137
document.body.removeChild(link)
38+
39+
// Clean up the blob URL
40+
URL.revokeObjectURL(blobUrl)
1241
}

0 commit comments

Comments
 (0)