This commit is contained in:
jonaswinkler 2021-01-03 21:44:53 +01:00
parent a96ab9a9a4
commit d935dcd350
15 changed files with 80 additions and 72 deletions

View File

@ -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>

View File

@ -28,6 +28,9 @@ export class ConfirmDialogComponent implements OnInit {
@Input()
btnCaption = $localize`Confirm`
@Input()
buttonsEnabled = true
confirmButtonEnabled = true
seconds = 0

View File

@ -127,9 +127,9 @@
<div [ngbNavOutlet]="nav" class="mt-2"></div>
<button type="button" class="btn btn-outline-secondary" (click)="discard()" i18n>Discard</button>&nbsp;
<button type="button" class="btn btn-outline-primary" (click)="saveEditNext()" *ngIf="hasNext()" i18n>Save & next</button>&nbsp;
<button type="submit" class="btn btn-primary" i18n>Save</button>&nbsp;
<button type="button" class="btn btn-outline-secondary" (click)="discard()" i18n [disabled]="networkActive">Discard</button>&nbsp;
<button type="button" class="btn btn-outline-primary" (click)="saveEditNext()" *ngIf="hasNext()" i18n [disabled]="networkActive">Save & next</button>&nbsp;
<button type="submit" class="btn btn-primary" i18n [disabled]="networkActive">Save</button>&nbsp;
</form>
</div>

View File

@ -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
})
})

View File

@ -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", {})
})
}
}

View File

@ -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
})
})
}

View File

@ -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>

View File

@ -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),

View File

@ -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>

View File

@ -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) {

View File

@ -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>

View File

@ -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) {

View File

@ -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)}`)
})
}
)

View File

@ -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>

View File

@ -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) {