mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-11-03 03:16:10 -06:00 
			
		
		
		
	Merge branch 'dev' into feature/dark-mode
This commit is contained in:
		@@ -9,6 +9,7 @@ RUN apt-get update \
 | 
				
			|||||||
  && apt-get -y --no-install-recommends install \
 | 
					  && apt-get -y --no-install-recommends install \
 | 
				
			||||||
		build-essential \
 | 
							build-essential \
 | 
				
			||||||
		curl \
 | 
							curl \
 | 
				
			||||||
 | 
							file \
 | 
				
			||||||
		fonts-liberation \
 | 
							fonts-liberation \
 | 
				
			||||||
		ghostscript \
 | 
							ghostscript \
 | 
				
			||||||
		gnupg \
 | 
							gnupg \
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,7 @@ import { Observable } from 'rxjs';
 | 
				
			|||||||
import { MATCHING_ALGORITHMS } from 'src/app/data/matching-model';
 | 
					import { MATCHING_ALGORITHMS } from 'src/app/data/matching-model';
 | 
				
			||||||
import { ObjectWithId } from 'src/app/data/object-with-id';
 | 
					import { ObjectWithId } from 'src/app/data/object-with-id';
 | 
				
			||||||
import { AbstractPaperlessService } from 'src/app/services/rest/abstract-paperless-service';
 | 
					import { AbstractPaperlessService } from 'src/app/services/rest/abstract-paperless-service';
 | 
				
			||||||
import { Toast, ToastService } from 'src/app/services/toast.service';
 | 
					import { ToastService } from 'src/app/services/toast.service';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Directive()
 | 
					@Directive()
 | 
				
			||||||
export abstract class EditDialogComponent<T extends ObjectWithId> implements OnInit {
 | 
					export abstract class EditDialogComponent<T extends ObjectWithId> implements OnInit {
 | 
				
			||||||
@@ -13,8 +13,7 @@ export abstract class EditDialogComponent<T extends ObjectWithId> implements OnI
 | 
				
			|||||||
  constructor(
 | 
					  constructor(
 | 
				
			||||||
    private service: AbstractPaperlessService<T>,
 | 
					    private service: AbstractPaperlessService<T>,
 | 
				
			||||||
    private activeModal: NgbActiveModal,
 | 
					    private activeModal: NgbActiveModal,
 | 
				
			||||||
    private toastService: ToastService,
 | 
					    private toastService: ToastService) { }
 | 
				
			||||||
    private entityName: string) { }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @Input()
 | 
					  @Input()
 | 
				
			||||||
  dialogMode: string = 'create'
 | 
					  dialogMode: string = 'create'
 | 
				
