mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-10-30 03:56:23 -05:00 
			
		
		
		
	Add bulk download options dropdown
This commit is contained in:
		 Michael Shamoon
					Michael Shamoon
				
			
				
					committed by
					
						 Trenton H
						Trenton H
					
				
			
			
				
	
			
			
			 Trenton H
						Trenton H
					
				
			
						parent
						
							447a892f17
						
					
				
				
					commit
					c24dc0f792
				
			| @@ -66,7 +66,6 @@ | |||||||
|   </div> |   </div> | ||||||
|   <div class="col-auto ms-auto mb-2 mb-xl-0 d-flex"> |   <div class="col-auto ms-auto mb-2 mb-xl-0 d-flex"> | ||||||
|     <div class="btn-group btn-group-sm me-2"> |     <div class="btn-group btn-group-sm me-2"> | ||||||
|  |  | ||||||
|       <div ngbDropdown class="me-2 d-flex"> |       <div ngbDropdown class="me-2 d-flex"> | ||||||
|         <button class="btn btn-sm btn-outline-primary" id="dropdownSelect" ngbDropdownToggle> |         <button class="btn btn-sm btn-outline-primary" id="dropdownSelect" ngbDropdownToggle> | ||||||
|           <svg class="toolbaricon" fill="currentColor"> |           <svg class="toolbaricon" fill="currentColor"> | ||||||
| @@ -75,26 +74,57 @@ | |||||||
|           <div class="d-none d-sm-inline"> <ng-container i18n>Actions</ng-container></div> |           <div class="d-none d-sm-inline"> <ng-container i18n>Actions</ng-container></div> | ||||||
|         </button> |         </button> | ||||||
|         <div ngbDropdownMenu aria-labelledby="dropdownSelect" class="shadow"> |         <div ngbDropdownMenu aria-labelledby="dropdownSelect" class="shadow"> | ||||||
|           <button ngbDropdownItem [disabled]="awaitingDownload" (click)="downloadSelected()" i18n> |  | ||||||
|             Download |  | ||||||
|             <div *ngIf="awaitingDownload" class="spinner-border spinner-border-sm" role="status"> |  | ||||||
|               <span class="visually-hidden">Preparing download...</span> |  | ||||||
|             </div> |  | ||||||
|           </button> |  | ||||||
|           <button ngbDropdownItem [disabled]="awaitingDownload" (click)="downloadSelected('originals')" i18n> |  | ||||||
|             Download originals |  | ||||||
|             <div *ngIf="awaitingDownload" class="spinner-border spinner-border-sm" role="status"> |  | ||||||
|               <span class="visually-hidden">Preparing download...</span> |  | ||||||
|             </div> |  | ||||||
|           </button> |  | ||||||
|           <button ngbDropdownItem (click)="redoOcrSelected()" i18n>Redo OCR</button> |           <button ngbDropdownItem (click)="redoOcrSelected()" i18n>Redo OCR</button> | ||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|     <button type="button" class="btn btn-sm btn-outline-danger" (click)="applyDelete()"> |     <div class="btn-group btn-group-sm me-2"> | ||||||
|       <svg width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor"> |       <button class="btn btn-sm btn-outline-primary" [disabled]="awaitingDownload" (click)="downloadSelected()"> | ||||||
|         <use xlink:href="assets/bootstrap-icons.svg#trash" /> |         <svg *ngIf="!awaitingDownload" class="toolbaricon" fill="currentColor"> | ||||||
|       </svg> <ng-container i18n>Delete</ng-container> |           <use xlink:href="assets/bootstrap-icons.svg#arrow-down" /> | ||||||
|     </button> |         </svg> | ||||||
|  |         <div *ngIf="awaitingDownload" class="spinner-border spinner-border-sm" role="status"> | ||||||
|  |           <span class="visually-hidden">Preparing download...</span> | ||||||
|  |         </div> | ||||||
|  |         <div class="d-none d-sm-inline"> <ng-container i18n>Download</ng-container></div> | ||||||
|  |       </button> | ||||||
|  |       <div ngbDropdown class="me-2 d-flex btn-group" role="group"> | ||||||
|  |         <button type="button" class="btn btn-sm btn-outline-primary dropdown-toggle-split rounded-end" ngbDropdownToggle></button> | ||||||
|  |         <div ngbDropdownMenu aria-labelledby="dropdownSelect" class="shadow"> | ||||||
|  | 					<form [formGroup]="downloadForm" class="px-3 py-1"> | ||||||
|  |             <p class="mb-1" i18n>Include:</p> | ||||||
|  |             <div class="form-group ps-3 mb-2"> | ||||||
|  |               <div class="form-check"> | ||||||
|  |                 <input type="checkbox" class="form-check-input" id="downloadFileType_archive" formControlName="downloadFileTypeArchive" /> | ||||||
|  |                 <label class="form-check-label" for="downloadFileType_archive" i18n> | ||||||
|  |                   Archived files | ||||||
|  |                 </label> | ||||||
|  |               </div> | ||||||
|  |               <div class="form-check"> | ||||||
|  |                 <input type="checkbox" class="form-check-input" id="downloadFileType_originals" formControlName="downloadFileTypeOriginals" /> | ||||||
|  |                 <label class="form-check-label" for="downloadFileType_originals" i18n> | ||||||
|  |                   Original files | ||||||
|  |                 </label> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |             <div class="form-check"> | ||||||
|  |               <input type="checkbox" class="form-check-input" id="downloadUseFormatting" formControlName="downloadUseFormatting" /> | ||||||
|  |               <label class="form-check-label" for="downloadUseFormatting" i18n> | ||||||
|  |                 Use formatted filename | ||||||
|  |               </label> | ||||||
|  |             </div> | ||||||
|  |           </form> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |     <div class="btn-group btn-group-sm me-2"> | ||||||
|  |       <button type="button" class="btn btn-sm btn-outline-danger" (click)="applyDelete()"> | ||||||
|  |         <svg width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor"> | ||||||
|  |           <use xlink:href="assets/bootstrap-icons.svg#trash" /> | ||||||
|  |         </svg> <ng-container i18n>Delete</ng-container> | ||||||
|  |       </button> | ||||||
|  |     </div> | ||||||
|   </div> |   </div> | ||||||
| </div> | </div> | ||||||
|   | |||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | .dropdown-toggle-split { | ||||||
|  |     --bs-border-radius: .25rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .dropdown-menu{ | ||||||
|  |     --bs-dropdown-min-width: 12rem; | ||||||
|  | } | ||||||
|   | |||||||
| @@ -25,6 +25,8 @@ import { saveAs } from 'file-saver' | |||||||
| import { StoragePathService } from 'src/app/services/rest/storage-path.service' | import { StoragePathService } from 'src/app/services/rest/storage-path.service' | ||||||
| import { PaperlessStoragePath } from 'src/app/data/paperless-storage-path' | import { PaperlessStoragePath } from 'src/app/data/paperless-storage-path' | ||||||
| import { SETTINGS_KEYS } from 'src/app/data/paperless-uisettings' | import { SETTINGS_KEYS } from 'src/app/data/paperless-uisettings' | ||||||
|  | import { FormControl, FormGroup } from '@angular/forms' | ||||||
|  | import { first, Subject, takeUntil } from 'rxjs' | ||||||
|  |  | ||||||
| @Component({ | @Component({ | ||||||
|   selector: 'app-bulk-editor', |   selector: 'app-bulk-editor', | ||||||
| @@ -43,6 +45,14 @@ export class BulkEditorComponent { | |||||||
|   storagePathsSelectionModel = new FilterableDropdownSelectionModel() |   storagePathsSelectionModel = new FilterableDropdownSelectionModel() | ||||||
|   awaitingDownload: boolean |   awaitingDownload: boolean | ||||||
|  |  | ||||||
|  |   unsubscribeNotifier: Subject<any> = new Subject() | ||||||
|  |  | ||||||
|  |   downloadForm = new FormGroup({ | ||||||
|  |     downloadFileTypeArchive: new FormControl(true), | ||||||
|  |     downloadFileTypeOriginals: new FormControl(false), | ||||||
|  |     downloadUseFormatting: new FormControl(false), | ||||||
|  |   }) | ||||||
|  |  | ||||||
|   constructor( |   constructor( | ||||||
|     private documentTypeService: DocumentTypeService, |     private documentTypeService: DocumentTypeService, | ||||||
|     private tagService: TagService, |     private tagService: TagService, | ||||||
| @@ -66,16 +76,46 @@ export class BulkEditorComponent { | |||||||
|   ngOnInit() { |   ngOnInit() { | ||||||
|     this.tagService |     this.tagService | ||||||
|       .listAll() |       .listAll() | ||||||
|  |       .pipe(first()) | ||||||
|       .subscribe((result) => (this.tags = result.results)) |       .subscribe((result) => (this.tags = result.results)) | ||||||
|     this.correspondentService |     this.correspondentService | ||||||
|       .listAll() |       .listAll() | ||||||
|  |       .pipe(first()) | ||||||
|       .subscribe((result) => (this.correspondents = result.results)) |       .subscribe((result) => (this.correspondents = result.results)) | ||||||
|     this.documentTypeService |     this.documentTypeService | ||||||
|       .listAll() |       .listAll() | ||||||
|  |       .pipe(first()) | ||||||
|       .subscribe((result) => (this.documentTypes = result.results)) |       .subscribe((result) => (this.documentTypes = result.results)) | ||||||
|     this.storagePathService |     this.storagePathService | ||||||
|       .listAll() |       .listAll() | ||||||
|  |       .pipe(first()) | ||||||
|       .subscribe((result) => (this.storagePaths = result.results)) |       .subscribe((result) => (this.storagePaths = result.results)) | ||||||
|  |  | ||||||
|  |     this.downloadForm | ||||||
|  |       .get('downloadFileTypeArchive') | ||||||
|  |       .valueChanges.pipe(takeUntil(this.unsubscribeNotifier)) | ||||||
|  |       .subscribe((newValue) => { | ||||||
|  |         if (!newValue) { | ||||||
|  |           this.downloadForm | ||||||
|  |             .get('downloadFileTypeOriginals') | ||||||
|  |             .patchValue(true, { emitEvent: false }) | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     this.downloadForm | ||||||
|  |       .get('downloadFileTypeOriginals') | ||||||
|  |       .valueChanges.pipe(takeUntil(this.unsubscribeNotifier)) | ||||||
|  |       .subscribe((newValue) => { | ||||||
|  |         if (!newValue) { | ||||||
|  |           this.downloadForm | ||||||
|  |             .get('downloadFileTypeArchive') | ||||||
|  |             .patchValue(true, { emitEvent: false }) | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   ngOnDestroy(): void { | ||||||
|  |     this.unsubscribeNotifier.next(this) | ||||||
|  |     this.unsubscribeNotifier.complete() | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private executeBulkOperation(modal, method: string, args) { |   private executeBulkOperation(modal, method: string, args) { | ||||||
| @@ -84,8 +124,9 @@ export class BulkEditorComponent { | |||||||
|     } |     } | ||||||
|     this.documentService |     this.documentService | ||||||
|       .bulkEdit(Array.from(this.list.selected), method, args) |       .bulkEdit(Array.from(this.list.selected), method, args) | ||||||
|       .subscribe( |       .pipe(first()) | ||||||
|         (response) => { |       .subscribe({ | ||||||
|  |         next: () => { | ||||||
|           this.list.reload() |           this.list.reload() | ||||||
|           this.list.reduceSelectionToFilter() |           this.list.reduceSelectionToFilter() | ||||||
|           this.list.selected.forEach((id) => { |           this.list.selected.forEach((id) => { | ||||||
| @@ -95,7 +136,7 @@ export class BulkEditorComponent { | |||||||
|             modal.close() |             modal.close() | ||||||
|           } |           } | ||||||
|         }, |         }, | ||||||
|         (error) => { |         error: (error) => { | ||||||
|           if (modal) { |           if (modal) { | ||||||
|             modal.componentInstance.buttonsEnabled = true |             modal.componentInstance.buttonsEnabled = true | ||||||
|           } |           } | ||||||
| @@ -104,8 +145,8 @@ export class BulkEditorComponent { | |||||||
|               error.error |               error.error | ||||||
|             )}` |             )}` | ||||||
|           ) |           ) | ||||||
|         } |         }, | ||||||
|       ) |       }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private applySelectionData( |   private applySelectionData( | ||||||
| @@ -126,6 +167,7 @@ export class BulkEditorComponent { | |||||||
|   openTagsDropdown() { |   openTagsDropdown() { | ||||||
|     this.documentService |     this.documentService | ||||||
|       .getSelectionData(Array.from(this.list.selected)) |       .getSelectionData(Array.from(this.list.selected)) | ||||||
|  |       .pipe(first()) | ||||||
|       .subscribe((s) => { |       .subscribe((s) => { | ||||||
|         this.applySelectionData(s.selected_tags, this.tagSelectionModel) |         this.applySelectionData(s.selected_tags, this.tagSelectionModel) | ||||||
|       }) |       }) | ||||||
| @@ -134,6 +176,7 @@ export class BulkEditorComponent { | |||||||
|   openDocumentTypeDropdown() { |   openDocumentTypeDropdown() { | ||||||
|     this.documentService |     this.documentService | ||||||
|       .getSelectionData(Array.from(this.list.selected)) |       .getSelectionData(Array.from(this.list.selected)) | ||||||
|  |       .pipe(first()) | ||||||
|       .subscribe((s) => { |       .subscribe((s) => { | ||||||
|         this.applySelectionData( |         this.applySelectionData( | ||||||
|           s.selected_document_types, |           s.selected_document_types, | ||||||
| @@ -145,6 +188,7 @@ export class BulkEditorComponent { | |||||||
|   openCorrespondentDropdown() { |   openCorrespondentDropdown() { | ||||||
|     this.documentService |     this.documentService | ||||||
|       .getSelectionData(Array.from(this.list.selected)) |       .getSelectionData(Array.from(this.list.selected)) | ||||||
|  |       .pipe(first()) | ||||||
|       .subscribe((s) => { |       .subscribe((s) => { | ||||||
|         this.applySelectionData( |         this.applySelectionData( | ||||||
|           s.selected_correspondents, |           s.selected_correspondents, | ||||||
| @@ -156,6 +200,7 @@ export class BulkEditorComponent { | |||||||
|   openStoragePathDropdown() { |   openStoragePathDropdown() { | ||||||
|     this.documentService |     this.documentService | ||||||
|       .getSelectionData(Array.from(this.list.selected)) |       .getSelectionData(Array.from(this.list.selected)) | ||||||
|  |       .pipe(first()) | ||||||
|       .subscribe((s) => { |       .subscribe((s) => { | ||||||
|         this.applySelectionData( |         this.applySelectionData( | ||||||
|           s.selected_storage_paths, |           s.selected_storage_paths, | ||||||
| @@ -232,12 +277,14 @@ export class BulkEditorComponent { | |||||||
|  |  | ||||||
|       modal.componentInstance.btnClass = 'btn-warning' |       modal.componentInstance.btnClass = 'btn-warning' | ||||||
|       modal.componentInstance.btnCaption = $localize`Confirm` |       modal.componentInstance.btnCaption = $localize`Confirm` | ||||||
|       modal.componentInstance.confirmClicked.subscribe(() => { |       modal.componentInstance.confirmClicked | ||||||
|         this.executeBulkOperation(modal, 'modify_tags', { |         .pipe(takeUntil(this.unsubscribeNotifier)) | ||||||
|           add_tags: changedTags.itemsToAdd.map((t) => t.id), |         .subscribe(() => { | ||||||
|           remove_tags: changedTags.itemsToRemove.map((t) => t.id), |           this.executeBulkOperation(modal, 'modify_tags', { | ||||||
|  |             add_tags: changedTags.itemsToAdd.map((t) => t.id), | ||||||
|  |             remove_tags: changedTags.itemsToRemove.map((t) => t.id), | ||||||
|  |           }) | ||||||
|         }) |         }) | ||||||
|       }) |  | ||||||
|     } else { |     } else { | ||||||
|       this.executeBulkOperation(null, 'modify_tags', { |       this.executeBulkOperation(null, 'modify_tags', { | ||||||
|         add_tags: changedTags.itemsToAdd.map((t) => t.id), |         add_tags: changedTags.itemsToAdd.map((t) => t.id), | ||||||
| @@ -270,11 +317,13 @@ export class BulkEditorComponent { | |||||||
|       } |       } | ||||||
|       modal.componentInstance.btnClass = 'btn-warning' |       modal.componentInstance.btnClass = 'btn-warning' | ||||||
|       modal.componentInstance.btnCaption = $localize`Confirm` |       modal.componentInstance.btnCaption = $localize`Confirm` | ||||||
|       modal.componentInstance.confirmClicked.subscribe(() => { |       modal.componentInstance.confirmClicked | ||||||
|         this.executeBulkOperation(modal, 'set_correspondent', { |         .pipe(takeUntil(this.unsubscribeNotifier)) | ||||||
|           correspondent: correspondent ? correspondent.id : null, |         .subscribe(() => { | ||||||
|  |           this.executeBulkOperation(modal, 'set_correspondent', { | ||||||
|  |             correspondent: correspondent ? correspondent.id : null, | ||||||
|  |           }) | ||||||
|         }) |         }) | ||||||
|       }) |  | ||||||
|     } else { |     } else { | ||||||
|       this.executeBulkOperation(null, 'set_correspondent', { |       this.executeBulkOperation(null, 'set_correspondent', { | ||||||
|         correspondent: correspondent ? correspondent.id : null, |         correspondent: correspondent ? correspondent.id : null, | ||||||
| @@ -306,11 +355,13 @@ export class BulkEditorComponent { | |||||||
|       } |       } | ||||||
|       modal.componentInstance.btnClass = 'btn-warning' |       modal.componentInstance.btnClass = 'btn-warning' | ||||||
|       modal.componentInstance.btnCaption = $localize`Confirm` |       modal.componentInstance.btnCaption = $localize`Confirm` | ||||||
|       modal.componentInstance.confirmClicked.subscribe(() => { |       modal.componentInstance.confirmClicked | ||||||
|         this.executeBulkOperation(modal, 'set_document_type', { |         .pipe(takeUntil(this.unsubscribeNotifier)) | ||||||
|           document_type: documentType ? documentType.id : null, |         .subscribe(() => { | ||||||
|  |           this.executeBulkOperation(modal, 'set_document_type', { | ||||||
|  |             document_type: documentType ? documentType.id : null, | ||||||
|  |           }) | ||||||
|         }) |         }) | ||||||
|       }) |  | ||||||
|     } else { |     } else { | ||||||
|       this.executeBulkOperation(null, 'set_document_type', { |       this.executeBulkOperation(null, 'set_document_type', { | ||||||
|         document_type: documentType ? documentType.id : null, |         document_type: documentType ? documentType.id : null, | ||||||
| @@ -342,11 +393,13 @@ export class BulkEditorComponent { | |||||||
|       } |       } | ||||||
|       modal.componentInstance.btnClass = 'btn-warning' |       modal.componentInstance.btnClass = 'btn-warning' | ||||||
|       modal.componentInstance.btnCaption = $localize`Confirm` |       modal.componentInstance.btnCaption = $localize`Confirm` | ||||||
|       modal.componentInstance.confirmClicked.subscribe(() => { |       modal.componentInstance.confirmClicked | ||||||
|         this.executeBulkOperation(modal, 'set_storage_path', { |         .pipe(takeUntil(this.unsubscribeNotifier)) | ||||||
|           storage_path: storagePath ? storagePath.id : null, |         .subscribe(() => { | ||||||
|  |           this.executeBulkOperation(modal, 'set_storage_path', { | ||||||
|  |             storage_path: storagePath ? storagePath.id : null, | ||||||
|  |           }) | ||||||
|         }) |         }) | ||||||
|       }) |  | ||||||
|     } else { |     } else { | ||||||
|       this.executeBulkOperation(null, 'set_storage_path', { |       this.executeBulkOperation(null, 'set_storage_path', { | ||||||
|         storage_path: storagePath ? storagePath.id : null, |         storage_path: storagePath ? storagePath.id : null, | ||||||
| @@ -364,16 +417,30 @@ export class BulkEditorComponent { | |||||||
|     modal.componentInstance.message = $localize`This operation cannot be undone.` |     modal.componentInstance.message = $localize`This operation cannot be undone.` | ||||||
|     modal.componentInstance.btnClass = 'btn-danger' |     modal.componentInstance.btnClass = 'btn-danger' | ||||||
|     modal.componentInstance.btnCaption = $localize`Delete document(s)` |     modal.componentInstance.btnCaption = $localize`Delete document(s)` | ||||||
|     modal.componentInstance.confirmClicked.subscribe(() => { |     modal.componentInstance.confirmClicked | ||||||
|       modal.componentInstance.buttonsEnabled = false |       .pipe(takeUntil(this.unsubscribeNotifier)) | ||||||
|       this.executeBulkOperation(modal, 'delete', {}) |       .subscribe(() => { | ||||||
|     }) |         modal.componentInstance.buttonsEnabled = false | ||||||
|  |         this.executeBulkOperation(modal, 'delete', {}) | ||||||
|  |       }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   downloadSelected(content = 'archive') { |   downloadSelected() { | ||||||
|     this.awaitingDownload = true |     this.awaitingDownload = true | ||||||
|  |     let downloadFileType: string = | ||||||
|  |       this.downloadForm.get('downloadFileTypeArchive').value && | ||||||
|  |       this.downloadForm.get('downloadFileTypeOriginals').value | ||||||
|  |         ? 'both' | ||||||
|  |         : this.downloadForm.get('downloadFileTypeArchive').value | ||||||
|  |         ? 'archive' | ||||||
|  |         : 'originals' | ||||||
|     this.documentService |     this.documentService | ||||||
|       .bulkDownload(Array.from(this.list.selected), content) |       .bulkDownload( | ||||||
|  |         Array.from(this.list.selected), | ||||||
|  |         downloadFileType, | ||||||
|  |         this.downloadForm.get('downloadUseFormatting').value | ||||||
|  |       ) | ||||||
|  |       .pipe(first()) | ||||||
|       .subscribe((result: any) => { |       .subscribe((result: any) => { | ||||||
|         saveAs(result, 'documents.zip') |         saveAs(result, 'documents.zip') | ||||||
|         this.awaitingDownload = false |         this.awaitingDownload = false | ||||||
| @@ -389,9 +456,11 @@ export class BulkEditorComponent { | |||||||
|     modal.componentInstance.message = $localize`This operation cannot be undone.` |     modal.componentInstance.message = $localize`This operation cannot be undone.` | ||||||
|     modal.componentInstance.btnClass = 'btn-danger' |     modal.componentInstance.btnClass = 'btn-danger' | ||||||
|     modal.componentInstance.btnCaption = $localize`Proceed` |     modal.componentInstance.btnCaption = $localize`Proceed` | ||||||
|     modal.componentInstance.confirmClicked.subscribe(() => { |     modal.componentInstance.confirmClicked | ||||||
|       modal.componentInstance.buttonsEnabled = false |       .pipe(takeUntil(this.unsubscribeNotifier)) | ||||||
|       this.executeBulkOperation(modal, 'redo_ocr', {}) |       .subscribe(() => { | ||||||
|     }) |         modal.componentInstance.buttonsEnabled = false | ||||||
|  |         this.executeBulkOperation(modal, 'redo_ocr', {}) | ||||||
|  |       }) | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -174,10 +174,18 @@ export class DocumentService extends AbstractPaperlessService<PaperlessDocument> | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   bulkDownload(ids: number[], content = 'both') { |   bulkDownload( | ||||||
|  |     ids: number[], | ||||||
|  |     content = 'both', | ||||||
|  |     useFilenameFormatting: boolean = false | ||||||
|  |   ) { | ||||||
|     return this.http.post( |     return this.http.post( | ||||||
|       this.getResourceUrl(null, 'bulk_download'), |       this.getResourceUrl(null, 'bulk_download'), | ||||||
|       { documents: ids, content: content }, |       { | ||||||
|  |         documents: ids, | ||||||
|  |         content: content, | ||||||
|  |         follow_formatting: useFilenameFormatting, | ||||||
|  |       }, | ||||||
|       { responseType: 'blob' } |       { responseType: 'blob' } | ||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -203,9 +203,13 @@ $form-check-radio-checked-bg-image-dark: url("data:image/svg+xml,<svg xmlns='htt | |||||||
|   .toast, |   .toast, | ||||||
|   .toast .toast-header, |   .toast .toast-header, | ||||||
|   .toast .btn, |   .toast .btn, | ||||||
|   .toast .btn-close, { |   .toast .btn-close { | ||||||
|     color: var(--pngx-primary-text-contrast); |     color: var(--pngx-primary-text-contrast); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   .dropdown-menu { | ||||||
|  |     --bs-dropdown-color: var(--bs-body-color); | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| body.color-scheme-dark { | body.color-scheme-dark { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user