mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-08-12 00:19:48 +00:00
Merge branch 'dev' into fix-merge-apps
This commit is contained in:
@@ -1,5 +1,10 @@
|
||||
import { DatePipe } from '@angular/common'
|
||||
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
|
||||
import {
|
||||
HttpHeaders,
|
||||
HttpResponse,
|
||||
provideHttpClient,
|
||||
withInterceptorsFromDi,
|
||||
} from '@angular/common/http'
|
||||
import {
|
||||
HttpTestingController,
|
||||
provideHttpClientTesting,
|
||||
@@ -1331,6 +1336,34 @@ describe('DocumentDetailComponent', () => {
|
||||
expect(urlRevokeSpy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should download a file with the correct filename', () => {
|
||||
const mockBlob = new Blob(['test content'], { type: 'text/plain' })
|
||||
const mockResponse = new HttpResponse({
|
||||
body: mockBlob,
|
||||
headers: new HttpHeaders({
|
||||
'Content-Disposition': 'attachment; filename="test-file.txt"',
|
||||
}),
|
||||
})
|
||||
|
||||
const downloadUrl = 'http://example.com/download'
|
||||
component.documentId = 123
|
||||
jest.spyOn(documentService, 'getDownloadUrl').mockReturnValue(downloadUrl)
|
||||
|
||||
const createSpy = jest.spyOn(document, 'createElement')
|
||||
const anchor: HTMLAnchorElement = {} as HTMLAnchorElement
|
||||
createSpy.mockReturnValueOnce(anchor)
|
||||
|
||||
component.download(false)
|
||||
|
||||
httpTestingController
|
||||
.expectOne(downloadUrl)
|
||||
.flush(mockBlob, { headers: mockResponse.headers })
|
||||
|
||||
expect(createSpy).toHaveBeenCalledWith('a')
|
||||
expect(anchor.download).toBe('test-file.txt')
|
||||
createSpy.mockClear()
|
||||
})
|
||||
|
||||
it('should get email enabled status from settings', () => {
|
||||
jest.spyOn(settingsService, 'get').mockReturnValue(true)
|
||||
expect(component.emailEnabled).toBeTruthy()
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { AsyncPipe, NgTemplateOutlet } from '@angular/common'
|
||||
import { HttpClient } from '@angular/common/http'
|
||||
import { HttpClient, HttpResponse } from '@angular/common/http'
|
||||
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'
|
||||
import {
|
||||
FormArray,
|
||||
@@ -995,44 +995,48 @@ export class DocumentDetailComponent
|
||||
this.documentId,
|
||||
original
|
||||
)
|
||||
this.http.get(downloadUrl, { responseType: 'blob' }).subscribe({
|
||||
next: (blob) => {
|
||||
this.downloading = false
|
||||
const blobParts = [blob]
|
||||
const file = new File(
|
||||
blobParts,
|
||||
original
|
||||
? this.document.original_file_name
|
||||
: this.document.archived_file_name,
|
||||
{
|
||||
type: original ? this.document.mime_type : 'application/pdf',
|
||||
}
|
||||
)
|
||||
if (
|
||||
!this.deviceDetectorService.isDesktop() &&
|
||||
navigator.canShare &&
|
||||
navigator.canShare({ files: [file] })
|
||||
) {
|
||||
navigator.share({
|
||||
files: [file],
|
||||
this.http
|
||||
.get(downloadUrl, { observe: 'response', responseType: 'blob' })
|
||||
.subscribe({
|
||||
next: (response: HttpResponse<Blob>) => {
|
||||
const filename = response.headers
|
||||
.get('Content-Disposition')
|
||||
?.split(';')
|
||||
?.find((part) => part.trim().startsWith('filename='))
|
||||
?.split('=')[1]
|
||||
?.replace(/['"]/g, '')
|
||||
const blob = new Blob([response.body], {
|
||||
type: response.body.type,
|
||||
})
|
||||
} else {
|
||||
const url = URL.createObjectURL(blob)
|
||||
const a = document.createElement('a')
|
||||
a.href = url
|
||||
a.download = this.document.title
|
||||
a.click()
|
||||
URL.revokeObjectURL(url)
|
||||
}
|
||||
},
|
||||
error: (error) => {
|
||||
this.downloading = false
|
||||
this.toastService.showError(
|
||||
$localize`Error downloading document`,
|
||||
error
|
||||
)
|
||||
},
|
||||
})
|
||||
this.downloading = false
|
||||
const file = new File([blob], filename, {
|
||||
type: response.body.type,
|
||||
})
|
||||
if (
|
||||
!this.deviceDetectorService.isDesktop() &&
|
||||
navigator.canShare &&
|
||||
navigator.canShare({ files: [file] })
|
||||
) {
|
||||
navigator.share({
|
||||
files: [file],
|
||||
})
|
||||
} else {
|
||||
const url = URL.createObjectURL(blob)
|
||||
const a = document.createElement('a')
|
||||
a.href = url
|
||||
a.download = filename
|
||||
a.click()
|
||||
URL.revokeObjectURL(url)
|
||||
}
|
||||
},
|
||||
error: (error) => {
|
||||
this.downloading = false
|
||||
this.toastService.showError(
|
||||
$localize`Error downloading document`,
|
||||
error
|
||||
)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
hasNext() {
|
||||
|
@@ -5,7 +5,7 @@ export const environment = {
|
||||
apiBaseUrl: document.baseURI + 'api/',
|
||||
apiVersion: '7',
|
||||
appTitle: 'Paperless-ngx',
|
||||
version: '2.15.0',
|
||||
version: '2.15.1',
|
||||
webSocketHost: window.location.host,
|
||||
webSocketProtocol: window.location.protocol == 'https:' ? 'wss:' : 'ws:',
|
||||
webSocketBaseUrl: base_url.pathname + 'ws/',
|
||||
|
@@ -556,7 +556,7 @@
|
||||
<context context-type="sourcefile">src/app/components/admin/config/config.component.html</context>
|
||||
<context context-type="linenumber">2</context>
|
||||
</context-group>
|
||||
<target state="translated">應用程式設定</target>
|
||||
<target state="translated">系統配置</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="8528041182664173532" datatype="html">
|
||||
<source>Global app configuration options which apply to <strong>every</strong> user of this install of Paperless-ngx. Options can also be set using environment variables or the configuration file but the value here will always take precedence.</source>
|
||||
@@ -564,7 +564,7 @@
|
||||
<context context-type="sourcefile">src/app/components/admin/config/config.component.html</context>
|
||||
<context context-type="linenumber">4</context>
|
||||
</context-group>
|
||||
<target state="translated">全域應用程式設定選項適用於此安裝版本的<strong>每位</strong>使用者。雖然也可以透過環境變數或設定檔來設定,但這裡的設定將始終優先於其他設定。</target>
|
||||
<target state="translated">全域系統配置會套用至該系統的<strong>每一位</strong>使用者。雖然環境變數或設定檔也可以調整相關設定,但此處的設定將優先於他處的設定。</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="7991430199894172363" datatype="html">
|
||||
<source>Read the documentation about this setting</source>
|
||||
@@ -864,7 +864,7 @@
|
||||
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
|
||||
<context context-type="linenumber">4</context>
|
||||
</context-group>
|
||||
<target state="translated">自訂外觀、通知等選項。設定只適用於<strong>目前使用者</strong>。</target>
|
||||
<target state="translated">自訂外觀、通知等選項。這些設定只套用於<strong>目前的使用者</strong>。</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="1685061484835793745" datatype="html">
|
||||
<source>Start tour</source>
|
||||
|
Reference in New Issue
Block a user