mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-10-30 03:56:23 -05:00 
			
		
		
		
	fixes #98
This commit is contained in:
		| @@ -9,8 +9,8 @@ | ||||
|       <p *ngIf="message">{{message}}</p> | ||||
|     </div> | ||||
|     <div class="modal-footer"> | ||||
|       <button type="button" class="btn btn-outline-dark" (click)="cancelClicked()">Cancel</button> | ||||
|       <button type="button" class="btn" [class]="btnClass" (click)="confirmClicked.emit()" [disabled]="!confirmButtonEnabled"> | ||||
|       <button type="button" class="btn btn-outline-dark" (click)="cancelClicked()" [disabled]="!buttonsEnabled">Cancel</button> | ||||
|       <button type="button" class="btn" [class]="btnClass" (click)="confirmClicked.emit()" [disabled]="!confirmButtonEnabled || !buttonsEnabled"> | ||||
|         {{btnCaption}} | ||||
|         <span *ngIf="!confirmButtonEnabled"> ({{seconds}})</span> | ||||
|       </button> | ||||
|   | ||||
| @@ -28,6 +28,9 @@ export class ConfirmDialogComponent implements OnInit { | ||||
|   @Input() | ||||
|   btnCaption = $localize`Confirm` | ||||
|  | ||||
|   @Input() | ||||
|   buttonsEnabled = true | ||||
|    | ||||
|   confirmButtonEnabled = true | ||||
|   seconds = 0 | ||||
|  | ||||
|   | ||||
| @@ -127,9 +127,9 @@ | ||||
|  | ||||
|             <div [ngbNavOutlet]="nav" class="mt-2"></div> | ||||
|  | ||||
|             <button type="button" class="btn btn-outline-secondary" (click)="discard()" i18n>Discard</button>  | ||||
|             <button type="button" class="btn btn-outline-primary" (click)="saveEditNext()" *ngIf="hasNext()" i18n>Save & next</button>  | ||||
|             <button type="submit" class="btn btn-primary" i18n>Save</button>  | ||||
|             <button type="button" class="btn btn-outline-secondary" (click)="discard()" i18n [disabled]="networkActive">Discard</button>  | ||||
|             <button type="button" class="btn btn-outline-primary" (click)="saveEditNext()" *ngIf="hasNext()" i18n [disabled]="networkActive">Save & next</button>  | ||||
|             <button type="submit" class="btn btn-primary" i18n [disabled]="networkActive">Save</button>  | ||||
|         </form> | ||||
|     </div> | ||||
|  | ||||
|   | ||||
| @@ -16,6 +16,7 @@ import { ConfirmDialogComponent } from '../common/confirm-dialog/confirm-dialog. | ||||
| import { CorrespondentEditDialogComponent } from '../manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component'; | ||||
| import { DocumentTypeEditDialogComponent } from '../manage/document-type-list/document-type-edit-dialog/document-type-edit-dialog.component'; | ||||
| import { PDFDocumentProxy } from 'ng2-pdf-viewer'; | ||||
| import { ToastService } from 'src/app/services/toast.service'; | ||||
|  | ||||
| @Component({ | ||||
|   selector: 'app-document-detail', | ||||
| @@ -64,7 +65,8 @@ export class DocumentDetailComponent implements OnInit { | ||||
|     private modalService: NgbModal, | ||||
|     private openDocumentService: OpenDocumentsService, | ||||
|     private documentListViewService: DocumentListViewService, | ||||
|     private documentTitlePipe: DocumentTitlePipe) { } | ||||
|     private documentTitlePipe: DocumentTitlePipe, | ||||
|     private toastService: ToastService) { } | ||||
|  | ||||
|   getContentType() { | ||||
|     return this.metadata?.has_archive_version ? 'application/pdf' : this.metadata?.original_mime_type | ||||
| @@ -182,9 +184,13 @@ export class DocumentDetailComponent implements OnInit { | ||||
|     modal.componentInstance.btnClass = "btn-danger" | ||||
|     modal.componentInstance.btnCaption = $localize`Delete document` | ||||
|     modal.componentInstance.confirmClicked.subscribe(() => { | ||||
|       modal.componentInstance.buttonsEnabled = false | ||||
|       this.documentsService.delete(this.document).subscribe(() => { | ||||
|         modal.close() | ||||
|         this.close() | ||||
|       }, error => { | ||||
|         this.toastService.showError($localize`Error deleting document: ${JSON.stringify(error)}`) | ||||
|         modal.componentInstance.buttonsEnabled = true | ||||
|       }) | ||||
|     }) | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,4 @@ | ||||
| import { Component } from '@angular/core'; | ||||
| import { Observable } from 'rxjs'; | ||||
| import { tap } from 'rxjs/operators'; | ||||
| import { PaperlessTag } from 'src/app/data/paperless-tag'; | ||||
| import { PaperlessCorrespondent } from 'src/app/data/paperless-correspondent'; | ||||
| import { PaperlessDocumentType } from 'src/app/data/paperless-document-type'; | ||||
| @@ -16,6 +14,7 @@ import { ChangedItems, FilterableDropdownSelectionModel } from '../../common/fil | ||||
| import { ToggleableItemState } from '../../common/filterable-dropdown/toggleable-dropdown-button/toggleable-dropdown-button.component'; | ||||
| import { MatchingModel } from 'src/app/data/matching-model'; | ||||
| import { SettingsService, SETTINGS_KEYS } from 'src/app/services/settings.service'; | ||||
| import { ToastService } from 'src/app/services/toast.service'; | ||||
|  | ||||
| @Component({ | ||||
|   selector: 'app-bulk-editor', | ||||
| @@ -40,7 +39,8 @@ export class BulkEditorComponent { | ||||
|     private documentService: DocumentService, | ||||
|     private modalService: NgbModal, | ||||
|     private openDocumentService: OpenDocumentsService, | ||||
|     private settings: SettingsService | ||||
|     private settings: SettingsService, | ||||
|     private toastService: ToastService | ||||
|   ) { } | ||||
|  | ||||
|   applyOnClose: boolean = this.settings.get(SETTINGS_KEYS.BULK_EDIT_APPLY_ON_CLOSE) | ||||
| @@ -52,15 +52,26 @@ export class BulkEditorComponent { | ||||
|     this.documentTypeService.listAll().subscribe(result => this.documentTypes = result.results) | ||||
|   } | ||||
|  | ||||
|   private executeBulkOperation(method: string, args): Observable<any> { | ||||
|     return this.documentService.bulkEdit(Array.from(this.list.selected), method, args).pipe( | ||||
|       tap(() => { | ||||
|   private executeBulkOperation(modal, method: string, args) { | ||||
|     if (modal) { | ||||
|       modal.componentInstance.buttonsEnabled = false | ||||
|     } | ||||
|     this.documentService.bulkEdit(Array.from(this.list.selected), method, args).subscribe( | ||||
|       response => { | ||||
|         this.list.reload() | ||||
|         this.list.reduceSelectionToFilter() | ||||
|         this.list.selected.forEach(id => { | ||||
|           this.openDocumentService.refreshDocument(id) | ||||
|         }) | ||||
|       }) | ||||
|         if (modal) { | ||||
|           modal.close() | ||||
|         } | ||||
|       }, error => { | ||||
|         if (modal) { | ||||
|           modal.componentInstance.buttonsEnabled = true | ||||
|         } | ||||
|         this.toastService.showError($localize`Error executing bulk operation: ${JSON.stringify(error.error)}`) | ||||
|       } | ||||
|     ) | ||||
|   } | ||||
|  | ||||
| @@ -130,23 +141,13 @@ export class BulkEditorComponent { | ||||
|       modal.componentInstance.btnClass = "btn-warning" | ||||
|       modal.componentInstance.btnCaption = $localize`Confirm` | ||||
|       modal.componentInstance.confirmClicked.subscribe(() => { | ||||
|         this.performSetTags(modal, changedTags) | ||||
|         this.executeBulkOperation(modal, 'modify_tags', {"add_tags": changedTags.itemsToAdd.map(t => t.id), "remove_tags": changedTags.itemsToRemove.map(t => t.id)}) | ||||
|       }) | ||||
|     } else { | ||||
|       this.performSetTags(null, changedTags) | ||||
|       this.executeBulkOperation(null, 'modify_tags', {"add_tags": changedTags.itemsToAdd.map(t => t.id), "remove_tags": changedTags.itemsToRemove.map(t => t.id)}) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   private performSetTags(modal, changedTags: ChangedItems) { | ||||
|     this.executeBulkOperation('modify_tags', {"add_tags": changedTags.itemsToAdd.map(t => t.id), "remove_tags": changedTags.itemsToRemove.map(t => t.id)}).subscribe( | ||||
|       response => { | ||||
|         if (modal) { | ||||
|           modal.close() | ||||
|         } | ||||
|       } | ||||
|     ) | ||||
|   } | ||||
|  | ||||
|   setCorrespondents(changedCorrespondents: ChangedItems) { | ||||
|     if (changedCorrespondents.itemsToAdd.length == 0 && changedCorrespondents.itemsToRemove.length == 0) return | ||||
|  | ||||
| @@ -163,23 +164,13 @@ export class BulkEditorComponent { | ||||
|       modal.componentInstance.btnClass = "btn-warning" | ||||
|       modal.componentInstance.btnCaption = $localize`Confirm` | ||||
|       modal.componentInstance.confirmClicked.subscribe(() => { | ||||
|         this.performSetCorrespondents(modal, correspondent) | ||||
|         this.executeBulkOperation(modal, 'set_correspondent', {"correspondent": correspondent ? correspondent.id : null}) | ||||
|       }) | ||||
|     } else { | ||||
|       this.performSetCorrespondents(null, correspondent) | ||||
|       this.executeBulkOperation(null, 'set_correspondent', {"correspondent": correspondent ? correspondent.id : null}) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   private performSetCorrespondents(modal, correspondent: MatchingModel) { | ||||
|     this.executeBulkOperation('set_correspondent', {"correspondent": correspondent ? correspondent.id : null}).subscribe( | ||||
|       response => { | ||||
|         if (modal) { | ||||
|           modal.close() | ||||
|         } | ||||
|       } | ||||
|     ) | ||||
|   } | ||||
|  | ||||
|   setDocumentTypes(changedDocumentTypes: ChangedItems) { | ||||
|     if (changedDocumentTypes.itemsToAdd.length == 0 && changedDocumentTypes.itemsToRemove.length == 0) return | ||||
|  | ||||
| @@ -196,23 +187,13 @@ export class BulkEditorComponent { | ||||
|       modal.componentInstance.btnClass = "btn-warning" | ||||
|       modal.componentInstance.btnCaption = $localize`Confirm` | ||||
|       modal.componentInstance.confirmClicked.subscribe(() => { | ||||
|         this.performSetDocumentTypes(modal, documentType) | ||||
|         this.executeBulkOperation(modal, 'set_document_type', {"document_type": documentType ? documentType.id : null}) | ||||
|       }) | ||||
|     } else { | ||||
|       this.performSetDocumentTypes(null, documentType) | ||||
|       this.executeBulkOperation(null, 'set_document_type', {"document_type": documentType ? documentType.id : null}) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   private performSetDocumentTypes(modal, documentType) { | ||||
|     this.executeBulkOperation('set_document_type', {"document_type": documentType ? documentType.id : null}).subscribe( | ||||
|       response => { | ||||
|         if (modal) { | ||||
|           modal.close() | ||||
|         } | ||||
|       } | ||||
|     ) | ||||
|   } | ||||
|  | ||||
|   applyDelete() { | ||||
|     let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'}) | ||||
|     modal.componentInstance.delayConfirm(5) | ||||
| @@ -222,11 +203,8 @@ export class BulkEditorComponent { | ||||
|     modal.componentInstance.btnClass = "btn-danger" | ||||
|     modal.componentInstance.btnCaption = $localize`Delete document(s)` | ||||
|     modal.componentInstance.confirmClicked.subscribe(() => { | ||||
|       this.executeBulkOperation("delete", {}).subscribe( | ||||
|         response => { | ||||
|           modal.close() | ||||
|         } | ||||
|       ) | ||||
|       modal.componentInstance.buttonsEnabled = false | ||||
|       this.executeBulkOperation(modal, "delete", {}) | ||||
|     }) | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -90,6 +90,7 @@ export class DocumentListComponent implements OnInit { | ||||
|     let modal = this.modalService.open(SaveViewConfigDialogComponent, {backdrop: 'static'}) | ||||
|     modal.componentInstance.defaultName = this.filterEditor.generateFilterName() | ||||
|     modal.componentInstance.saveClicked.subscribe(formValue => { | ||||
|       modal.componentInstance.buttonsEnabled = false | ||||
|       let savedView = { | ||||
|         name: formValue.name, | ||||
|         show_on_dashboard: formValue.showOnDashboard, | ||||
| @@ -101,6 +102,9 @@ export class DocumentListComponent implements OnInit { | ||||
|       this.savedViewService.create(savedView).subscribe(() => { | ||||
|         modal.close() | ||||
|         this.toastService.showInfo($localize`View "${savedView.name}" created successfully.`) | ||||
|       }, error => { | ||||
|         modal.componentInstance.error = error.error | ||||
|         modal.componentInstance.buttonsEnabled = true | ||||
|       }) | ||||
|     }) | ||||
|   } | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| <form [formGroup]="saveViewConfigForm" class="needs-validation" novalidate (ngSubmit)="save()"> | ||||
| <form [formGroup]="saveViewConfigForm" (ngSubmit)="save()"> | ||||
|   <div class="modal-header"> | ||||
|     <h4 class="modal-title" id="modal-basic-title" i18n>Save current view</h4> | ||||
|     <button type="button" class="close" aria-label="Close" (click)="cancel()"> | ||||
| @@ -6,12 +6,12 @@ | ||||
|     </button> | ||||
|   </div> | ||||
|   <div class="modal-body"> | ||||
|     <app-input-text i18n-title title="Name" formControlName="name"></app-input-text> | ||||
|     <app-input-text i18n-title title="Name" formControlName="name" [error]="error?.name"></app-input-text> | ||||
|     <app-input-check i18n-title title="Show in sidebar" formControlName="showInSideBar"></app-input-check> | ||||
|     <app-input-check i18n-title title="Show on dashboard" formControlName="showOnDashboard"></app-input-check> | ||||
|   </div> | ||||
|   <div class="modal-footer"> | ||||
|     <button type="button" class="btn btn-outline-dark" (click)="cancel()" i18n>Cancel</button> | ||||
|     <button type="submit" class="btn btn-primary" i18n>Save</button> | ||||
|     <button type="button" class="btn btn-outline-dark" (click)="cancel()" i18n [disabled]="!buttonsEnabled">Cancel</button> | ||||
|     <button type="submit" class="btn btn-primary" i18n [disabled]="!buttonsEnabled">Save</button> | ||||
|   </div> | ||||
| </form> | ||||
|   | ||||
| @@ -14,6 +14,12 @@ export class SaveViewConfigDialogComponent implements OnInit { | ||||
|   @Output() | ||||
|   public saveClicked = new EventEmitter() | ||||
|  | ||||
|   @Input() | ||||
|   error | ||||
|  | ||||
|   @Input() | ||||
|   buttonsEnabled = true | ||||
|  | ||||
|   _defaultName = "" | ||||
|  | ||||
|   get defaultName() { | ||||
| @@ -26,7 +32,6 @@ export class SaveViewConfigDialogComponent implements OnInit { | ||||
|     this.saveViewConfigForm.patchValue({name: value}) | ||||
|   } | ||||
|    | ||||
|  | ||||
|   saveViewConfigForm = new FormGroup({ | ||||
|     name: new FormControl(''), | ||||
|     showInSideBar: new FormControl(false), | ||||
|   | ||||
| @@ -13,7 +13,7 @@ | ||||
|     <app-input-check *ngIf="patternRequired" i18n-title title="Case insensitive" formControlName="is_insensitive" novalidate></app-input-check> | ||||
|   </div> | ||||
|   <div class="modal-footer"> | ||||
|     <button type="button" class="btn btn-outline-dark" (click)="cancel()" i18n>Cancel</button> | ||||
|     <button type="submit" class="btn btn-primary" i18n>Save</button> | ||||
|     <button type="button" class="btn btn-outline-dark" (click)="cancel()" i18n [disabled]="networkActive">Cancel</button> | ||||
|     <button type="submit" class="btn btn-primary" i18n [disabled]="networkActive">Save</button> | ||||
|   </div> | ||||
| </form> | ||||
|   | ||||
| @@ -4,6 +4,7 @@ import { FILTER_CORRESPONDENT } from 'src/app/data/filter-rule-type'; | ||||
| import { PaperlessCorrespondent } from 'src/app/data/paperless-correspondent'; | ||||
| import { DocumentListViewService } from 'src/app/services/document-list-view.service'; | ||||
| import { CorrespondentService } from 'src/app/services/rest/correspondent.service'; | ||||
| import { ToastService } from 'src/app/services/toast.service'; | ||||
| import { GenericListComponent } from '../generic-list/generic-list.component'; | ||||
| import { CorrespondentEditDialogComponent } from './correspondent-edit-dialog/correspondent-edit-dialog.component'; | ||||
|  | ||||
| @@ -15,9 +16,10 @@ import { CorrespondentEditDialogComponent } from './correspondent-edit-dialog/co | ||||
| export class CorrespondentListComponent extends GenericListComponent<PaperlessCorrespondent> { | ||||
|  | ||||
|   constructor(correspondentsService: CorrespondentService, modalService: NgbModal, | ||||
|     private list: DocumentListViewService | ||||
|     private list: DocumentListViewService, | ||||
|     toastService: ToastService | ||||
|   ) {  | ||||
|     super(correspondentsService,modalService,CorrespondentEditDialogComponent) | ||||
|     super(correspondentsService,modalService,CorrespondentEditDialogComponent, toastService) | ||||
|   } | ||||
|  | ||||
|   getDeleteMessage(object: PaperlessCorrespondent) { | ||||
|   | ||||
| @@ -14,7 +14,7 @@ | ||||
|  | ||||
|     </div> | ||||
|     <div class="modal-footer"> | ||||
|       <button type="button" class="btn btn-outline-dark" (click)="cancel()" i18n>Cancel</button> | ||||
|       <button type="submit" class="btn btn-primary" i18n>Save</button> | ||||
|       <button type="button" class="btn btn-outline-dark" (click)="cancel()" i18n [disabled]="networkActive">Cancel</button> | ||||
|       <button type="submit" class="btn btn-primary" i18n [disabled]="networkActive">Save</button> | ||||
|     </div> | ||||
|   </form> | ||||
|   | ||||
| @@ -4,6 +4,7 @@ import { FILTER_DOCUMENT_TYPE } from 'src/app/data/filter-rule-type'; | ||||
| import { PaperlessDocumentType } from 'src/app/data/paperless-document-type'; | ||||
| import { DocumentListViewService } from 'src/app/services/document-list-view.service'; | ||||
| import { DocumentTypeService } from 'src/app/services/rest/document-type.service'; | ||||
| import { ToastService } from 'src/app/services/toast.service'; | ||||
| import { GenericListComponent } from '../generic-list/generic-list.component'; | ||||
| import { DocumentTypeEditDialogComponent } from './document-type-edit-dialog/document-type-edit-dialog.component'; | ||||
|  | ||||
| @@ -15,9 +16,10 @@ import { DocumentTypeEditDialogComponent } from './document-type-edit-dialog/doc | ||||
| export class DocumentTypeListComponent extends GenericListComponent<PaperlessDocumentType> { | ||||
|  | ||||
|   constructor(service: DocumentTypeService, modalService: NgbModal, | ||||
|     private list: DocumentListViewService | ||||
|     private list: DocumentListViewService, | ||||
|     toastService: ToastService | ||||
|   ) { | ||||
|     super(service, modalService, DocumentTypeEditDialogComponent) | ||||
|     super(service, modalService, DocumentTypeEditDialogComponent, toastService) | ||||
|   } | ||||
|  | ||||
|   getDeleteMessage(object: PaperlessDocumentType) { | ||||
|   | ||||
| @@ -4,6 +4,7 @@ import { MatchingModel, MATCHING_ALGORITHMS, MATCH_AUTO } from 'src/app/data/mat | ||||
| import { ObjectWithId } from 'src/app/data/object-with-id'; | ||||
| import { SortableDirective, SortEvent } from 'src/app/directives/sortable.directive'; | ||||
| import { AbstractPaperlessService } from 'src/app/services/rest/abstract-paperless-service'; | ||||
| import { ToastService } from 'src/app/services/toast.service'; | ||||
| import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dialog.component'; | ||||
|  | ||||
| @Directive() | ||||
| @@ -12,7 +13,8 @@ export abstract class GenericListComponent<T extends ObjectWithId> implements On | ||||
|   constructor( | ||||
|     private service: AbstractPaperlessService<T>, | ||||
|     private modalService: NgbModal, | ||||
|     private editDialogComponent: any) { | ||||
|     private editDialogComponent: any, | ||||
|     private toastService: ToastService) { | ||||
|     } | ||||
|  | ||||
|   @ViewChildren(SortableDirective) headers: QueryList<SortableDirective>; | ||||
| @@ -96,9 +98,13 @@ export abstract class GenericListComponent<T extends ObjectWithId> implements On | ||||
|     activeModal.componentInstance.btnClass = "btn-danger" | ||||
|     activeModal.componentInstance.btnCaption = $localize`Delete` | ||||
|     activeModal.componentInstance.confirmClicked.subscribe(() => { | ||||
|       activeModal.componentInstance.buttonsEnabled = false | ||||
|       this.service.delete(object).subscribe(_ => { | ||||
|         activeModal.close() | ||||
|         this.reloadData() | ||||
|       }, error => { | ||||
|         activeModal.componentInstance.buttonsEnabled = true | ||||
|         this.toastService.showError($localize`Error while deleting element: ${JSON.stringify(error.error)}`) | ||||
|       }) | ||||
|     } | ||||
|     ) | ||||
|   | ||||
| @@ -24,7 +24,7 @@ | ||||
|       <app-input-check *ngIf="patternRequired" i18n-title title="Case insensitive" formControlName="is_insensitive"></app-input-check> | ||||
|     </div> | ||||
|     <div class="modal-footer"> | ||||
|       <button type="button" class="btn btn-outline-dark" (click)="cancel()" i18n>Cancel</button> | ||||
|       <button type="submit" class="btn btn-primary" i18n>Save</button> | ||||
|       <button type="button" class="btn btn-outline-dark" (click)="cancel()" i18n [disabled]="networkActive">Cancel</button> | ||||
|       <button type="submit" class="btn btn-primary" i18n [disabled]="networkActive">Save</button> | ||||
|     </div> | ||||
|   </form> | ||||
|   | ||||
| @@ -4,6 +4,7 @@ import { FILTER_HAS_TAG } from 'src/app/data/filter-rule-type'; | ||||
| import { TAG_COLOURS, PaperlessTag } from 'src/app/data/paperless-tag'; | ||||
| import { DocumentListViewService } from 'src/app/services/document-list-view.service'; | ||||
| import { TagService } from 'src/app/services/rest/tag.service'; | ||||
| import { ToastService } from 'src/app/services/toast.service'; | ||||
| import { GenericListComponent } from '../generic-list/generic-list.component'; | ||||
| import { TagEditDialogComponent } from './tag-edit-dialog/tag-edit-dialog.component'; | ||||
|  | ||||
| @@ -15,9 +16,10 @@ import { TagEditDialogComponent } from './tag-edit-dialog/tag-edit-dialog.compon | ||||
| export class TagListComponent extends GenericListComponent<PaperlessTag> { | ||||
|  | ||||
|   constructor(tagService: TagService, modalService: NgbModal, | ||||
|     private list: DocumentListViewService | ||||
|     private list: DocumentListViewService, | ||||
|     toastService: ToastService | ||||
|   ) { | ||||
|     super(tagService, modalService, TagEditDialogComponent) | ||||
|     super(tagService, modalService, TagEditDialogComponent, toastService) | ||||
|   } | ||||
|  | ||||
|   getColor(id) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 jonaswinkler
					jonaswinkler