diff --git a/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.html b/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.html index f4dffa7d1..565829f21 100644 --- a/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.html +++ b/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.html @@ -9,8 +9,8 @@

{{message}}

diff --git a/src-ui/src/app/components/document-detail/document-detail.component.ts b/src-ui/src/app/components/document-detail/document-detail.component.ts index 84a03446a..4dbb6ab16 100644 --- a/src-ui/src/app/components/document-detail/document-detail.component.ts +++ b/src-ui/src/app/components/document-detail/document-detail.component.ts @@ -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 }) }) diff --git a/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.ts b/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.ts index e69ab241b..6b2598fe8 100644 --- a/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.ts +++ b/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.ts @@ -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 { - 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", {}) }) } } diff --git a/src-ui/src/app/components/document-list/document-list.component.ts b/src-ui/src/app/components/document-list/document-list.component.ts index fbd8065ae..1f29cb901 100644 --- a/src-ui/src/app/components/document-list/document-list.component.ts +++ b/src-ui/src/app/components/document-list/document-list.component.ts @@ -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 }) }) } diff --git a/src-ui/src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html b/src-ui/src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html index 9e28448a2..f2063df7e 100644 --- a/src-ui/src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html +++ b/src-ui/src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html @@ -1,4 +1,4 @@ -
+
diff --git a/src-ui/src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.ts b/src-ui/src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.ts index 8f0eb26f2..e930ffaed 100644 --- a/src-ui/src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.ts +++ b/src-ui/src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.ts @@ -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), diff --git a/src-ui/src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html b/src-ui/src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html index e2b7f13e0..3544aeed0 100644 --- a/src-ui/src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html +++ b/src-ui/src/app/components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component.html @@ -13,7 +13,7 @@ diff --git a/src-ui/src/app/components/manage/correspondent-list/correspondent-list.component.ts b/src-ui/src/app/components/manage/correspondent-list/correspondent-list.component.ts index 37b6fa66e..25ea653fa 100644 --- a/src-ui/src/app/components/manage/correspondent-list/correspondent-list.component.ts +++ b/src-ui/src/app/components/manage/correspondent-list/correspondent-list.component.ts @@ -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 { 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) { diff --git a/src-ui/src/app/components/manage/document-type-list/document-type-edit-dialog/document-type-edit-dialog.component.html b/src-ui/src/app/components/manage/document-type-list/document-type-edit-dialog/document-type-edit-dialog.component.html index d672c5bd8..8c3e848f5 100644 --- a/src-ui/src/app/components/manage/document-type-list/document-type-edit-dialog/document-type-edit-dialog.component.html +++ b/src-ui/src/app/components/manage/document-type-list/document-type-edit-dialog/document-type-edit-dialog.component.html @@ -14,7 +14,7 @@ diff --git a/src-ui/src/app/components/manage/document-type-list/document-type-list.component.ts b/src-ui/src/app/components/manage/document-type-list/document-type-list.component.ts index 68c8b6f91..02b9231ee 100644 --- a/src-ui/src/app/components/manage/document-type-list/document-type-list.component.ts +++ b/src-ui/src/app/components/manage/document-type-list/document-type-list.component.ts @@ -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 { 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) { diff --git a/src-ui/src/app/components/manage/generic-list/generic-list.component.ts b/src-ui/src/app/components/manage/generic-list/generic-list.component.ts index b31231bc8..bedf7167d 100644 --- a/src-ui/src/app/components/manage/generic-list/generic-list.component.ts +++ b/src-ui/src/app/components/manage/generic-list/generic-list.component.ts @@ -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 implements On constructor( private service: AbstractPaperlessService, private modalService: NgbModal, - private editDialogComponent: any) { + private editDialogComponent: any, + private toastService: ToastService) { } @ViewChildren(SortableDirective) headers: QueryList; @@ -96,9 +98,13 @@ export abstract class GenericListComponent 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)}`) }) } ) diff --git a/src-ui/src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.html b/src-ui/src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.html index 502502c5c..ad40659fb 100644 --- a/src-ui/src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.html +++ b/src-ui/src/app/components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component.html @@ -24,7 +24,7 @@ diff --git a/src-ui/src/app/components/manage/tag-list/tag-list.component.ts b/src-ui/src/app/components/manage/tag-list/tag-list.component.ts index 2c70ffef1..f9d0678ab 100644 --- a/src-ui/src/app/components/manage/tag-list/tag-list.component.ts +++ b/src-ui/src/app/components/manage/tag-list/tag-list.component.ts @@ -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 { constructor(tagService: TagService, modalService: NgbModal, - private list: DocumentListViewService + private list: DocumentListViewService, + toastService: ToastService ) { - super(tagService, modalService, TagEditDialogComponent) + super(tagService, modalService, TagEditDialogComponent, toastService) } getColor(id) {