diff --git a/src-ui/src/app/app.module.ts b/src-ui/src/app/app.module.ts index befd26639..887dc7ffd 100644 --- a/src-ui/src/app/app.module.ts +++ b/src-ui/src/app/app.module.ts @@ -16,7 +16,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { DatePipe } from '@angular/common'; import { NotFoundComponent } from './components/not-found/not-found.component'; import { CorrespondentListComponent } from './components/manage/correspondent-list/correspondent-list.component'; -import { DeleteDialogComponent } from './components/common/delete-dialog/delete-dialog.component'; +import { ConfirmDialogComponent } from './components/common/confirm-dialog/confirm-dialog.component'; import { CorrespondentEditDialogComponent } from './components/manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component'; import { TagEditDialogComponent } from './components/manage/tag-list/tag-edit-dialog/tag-edit-dialog.component'; import { DocumentTypeEditDialogComponent } from './components/manage/document-type-list/document-type-edit-dialog/document-type-edit-dialog.component'; @@ -49,6 +49,7 @@ import { WelcomeWidgetComponent } from './components/dashboard/widgets/welcome-w import { YesNoPipe } from './pipes/yes-no.pipe'; import { FileSizePipe } from './pipes/file-size.pipe'; import { DocumentTitlePipe } from './pipes/document-title.pipe'; +import { MetadataCollapseComponent } from './components/document-detail/metadata-collapse/metadata-collapse.component'; import { SelectDialogComponent } from './components/common/select-dialog/select-dialog.component'; @NgModule({ @@ -64,7 +65,7 @@ import { SelectDialogComponent } from './components/common/select-dialog/select- SettingsComponent, NotFoundComponent, CorrespondentEditDialogComponent, - DeleteDialogComponent, + ConfirmDialogComponent, TagEditDialogComponent, DocumentTypeEditDialogComponent, TagComponent, @@ -91,6 +92,7 @@ import { SelectDialogComponent } from './components/common/select-dialog/select- YesNoPipe, FileSizePipe, DocumentTitlePipe, + MetadataCollapseComponent, SelectDialogComponent ], imports: [ diff --git a/src-ui/src/app/components/common/delete-dialog/delete-dialog.component.html b/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.html similarity index 55% rename from src-ui/src/app/components/common/delete-dialog/delete-dialog.component.html rename to src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.html index 52287fc69..f4dffa7d1 100644 --- a/src-ui/src/app/components/common/delete-dialog/delete-dialog.component.html +++ b/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.html @@ -5,10 +5,13 @@ </button> </div> <div class="modal-body"> - <p><b>{{message}}</b></p> - <p *ngIf="message2">{{message2}}</p> + <p *ngIf="messageBold"><b>{{messageBold}}</b></p> + <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 btn-danger" (click)="deleteClicked.emit()" [disabled]="!deleteButtonEnabled">Delete<span *ngIf="!deleteButtonEnabled"> ({{seconds}})</span></button> - </div> \ No newline at end of file + <button type="button" class="btn" [class]="btnClass" (click)="confirmClicked.emit()" [disabled]="!confirmButtonEnabled"> + {{btnCaption}} + <span *ngIf="!confirmButtonEnabled"> ({{seconds}})</span> + </button> + </div> diff --git a/src-ui/src/app/components/common/delete-dialog/delete-dialog.component.scss b/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.scss similarity index 100% rename from src-ui/src/app/components/common/delete-dialog/delete-dialog.component.scss rename to src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.scss diff --git a/src-ui/src/app/components/common/delete-dialog/delete-dialog.component.spec.ts b/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.spec.ts similarity index 52% rename from src-ui/src/app/components/common/delete-dialog/delete-dialog.component.spec.ts rename to src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.spec.ts index 33c7d6e88..fe08dc57a 100644 --- a/src-ui/src/app/components/common/delete-dialog/delete-dialog.component.spec.ts +++ b/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.spec.ts @@ -1,20 +1,20 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { DeleteDialogComponent } from './delete-dialog.component'; +import { ConfirmDialogComponent } from './confirm-dialog.component'; -describe('DeleteDialogComponent', () => { - let component: DeleteDialogComponent; - let fixture: ComponentFixture<DeleteDialogComponent>; +describe('ConfirmDialogComponent', () => { + let component: ConfirmDialogComponent; + let fixture: ComponentFixture<ConfirmDialogComponent>; beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ DeleteDialogComponent ] + declarations: [ ConfirmDialogComponent ] }) .compileComponents(); }); beforeEach(() => { - fixture = TestBed.createComponent(DeleteDialogComponent); + fixture = TestBed.createComponent(ConfirmDialogComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/src-ui/src/app/components/common/delete-dialog/delete-dialog.component.ts b/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.ts similarity index 54% rename from src-ui/src/app/components/common/delete-dialog/delete-dialog.component.ts rename to src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.ts index 38ec93bae..4791d0e77 100644 --- a/src-ui/src/app/components/common/delete-dialog/delete-dialog.component.ts +++ b/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.ts @@ -2,35 +2,41 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; @Component({ - selector: 'app-delete-dialog', - templateUrl: './delete-dialog.component.html', - styleUrls: ['./delete-dialog.component.scss'] + selector: 'app-confirm-dialog', + templateUrl: './confirm-dialog.component.html', + styleUrls: ['./confirm-dialog.component.scss'] }) -export class DeleteDialogComponent implements OnInit { +export class ConfirmDialogComponent implements OnInit { constructor(public activeModal: NgbActiveModal) { } @Output() - public deleteClicked = new EventEmitter() + public confirmClicked = new EventEmitter() @Input() - title = "Delete confirmation" + title = "Confirmation" @Input() - message = "Do you really want to delete this?" + messageBold @Input() - message2 + message - deleteButtonEnabled = true + @Input() + btnClass = "btn-primary" + + @Input() + btnCaption = "Confirm" + + confirmButtonEnabled = true seconds = 0 delayConfirm(seconds: number) { - this.deleteButtonEnabled = false + this.confirmButtonEnabled = false this.seconds = seconds setTimeout(() => { if (this.seconds <= 1) { - this.deleteButtonEnabled = true + this.confirmButtonEnabled = true } else { this.delayConfirm(seconds - 1) } diff --git a/src-ui/src/app/components/document-detail/document-detail.component.html b/src-ui/src/app/components/document-detail/document-detail.component.html index f9f6e57ef..c0114f709 100644 --- a/src-ui/src/app/components/document-detail/document-detail.component.html +++ b/src-ui/src/app/components/document-detail/document-detail.component.html @@ -110,53 +110,8 @@ </tbody> </table> - <h6 *ngIf="metadata?.original_metadata.length > 0"> - <button type="button" class="btn btn-outline-secondary btn-sm mr-2" - (click)="expandOriginalMetadata = !expandOriginalMetadata" aria-controls="collapseExample"> - <svg class="buttonicon" fill="currentColor" *ngIf="!expandOriginalMetadata"> - <use xlink:href="assets/bootstrap-icons.svg#caret-down" /> - </svg> - <svg class="buttonicon" fill="currentColor" *ngIf="expandOriginalMetadata"> - <use xlink:href="assets/bootstrap-icons.svg#caret-up" /> - </svg> - </button> - Original document metadata - </h6> - - <div #collapse="ngbCollapse" [(ngbCollapse)]="!expandOriginalMetadata"> - <table class="table table-borderless"> - <tbody> - <tr *ngFor="let m of metadata?.original_metadata"> - <td>{{m.prefix}}:{{m.key}}</td> - <td>{{m.value}}</td> - </tr> - </tbody> - </table> - </div> - - <h6 *ngIf="metadata?.has_archive_version && metadata?.archive_metadata.length > 0"> - <button type="button" class="btn btn-outline-secondary btn-sm mr-2" - (click)="expandArchivedMetadata = !expandArchivedMetadata" aria-controls="collapseExample"> - <svg class="buttonicon" fill="currentColor" *ngIf="!expandArchivedMetadata"> - <use xlink:href="assets/bootstrap-icons.svg#caret-down" /> - </svg> - <svg class="buttonicon" fill="currentColor" *ngIf="expandArchivedMetadata"> - <use xlink:href="assets/bootstrap-icons.svg#caret-up" /> - </svg> - </button> - Archived document metadata - </h6> - - <div #collapse="ngbCollapse" [(ngbCollapse)]="!expandArchivedMetadata"> - <table class="table table-borderless"> - <tbody> - <tr *ngFor="let m of metadata?.archive_metadata"> - <td>{{m.prefix}}:{{m.key}}</td> - <td>{{m.value}}</td> - </tr> - </tbody> - </table> - </div> + <app-metadata-collapse title="Original document metadata" [metadata]="metadata.original_metadata" *ngIf="metadata?.original_metadata.length > 0"></app-metadata-collapse> + <app-metadata-collapse title="Archived document metadata" [metadata]="metadata.archive_metadata" *ngIf="metadata?.archive_metadata.length > 0"></app-metadata-collapse> </ng-template> </li> 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 c80a8b1ce..4aac9c769 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 @@ -13,7 +13,7 @@ import { CorrespondentService } from 'src/app/services/rest/correspondent.servic import { DocumentTypeService } from 'src/app/services/rest/document-type.service'; import { DocumentService } from 'src/app/services/rest/document.service'; import { environment } from 'src/environments/environment'; -import { DeleteDialogComponent } from '../common/delete-dialog/delete-dialog.component'; +import { ConfirmDialogComponent } from '../common/confirm-dialog/confirm-dialog.component'; 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'; @@ -155,10 +155,13 @@ export class DocumentDetailComponent implements OnInit { } delete() { - let modal = this.modalService.open(DeleteDialogComponent, {backdrop: 'static'}) - modal.componentInstance.message = `Do you really want to delete document '${this.document.title}'?` - modal.componentInstance.message2 = `The files for this document will be deleted permanently. This operation cannot be undone.` - modal.componentInstance.deleteClicked.subscribe(() => { + let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'}) + modal.componentInstance.title = "Confirm delete" + modal.componentInstance.messageBold = `Do you really want to delete document '${this.document.title}'?` + modal.componentInstance.message = `The files for this document will be deleted permanently. This operation cannot be undone.` + modal.componentInstance.btnClass = "btn-danger" + modal.componentInstance.btnCaption = "Delete document" + modal.componentInstance.confirmClicked.subscribe(() => { this.documentsService.delete(this.document).subscribe(() => { modal.close() this.close() diff --git a/src-ui/src/app/components/document-detail/metadata-collapse/metadata-collapse.component.html b/src-ui/src/app/components/document-detail/metadata-collapse/metadata-collapse.component.html new file mode 100644 index 000000000..e8fda1d0b --- /dev/null +++ b/src-ui/src/app/components/document-detail/metadata-collapse/metadata-collapse.component.html @@ -0,0 +1,23 @@ +<h6> + <button type="button" class="btn btn-outline-secondary btn-sm mr-2" + (click)="expand = !expand"> + <svg class="buttonicon" fill="currentColor" *ngIf="!expand"> + <use xlink:href="assets/bootstrap-icons.svg#caret-down" /> + </svg> + <svg class="buttonicon" fill="currentColor" *ngIf="expand"> + <use xlink:href="assets/bootstrap-icons.svg#caret-up" /> + </svg> + </button> + {{title}} +</h6> + +<div #collapse="ngbCollapse" [(ngbCollapse)]="!expand"> + <table class="table table-borderless"> + <tbody> + <tr *ngFor="let m of metadata"> + <td>{{m.prefix}}:{{m.key}}</td> + <td>{{m.value}}</td> + </tr> + </tbody> + </table> +</div> \ No newline at end of file diff --git a/src-ui/src/app/components/document-detail/metadata-collapse/metadata-collapse.component.scss b/src-ui/src/app/components/document-detail/metadata-collapse/metadata-collapse.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src-ui/src/app/components/document-detail/metadata-collapse/metadata-collapse.component.spec.ts b/src-ui/src/app/components/document-detail/metadata-collapse/metadata-collapse.component.spec.ts new file mode 100644 index 000000000..2bd96760b --- /dev/null +++ b/src-ui/src/app/components/document-detail/metadata-collapse/metadata-collapse.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MetadataCollapseComponent } from './metadata-collapse.component'; + +describe('MetadataCollapseComponent', () => { + let component: MetadataCollapseComponent; + let fixture: ComponentFixture<MetadataCollapseComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ MetadataCollapseComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(MetadataCollapseComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src-ui/src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts b/src-ui/src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts new file mode 100644 index 000000000..160274e41 --- /dev/null +++ b/src-ui/src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -0,0 +1,23 @@ +import { Component, Input, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-metadata-collapse', + templateUrl: './metadata-collapse.component.html', + styleUrls: ['./metadata-collapse.component.scss'] +}) +export class MetadataCollapseComponent implements OnInit { + + constructor() { } + + expand = false + + @Input() + metadata + + @Input() + title = "Metadata" + + ngOnInit(): void { + } + +} 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 4d5597220..36c70a00e 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 @@ -15,7 +15,7 @@ import { TagService } from 'src/app/services/rest/tag.service'; import { SavedViewConfigService } from 'src/app/services/saved-view-config.service'; import { Toast, ToastService } from 'src/app/services/toast.service'; import { environment } from 'src/environments/environment'; -import { DeleteDialogComponent } from '../common/delete-dialog/delete-dialog.component'; +import { ConfirmDialogComponent } from '../common/confirm-dialog/confirm-dialog.component'; import { SelectDialogComponent } from '../common/select-dialog/select-dialog.component'; import { SaveViewConfigDialogComponent } from './save-view-config-dialog/save-view-config-dialog.component'; @@ -238,11 +238,14 @@ export class DocumentListComponent implements OnInit { } bulkDelete() { - let modal = this.modalService.open(DeleteDialogComponent, {backdrop: 'static'}) + let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'}) modal.componentInstance.delayConfirm(5) - modal.componentInstance.message = `This operation will permanently delete all ${this.list.selected.size} selected document(s).` - modal.componentInstance.message2 = `This operation cannot be undone.` - modal.componentInstance.deleteClicked.subscribe(() => { + modal.componentInstance.title = "Delete confirm" + modal.componentInstance.messageBold = `This operation will permanently delete all ${this.list.selected.size} selected document(s).` + modal.componentInstance.message = `This operation cannot be undone.` + modal.componentInstance.btnClass = "btn-danger" + modal.componentInstance.btnCaption = "Delete document(s)" + modal.componentInstance.confirmClicked.subscribe(() => { this.executeBulkOperation("delete", {}).subscribe( response => { modal.close() 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 d5477d010..59a5f09ed 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,7 +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 { DeleteDialogComponent } from '../../common/delete-dialog/delete-dialog.component'; +import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dialog.component'; @Directive() export abstract class GenericListComponent<T extends ObjectWithId> implements OnInit { @@ -88,10 +88,13 @@ export abstract class GenericListComponent<T extends ObjectWithId> implements On } openDeleteDialog(object: T) { - var activeModal = this.modalService.open(DeleteDialogComponent, {backdrop: 'static'}) - activeModal.componentInstance.message = `Do you really want to delete ${this.getObjectName(object)}?` - activeModal.componentInstance.message2 = "Associated documents will not be deleted." - activeModal.componentInstance.deleteClicked.subscribe(() => { + var activeModal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'}) + activeModal.componentInstance.title = "Confirm delete" + activeModal.componentInstance.messageBold = `Do you really want to delete ${this.getObjectName(object)}?` + activeModal.componentInstance.message = "Associated documents will not be deleted." + activeModal.componentInstance.btnClass = "btn-danger" + activeModal.componentInstance.btnCaption = "Delete" + activeModal.componentInstance.confirmPressed.subscribe(() => { this.service.delete(object).subscribe(_ => { activeModal.close() this.reloadData()