			||||||
@@ -35,12 +34,24 @@ export abstract class EditDialogComponent<T extends ObjectWithId> implements OnI
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getCreateTitle() {
 | 
				
			||||||
 | 
					    return $localize`Create new item`
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getEditTitle() {
 | 
				
			||||||
 | 
					    return $localize`Edit item`
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getSaveErrorMessage(error: string) {
 | 
				
			||||||
 | 
					    return $localize`Could not save element: ${error}`
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getTitle() {
 | 
					  getTitle() {
 | 
				
			||||||
    switch (this.dialogMode) {
 | 
					    switch (this.dialogMode) {
 | 
				
			||||||
      case 'create':
 | 
					      case 'create':
 | 
				
			||||||
        return "Create new " + this.entityName
 | 
					        return this.getCreateTitle()
 | 
				
			||||||
      case 'edit':
 | 
					      case 'edit':
 | 
				
			||||||
        return "Edit " + this.entityName
 | 
					        return this.getEditTitle()
 | 
				
			||||||
      default:
 | 
					      default:
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -66,7 +77,7 @@ export abstract class EditDialogComponent<T extends ObjectWithId> implements OnI
 | 
				
			|||||||
      this.activeModal.close()
 | 
					      this.activeModal.close()
 | 
				
			||||||
      this.success.emit(result)
 | 
					      this.success.emit(result)
 | 
				
			||||||
    }, error => {
 | 
					    }, error => {
 | 
				
			||||||
      this.toastService.showToast(Toast.makeError(`Could not save ${this.entityName}: ${error.error.name}`))
 | 
					      this.toastService.showError(this.getSaveErrorMessage(error.error.name))
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@ import { HttpEventType } from '@angular/common/http';
 | 
				
			|||||||
import { Component, OnInit } from '@angular/core';
 | 
					import { Component, OnInit } from '@angular/core';
 | 
				
			||||||
import { FileSystemFileEntry, NgxFileDropEntry } from 'ngx-file-drop';
 | 
					import { FileSystemFileEntry, NgxFileDropEntry } from 'ngx-file-drop';
 | 
				
			||||||
import { DocumentService } from 'src/app/services/rest/document.service';
 | 
					import { DocumentService } from 'src/app/services/rest/document.service';
 | 
				
			||||||
import { Toast, ToastService } from 'src/app/services/toast.service';
 | 
					import { ToastService } from 'src/app/services/toast.service';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface UploadStatus {
 | 
					interface UploadStatus {
 | 
				
			||||||
@@ -60,7 +60,7 @@ export class UploadFileWidgetComponent implements OnInit {
 | 
				
			|||||||
            } else if (event.type == HttpEventType.Response) {
 | 
					            } else if (event.type == HttpEventType.Response) {
 | 
				
			||||||
              this.uploadStatus.splice(this.uploadStatus.indexOf(uploadStatusObject), 1)
 | 
					              this.uploadStatus.splice(this.uploadStatus.indexOf(uploadStatusObject), 1)
 | 
				
			||||||
              this.completedFiles += 1
 | 
					              this.completedFiles += 1
 | 
				
			||||||
              this.toastService.showToast(Toast.make("Information", $localize`The document has been uploaded and will be processed by the consumer shortly.`))
 | 
					              this.toastService.showInfo($localize`The document has been uploaded and will be processed by the consumer shortly.`)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
          }, error => {
 | 
					          }, error => {
 | 
				
			||||||
@@ -68,11 +68,11 @@ export class UploadFileWidgetComponent implements OnInit {
 | 
				
			|||||||
            this.completedFiles += 1
 | 
					            this.completedFiles += 1
 | 
				
			||||||
            switch (error.status) {
 | 
					            switch (error.status) {
 | 
				
			||||||
              case 400: {
 | 
					              case 400: {
 | 
				
			||||||
                this.toastService.showToast(Toast.makeError($localize`There was an error while uploading the document: ${error.error.document}`))
 | 
					                this.toastService.showInfo($localize`There was an error while uploading the document: ${error.error.document}`)
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
              default: {
 | 
					              default: {
 | 
				
			||||||
                this.toastService.showToast(Toast.makeError($localize`An error has occurred while uploading the document. Sorry!`))
 | 
					                this.toastService.showInfo($localize`An error has occurred while uploading the document. Sorry!`)
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,7 @@ import { OpenDocumentsService } from 'src/app/services/open-documents.service';
 | 
				
			|||||||
import { ConfirmDialogComponent } from 'src/app/components/common/confirm-dialog/confirm-dialog.component';
 | 
					import { ConfirmDialogComponent } from 'src/app/components/common/confirm-dialog/confirm-dialog.component';
 | 
				
			||||||
import { ChangedItems, FilterableDropdownSelectionModel } from '../../common/filterable-dropdown/filterable-dropdown.component';
 | 
					import { ChangedItems, FilterableDropdownSelectionModel } from '../../common/filterable-dropdown/filterable-dropdown.component';
 | 
				
			||||||
import { ToggleableItemState } from '../../common/filterable-dropdown/toggleable-dropdown-button/toggleable-dropdown-button.component';
 | 
					import { ToggleableItemState } from '../../common/filterable-dropdown/toggleable-dropdown-button/toggleable-dropdown-button.component';
 | 
				
			||||||
 | 
					import { MatchingModel } from 'src/app/data/matching-model';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Component({
 | 
					@Component({
 | 
				
			||||||
  selector: 'app-bulk-editor',
 | 
					  selector: 'app-bulk-editor',
 | 
				
			||||||
@@ -88,15 +89,40 @@ export class BulkEditorComponent {
 | 
				
			|||||||
    })
 | 
					    })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private _localizeList(items: MatchingModel[]) {
 | 
				
			||||||
 | 
					    if (items.length == 0) {
 | 
				
			||||||
 | 
					      return ""
 | 
				
			||||||
 | 
					    } else if (items.length == 1) {
 | 
				
			||||||
 | 
					      return items[0].name
 | 
				
			||||||
 | 
					    } else if (items.length == 2) {
 | 
				
			||||||
 | 
					      return $localize`${items[0].name} and ${items[1].name}`
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      let list = items.slice(0, items.length - 1).map(i => i.name).join($localize`, `)
 | 
				
			||||||
 | 
					      return $localize`${list} and ${items[items.length - 1].name}`
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  setTags(changedTags: ChangedItems) {
 | 
					  setTags(changedTags: ChangedItems) {
 | 
				
			||||||
    if (changedTags.itemsToAdd.length == 0 && changedTags.itemsToRemove.length == 0) return
 | 
					    if (changedTags.itemsToAdd.length == 0 && changedTags.itemsToRemove.length == 0) return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'})
 | 
					    let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'})
 | 
				
			||||||
    modal.componentInstance.title = "Confirm Tags Assignment"
 | 
					    modal.componentInstance.title = $localize`Confirm tags assignment`
 | 
				
			||||||
 | 
					    if (changedTags.itemsToAdd.length == 1 && changedTags.itemsToRemove.length == 0) {
 | 
				
			||||||
 | 
					      let tag = changedTags.itemsToAdd[0]
 | 
				
			||||||
 | 
					      modal.componentInstance.message = $localize`This operation will add the tag ${tag.name} to all ${this.list.selected.size} selected document(s).`
 | 
				
			||||||
 | 
					    } else if (changedTags.itemsToAdd.length > 1 && changedTags.itemsToRemove.length == 0) {
 | 
				
			||||||
 | 
					      modal.componentInstance.message = $localize`This operation will add the tags ${this._localizeList(changedTags.itemsToAdd)} to all ${this.list.selected.size} selected document(s).`
 | 
				
			||||||
 | 
					    } else if (changedTags.itemsToAdd.length == 0 && changedTags.itemsToRemove.length == 1) {
 | 
				
			||||||
 | 
					      let tag = changedTags.itemsToAdd[0]
 | 
				
			||||||
 | 
					      modal.componentInstance.message = $localize`This operation will remove the tag ${tag.name} from all ${this.list.selected.size} selected document(s).`
 | 
				
			||||||
 | 
					    } else if (changedTags.itemsToAdd.length == 0 && changedTags.itemsToRemove.length > 1) {
 | 
				
			||||||
 | 
					      modal.componentInstance.message = $localize`This operation will remove the tags ${this._localizeList(changedTags.itemsToRemove)} from all ${this.list.selected.size} selected document(s).`
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      modal.componentInstance.message = $localize`This operation will add the tags ${this._localizeList(changedTags.itemsToAdd)} and remove the tags ${this._localizeList(changedTags.itemsToRemove)} on all ${this.list.selected.size} selected document(s).`
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    modal.componentInstance.message = `This operation will modify some tags on all ${this.list.selected.size} selected document(s).`
 | 
					 | 
				
			||||||
    modal.componentInstance.btnClass = "btn-warning"
 | 
					    modal.componentInstance.btnClass = "btn-warning"
 | 
				
			||||||
    modal.componentInstance.btnCaption = "Confirm"
 | 
					    modal.componentInstance.btnCaption = $localize`Confirm`
 | 
				
			||||||
    modal.componentInstance.confirmClicked.subscribe(() => {
 | 
					    modal.componentInstance.confirmClicked.subscribe(() => {
 | 
				
			||||||
      this.executeBulkOperation('modify_tags', {"add_tags": changedTags.itemsToAdd.map(t => t.id), "remove_tags": changedTags.itemsToRemove.map(t => t.id)}).subscribe(
 | 
					      this.executeBulkOperation('modify_tags', {"add_tags": changedTags.itemsToAdd.map(t => t.id), "remove_tags": changedTags.itemsToRemove.map(t => t.id)}).subscribe(
 | 
				
			||||||
        response => {
 | 
					        response => {
 | 
				
			||||||
@@ -111,18 +137,17 @@ export class BulkEditorComponent {
 | 
				
			|||||||
    if (changedCorrespondents.itemsToAdd.length == 0 && changedCorrespondents.itemsToRemove.length == 0) return
 | 
					    if (changedCorrespondents.itemsToAdd.length == 0 && changedCorrespondents.itemsToRemove.length == 0) return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'})
 | 
					    let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'})
 | 
				
			||||||
    modal.componentInstance.title = "Confirm Correspondent Assignment"
 | 
					    modal.componentInstance.title = $localize`Confirm correspondent assignment`
 | 
				
			||||||
    let correspondent
 | 
					    let correspondent = changedCorrespondents.itemsToAdd.length > 0 ? changedCorrespondents.itemsToAdd[0] : null
 | 
				
			||||||
    let messageFragment = 'remove all correspondents from'
 | 
					    if (correspondent) {
 | 
				
			||||||
    if (changedCorrespondents && changedCorrespondents.itemsToAdd.length > 0) {
 | 
					      modal.componentInstance.message = $localize`This operation will assign the correspondent ${correspondent.name} to all ${this.list.selected.size} selected document(s).`
 | 
				
			||||||
      correspondent = changedCorrespondents.itemsToAdd[0]
 | 
					    } else {
 | 
				
			||||||
      messageFragment = `assign the correspondent ${correspondent.name} to`
 | 
					      modal.componentInstance.message = $localize`This operation will remove the correspondent from all ${this.list.selected.size} selected document(s).`
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    modal.componentInstance.message = `This operation will ${messageFragment} all ${this.list.selected.size} selected document(s).`
 | 
					 | 
				
			||||||
    modal.componentInstance.btnClass = "btn-warning"
 | 
					    modal.componentInstance.btnClass = "btn-warning"
 | 
				
			||||||
    modal.componentInstance.btnCaption = "Confirm"
 | 
					    modal.componentInstance.btnCaption = $localize`Confirm`
 | 
				
			||||||
    modal.componentInstance.confirmClicked.subscribe(() => {
 | 
					    modal.componentInstance.confirmClicked.subscribe(() => {
 | 
				
			||||||
      this.executeBulkOperation('set_correspondent', {"correspondent": correspondent ? correspondent.id : null}).subscribe(
 | 
					      this.executeBulkOperation('set_correspondent', {"correspondent": correspondent?.id}).subscribe(
 | 
				
			||||||
        response => {
 | 
					        response => {
 | 
				
			||||||
          this.correspondentService.clearCache()
 | 
					          this.correspondentService.clearCache()
 | 
				
			||||||
          modal.close()
 | 
					          modal.close()
 | 
				
			||||||
@@ -135,18 +160,17 @@ export class BulkEditorComponent {
 | 
				
			|||||||
    if (changedDocumentTypes.itemsToAdd.length == 0 && changedDocumentTypes.itemsToRemove.length == 0) return
 | 
					    if (changedDocumentTypes.itemsToAdd.length == 0 && changedDocumentTypes.itemsToRemove.length == 0) return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'})
 | 
					    let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'})
 | 
				
			||||||
    modal.componentInstance.title = "Confirm Document Type Assignment"
 | 
					    modal.componentInstance.title = $localize`Confirm document type assignment`
 | 
				
			||||||
    let documentType
 | 
					    let documentType = changedDocumentTypes.itemsToAdd.length > 0 ? changedDocumentTypes.itemsToAdd[0] : null
 | 
				
			||||||
    let messageFragment = 'remove all document types from'
 | 
					    if (documentType) {
 | 
				
			||||||
    if (changedDocumentTypes && changedDocumentTypes.itemsToAdd.length > 0) {
 | 
					      modal.componentInstance.message = $localize`This operation will assign the document type ${documentType.name} to all ${this.list.selected.size} selected document(s).`
 | 
				
			||||||
      documentType = changedDocumentTypes.itemsToAdd[0]
 | 
					    } else {
 | 
				
			||||||
      messageFragment = `assign the document type ${documentType.name} to`
 | 
					      modal.componentInstance.message = $localize`This operation will remove the document type from all ${this.list.selected.size} selected document(s).`
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    modal.componentInstance.message = `This operation will ${messageFragment} all ${this.list.selected.size} selected document(s).`
 | 
					 | 
				
			||||||
    modal.componentInstance.btnClass = "btn-warning"
 | 
					    modal.componentInstance.btnClass = "btn-warning"
 | 
				
			||||||
    modal.componentInstance.btnCaption = "Confirm"
 | 
					    modal.componentInstance.btnCaption = $localize`Confirm`
 | 
				
			||||||
    modal.componentInstance.confirmClicked.subscribe(() => {
 | 
					    modal.componentInstance.confirmClicked.subscribe(() => {
 | 
				
			||||||
      this.executeBulkOperation('set_document_type', {"document_type": documentType ? documentType.id : null}).subscribe(
 | 
					      this.executeBulkOperation('set_document_type', {"document_type": documentType?.id}).subscribe(
 | 
				
			||||||
        response => {
 | 
					        response => {
 | 
				
			||||||
          this.documentService.clearCache()
 | 
					          this.documentService.clearCache()
 | 
				
			||||||
          modal.close()
 | 
					          modal.close()
 | 
				
			||||||
@@ -158,11 +182,11 @@ export class BulkEditorComponent {
 | 
				
			|||||||
  applyDelete() {
 | 
					  applyDelete() {
 | 
				
			||||||
    let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'})
 | 
					    let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'})
 | 
				
			||||||
    modal.componentInstance.delayConfirm(5)
 | 
					    modal.componentInstance.delayConfirm(5)
 | 
				
			||||||
    modal.componentInstance.title = "Delete confirm"
 | 
					    modal.componentInstance.title = $localize`Delete confirm`
 | 
				
			||||||
    modal.componentInstance.messageBold = `This operation will permanently delete all ${this.list.selected.size} selected document(s).`
 | 
					    modal.componentInstance.messageBold = $localize`This operation will permanently delete all ${this.list.selected.size} selected document(s).`
 | 
				
			||||||
    modal.componentInstance.message = `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 = "Delete document(s)"
 | 
					    modal.componentInstance.btnCaption = $localize`Delete document(s)`
 | 
				
			||||||
    modal.componentInstance.confirmClicked.subscribe(() => {
 | 
					    modal.componentInstance.confirmClicked.subscribe(() => {
 | 
				
			||||||
      this.executeBulkOperation("delete", {}).subscribe(
 | 
					      this.executeBulkOperation("delete", {}).subscribe(
 | 
				
			||||||
        response => {
 | 
					        response => {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -81,7 +81,7 @@ export class DocumentListComponent implements OnInit {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  saveViewConfig() {
 | 
					  saveViewConfig() {
 | 
				
			||||||
    this.savedViewService.update(this.list.savedView).subscribe(result => {
 | 
					    this.savedViewService.update(this.list.savedView).subscribe(result => {
 | 
				
			||||||
      this.toastService.showToast(Toast.make("Information", $localize`View "${this.list.savedView.name}" saved successfully.`))
 | 
					      this.toastService.showInfo($localize`View "${this.list.savedView.name}" saved successfully.`)
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -100,7 +100,7 @@ export class DocumentListComponent implements OnInit {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
      this.savedViewService.create(savedView).subscribe(() => {
 | 
					      this.savedViewService.create(savedView).subscribe(() => {
 | 
				
			||||||
        modal.close()
 | 
					        modal.close()
 | 
				
			||||||
        this.toastService.showToast(Toast.make("Information", $localize`View "${savedView.name}" created successfully.`))
 | 
					        this.toastService.showInfo($localize`View "${savedView.name}" created successfully.`)
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,19 @@ import { ToastService } from 'src/app/services/toast.service';
 | 
				
			|||||||
export class CorrespondentEditDialogComponent extends EditDialogComponent<PaperlessCorrespondent> {
 | 
					export class CorrespondentEditDialogComponent extends EditDialogComponent<PaperlessCorrespondent> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(service: CorrespondentService, activeModal: NgbActiveModal, toastService: ToastService) {
 | 
					  constructor(service: CorrespondentService, activeModal: NgbActiveModal, toastService: ToastService) {
 | 
				
			||||||
    super(service, activeModal, toastService, 'correspondent')
 | 
					    super(service, activeModal, toastService)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getCreateTitle() {
 | 
				
			||||||
 | 
					    return $localize`Create new correspondent`
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getEditTitle() {
 | 
				
			||||||
 | 
					    return $localize`Edit correspondent`
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getSaveErrorMessage(error: string) {
 | 
				
			||||||
 | 
					    return $localize`Could not save correspondent: ${error}`
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getForm(): FormGroup {
 | 
					  getForm(): FormGroup {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,8 +22,8 @@ export class CorrespondentListComponent extends GenericListComponent<PaperlessCo
 | 
				
			|||||||
    super(correspondentsService,modalService,CorrespondentEditDialogComponent)
 | 
					    super(correspondentsService,modalService,CorrespondentEditDialogComponent)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getObjectName(object: PaperlessCorrespondent) {
 | 
					  getDeleteMessage(object: PaperlessCorrespondent) {
 | 
				
			||||||
    return `correspondent '${object.name}'`
 | 
					    return $localize`Do you really want to delete the correspondent ${object.name}?`
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  filterDocuments(object: PaperlessCorrespondent) {
 | 
					  filterDocuments(object: PaperlessCorrespondent) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,19 @@ import { ToastService } from 'src/app/services/toast.service';
 | 
				
			|||||||
export class DocumentTypeEditDialogComponent extends EditDialogComponent<PaperlessDocumentType> {
 | 
					export class DocumentTypeEditDialogComponent extends EditDialogComponent<PaperlessDocumentType> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(service: DocumentTypeService, activeModal: NgbActiveModal, toastService: ToastService) { 
 | 
					  constructor(service: DocumentTypeService, activeModal: NgbActiveModal, toastService: ToastService) { 
 | 
				
			||||||
    super(service, activeModal, toastService, 'document type')
 | 
					    super(service, activeModal, toastService)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getCreateTitle() {
 | 
				
			||||||
 | 
					    return $localize`Create new document type`
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getEditTitle() {
 | 
				
			||||||
 | 
					    return $localize`Edit document type`
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getSaveErrorMessage(error: string) {
 | 
				
			||||||
 | 
					    return $localize`Could not save document type: ${error}`
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getForm(): FormGroup {
 | 
					  getForm(): FormGroup {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,10 +22,11 @@ export class DocumentTypeListComponent extends GenericListComponent<PaperlessDoc
 | 
				
			|||||||
    super(service, modalService, DocumentTypeEditDialogComponent)
 | 
					    super(service, modalService, DocumentTypeEditDialogComponent)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getObjectName(object: PaperlessDocumentType) {
 | 
					  getDeleteMessage(object: PaperlessDocumentType) {
 | 
				
			||||||
    return `document type '${object.name}'`
 | 
					    return $localize`Do you really want to delete the document type ${object.name}?`
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  filterDocuments(object: PaperlessDocumentType) {
 | 
					  filterDocuments(object: PaperlessDocumentType) {
 | 
				
			||||||
    this.list.documentListView.filter_rules = [
 | 
					    this.list.documentListView.filter_rules = [
 | 
				
			||||||
      {rule_type: FILTER_DOCUMENT_TYPE, value: object.id.toString()}
 | 
					      {rule_type: FILTER_DOCUMENT_TYPE, value: object.id.toString()}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -84,14 +84,14 @@ export abstract class GenericListComponent<T extends ObjectWithId> implements On
 | 
				
			|||||||
    })
 | 
					    })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getObjectName(object: T) {
 | 
					  getDeleteMessage(object: T) {
 | 
				
			||||||
    return object.toString()
 | 
					    return $localize`Do you really want to delete this element?`
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  openDeleteDialog(object: T) {
 | 
					  openDeleteDialog(object: T) {
 | 
				
			||||||
    var activeModal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'})
 | 
					    var activeModal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'})
 | 
				
			||||||
    activeModal.componentInstance.title = $localize`Confirm delete`
 | 
					    activeModal.componentInstance.title = $localize`Confirm delete`
 | 
				
			||||||
    activeModal.componentInstance.messageBold = $localize`Do you really want to delete ${this.getObjectName(object)}?`
 | 
					    activeModal.componentInstance.messageBold = this.getDeleteMessage(object)
 | 
				
			||||||
    activeModal.componentInstance.message = $localize`Associated documents will not be deleted.`
 | 
					    activeModal.componentInstance.message = $localize`Associated documents will not be deleted.`
 | 
				
			||||||
    activeModal.componentInstance.btnClass = "btn-danger"
 | 
					    activeModal.componentInstance.btnClass = "btn-danger"
 | 
				
			||||||
    activeModal.componentInstance.btnCaption = $localize`Delete`
 | 
					    activeModal.componentInstance.btnCaption = $localize`Delete`
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@ import { PaperlessSavedView } from 'src/app/data/paperless-saved-view';
 | 
				
			|||||||
import { GENERAL_SETTINGS } from 'src/app/data/storage-keys';
 | 
					import { GENERAL_SETTINGS } from 'src/app/data/storage-keys';
 | 
				
			||||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service';
 | 
					import { DocumentListViewService } from 'src/app/services/document-list-view.service';
 | 
				
			||||||
import { SavedViewService } from 'src/app/services/rest/saved-view.service';
 | 
					import { SavedViewService } from 'src/app/services/rest/saved-view.service';
 | 
				
			||||||
import { Toast, ToastService } from 'src/app/services/toast.service';
 | 
					import { ToastService } from 'src/app/services/toast.service';
 | 
				
			||||||
import { AppViewService } from 'src/app/services/app-view.service';
 | 
					import { AppViewService } from 'src/app/services/app-view.service';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Component({
 | 
					@Component({
 | 
				
			||||||
@@ -54,7 +54,7 @@ export class SettingsComponent implements OnInit {
 | 
				
			|||||||
    this.savedViewService.delete(savedView).subscribe(() => {
 | 
					    this.savedViewService.delete(savedView).subscribe(() => {
 | 
				
			||||||
      this.savedViewGroup.removeControl(savedView.id.toString())
 | 
					      this.savedViewGroup.removeControl(savedView.id.toString())
 | 
				
			||||||
      this.savedViews.splice(this.savedViews.indexOf(savedView), 1)
 | 
					      this.savedViews.splice(this.savedViews.indexOf(savedView), 1)
 | 
				
			||||||
      this.toastService.showToast(Toast.make("Information", $localize`Saved view "${savedView.name} deleted.`))
 | 
					      this.toastService.showInfo($localize`Saved view "${savedView.name} deleted.`)
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -72,7 +72,7 @@ export class SettingsComponent implements OnInit {
 | 
				
			|||||||
    localStorage.setItem(GENERAL_SETTINGS.DARK_MODE_ENABLED, (this.settingsForm.value.darkModeEnabled == true).toString())
 | 
					    localStorage.setItem(GENERAL_SETTINGS.DARK_MODE_ENABLED, (this.settingsForm.value.darkModeEnabled == true).toString())
 | 
				
			||||||
    this.documentListViewService.updatePageSize()
 | 
					    this.documentListViewService.updatePageSize()
 | 
				
			||||||
    this.appViewService.updateDarkModeSettings()
 | 
					    this.appViewService.updateDarkModeSettings()
 | 
				
			||||||
    this.toastService.showToast(Toast.make("Information", $localize`Settings saved successfully.`))
 | 
					    this.toastService.showInfo($localize`Settings saved successfully.`)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  saveSettings() {
 | 
					  saveSettings() {
 | 
				
			||||||
@@ -84,7 +84,7 @@ export class SettingsComponent implements OnInit {
 | 
				
			|||||||
      this.savedViewService.patchMany(x).subscribe(s => {
 | 
					      this.savedViewService.patchMany(x).subscribe(s => {
 | 
				
			||||||
        this.saveLocalSettings()
 | 
					        this.saveLocalSettings()
 | 
				
			||||||
      }, error => {
 | 
					      }, error => {
 | 
				
			||||||
        this.toastService.showToast(Toast.makeError($localize`Error while storing settings on server: ${JSON.stringify(error.error)}`))
 | 
					        this.toastService.showError($localize`Error while storing settings on server: ${JSON.stringify(error.error)}`)
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      this.saveLocalSettings()
 | 
					      this.saveLocalSettings()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,19 @@ import { ToastService } from 'src/app/services/toast.service';
 | 
				
			|||||||
export class TagEditDialogComponent extends EditDialogComponent<PaperlessTag> {
 | 
					export class TagEditDialogComponent extends EditDialogComponent<PaperlessTag> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(service: TagService, activeModal: NgbActiveModal, toastService: ToastService) { 
 | 
					  constructor(service: TagService, activeModal: NgbActiveModal, toastService: ToastService) { 
 | 
				
			||||||
    super(service, activeModal, toastService, 'tag')
 | 
					    super(service, activeModal, toastService)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getCreateTitle() {
 | 
				
			||||||
 | 
					    return $localize`Create new tag`
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getEditTitle() {
 | 
				
			||||||
 | 
					    return $localize`Edit tag`
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getSaveErrorMessage(error: string) {
 | 
				
			||||||
 | 
					    return $localize`Could not save tag: ${error}`
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getForm(): FormGroup {
 | 
					  getForm(): FormGroup {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,8 +26,8 @@ export class TagListComponent extends GenericListComponent<PaperlessTag> {
 | 
				
			|||||||
    return TAG_COLOURS.find(c => c.id == id)
 | 
					    return TAG_COLOURS.find(c => c.id == id)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getObjectName(object: PaperlessTag) {
 | 
					  getDeleteMessage(object: PaperlessTag) {
 | 
				
			||||||
    return `tag '${object.name}'`
 | 
					    return $localize`Do you really want to delete the tag ${object.name}?`
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  filterDocuments(object: PaperlessTag) {
 | 
					  filterDocuments(object: PaperlessTag) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,30 +1,13 @@
 | 
				
			|||||||
import { Injectable } from '@angular/core';
 | 
					import { Injectable } from '@angular/core';
 | 
				
			||||||
import { Subject, zip } from 'rxjs';
 | 
					import { Subject, zip } from 'rxjs';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class Toast {
 | 
					export interface Toast {
 | 
				
			||||||
 | 
					 | 
				
			||||||
  static make(title: string, content: string, classname?: string, delay?: number): Toast {
 | 
					 | 
				
			||||||
    let t = new Toast()
 | 
					 | 
				
			||||||
    t.title = title
 | 
					 | 
				
			||||||
    t.content = content
 | 
					 | 
				
			||||||
    t.classname = classname
 | 
					 | 
				
			||||||
    if (delay) {
 | 
					 | 
				
			||||||
      t.delay = delay
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return t
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  static makeError(content: string) {
 | 
					 | 
				
			||||||
    return Toast.make("Error", content, null, 10000)
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  title: string
 | 
					  title: string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  classname: string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  content: string
 | 
					  content: string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  delay: number = 5000
 | 
					  delay: number
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -39,11 +22,19 @@ export class ToastService {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  private toastsSubject: Subject<Toast[]> = new Subject()
 | 
					  private toastsSubject: Subject<Toast[]> = new Subject()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  showToast(toast: Toast) {
 | 
					  show(toast: Toast) {
 | 
				
			||||||
    this.toasts.push(toast)
 | 
					    this.toasts.push(toast)
 | 
				
			||||||
    this.toastsSubject.next(this.toasts)
 | 
					    this.toastsSubject.next(this.toasts)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  showError(content: string, delay: number = 10000) {
 | 
				
			||||||
 | 
					    this.show({title: $localize`Error`, content: content, delay: delay})
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  showInfo(content: string, delay: number = 5000) {
 | 
				
			||||||
 | 
					    this.show({title: $localize`Information`, content: content, delay: delay})
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  closeToast(toast: Toast) {
 | 
					  closeToast(toast: Toast) {
 | 
				
			||||||
    let index = this.toasts.findIndex(t => t == toast)
 | 
					    let index = this.toasts.findIndex(t => t == toast)
 | 
				
			||||||
    if (index > -1) {
 | 
					    if (index > -1) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user