mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-11 10:00:48 -05:00
Merge branch 'dev' into feature-bulk-edit
This commit is contained in:
commit
bb9b438aa6
@ -16,7 +16,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|||||||
import { DatePipe } from '@angular/common';
|
import { DatePipe } from '@angular/common';
|
||||||
import { NotFoundComponent } from './components/not-found/not-found.component';
|
import { NotFoundComponent } from './components/not-found/not-found.component';
|
||||||
import { CorrespondentListComponent } from './components/manage/correspondent-list/correspondent-list.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 { 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 { 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';
|
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 { YesNoPipe } from './pipes/yes-no.pipe';
|
||||||
import { FileSizePipe } from './pipes/file-size.pipe';
|
import { FileSizePipe } from './pipes/file-size.pipe';
|
||||||
import { DocumentTitlePipe } from './pipes/document-title.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';
|
import { SelectDialogComponent } from './components/common/select-dialog/select-dialog.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@ -64,7 +65,7 @@ import { SelectDialogComponent } from './components/common/select-dialog/select-
|
|||||||
SettingsComponent,
|
SettingsComponent,
|
||||||
NotFoundComponent,
|
NotFoundComponent,
|
||||||
CorrespondentEditDialogComponent,
|
CorrespondentEditDialogComponent,
|
||||||
DeleteDialogComponent,
|
ConfirmDialogComponent,
|
||||||
TagEditDialogComponent,
|
TagEditDialogComponent,
|
||||||
DocumentTypeEditDialogComponent,
|
DocumentTypeEditDialogComponent,
|
||||||
TagComponent,
|
TagComponent,
|
||||||
@ -91,6 +92,7 @@ import { SelectDialogComponent } from './components/common/select-dialog/select-
|
|||||||
YesNoPipe,
|
YesNoPipe,
|
||||||
FileSizePipe,
|
FileSizePipe,
|
||||||
DocumentTitlePipe,
|
DocumentTitlePipe,
|
||||||
|
MetadataCollapseComponent,
|
||||||
SelectDialogComponent
|
SelectDialogComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
|
@ -5,10 +5,13 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<p><b>{{message}}</b></p>
|
<p *ngIf="messageBold"><b>{{messageBold}}</b></p>
|
||||||
<p *ngIf="message2">{{message2}}</p>
|
<p *ngIf="message">{{message}}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-outline-dark" (click)="cancelClicked()">Cancel</button>
|
<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>
|
<button type="button" class="btn" [class]="btnClass" (click)="confirmClicked.emit()" [disabled]="!confirmButtonEnabled">
|
||||||
|
{{btnCaption}}
|
||||||
|
<span *ngIf="!confirmButtonEnabled"> ({{seconds}})</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
@ -1,20 +1,20 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
import { DeleteDialogComponent } from './delete-dialog.component';
|
import { ConfirmDialogComponent } from './confirm-dialog.component';
|
||||||
|
|
||||||
describe('DeleteDialogComponent', () => {
|
describe('ConfirmDialogComponent', () => {
|
||||||
let component: DeleteDialogComponent;
|
let component: ConfirmDialogComponent;
|
||||||
let fixture: ComponentFixture<DeleteDialogComponent>;
|
let fixture: ComponentFixture<ConfirmDialogComponent>;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
declarations: [ DeleteDialogComponent ]
|
declarations: [ ConfirmDialogComponent ]
|
||||||
})
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(DeleteDialogComponent);
|
fixture = TestBed.createComponent(ConfirmDialogComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
@ -2,35 +2,41 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
|||||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-delete-dialog',
|
selector: 'app-confirm-dialog',
|
||||||
templateUrl: './delete-dialog.component.html',
|
templateUrl: './confirm-dialog.component.html',
|
||||||
styleUrls: ['./delete-dialog.component.scss']
|
styleUrls: ['./confirm-dialog.component.scss']
|
||||||
})
|
})
|
||||||
export class DeleteDialogComponent implements OnInit {
|
export class ConfirmDialogComponent implements OnInit {
|
||||||
|
|
||||||
constructor(public activeModal: NgbActiveModal) { }
|
constructor(public activeModal: NgbActiveModal) { }
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
public deleteClicked = new EventEmitter()
|
public confirmClicked = new EventEmitter()
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
title = "Delete confirmation"
|
title = "Confirmation"
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
message = "Do you really want to delete this?"
|
messageBold
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
message2
|
message
|
||||||
|
|
||||||
deleteButtonEnabled = true
|
@Input()
|
||||||
|
btnClass = "btn-primary"
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
btnCaption = "Confirm"
|
||||||
|
|
||||||
|
confirmButtonEnabled = true
|
||||||
seconds = 0
|
seconds = 0
|
||||||
|
|
||||||
delayConfirm(seconds: number) {
|
delayConfirm(seconds: number) {
|
||||||
this.deleteButtonEnabled = false
|
this.confirmButtonEnabled = false
|
||||||
this.seconds = seconds
|
this.seconds = seconds
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (this.seconds <= 1) {
|
if (this.seconds <= 1) {
|
||||||
this.deleteButtonEnabled = true
|
this.confirmButtonEnabled = true
|
||||||
} else {
|
} else {
|
||||||
this.delayConfirm(seconds - 1)
|
this.delayConfirm(seconds - 1)
|
||||||
}
|
}
|
@ -110,53 +110,8 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<h6 *ngIf="metadata?.original_metadata.length > 0">
|
<app-metadata-collapse title="Original document metadata" [metadata]="metadata.original_metadata" *ngIf="metadata?.original_metadata.length > 0"></app-metadata-collapse>
|
||||||
<button type="button" class="btn btn-outline-secondary btn-sm mr-2"
|
<app-metadata-collapse title="Archived document metadata" [metadata]="metadata.archive_metadata" *ngIf="metadata?.archive_metadata.length > 0"></app-metadata-collapse>
|
||||||
(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>
|
|
||||||
|
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</li>
|
</li>
|
||||||
|
@ -13,7 +13,7 @@ import { CorrespondentService } from 'src/app/services/rest/correspondent.servic
|
|||||||
import { DocumentTypeService } from 'src/app/services/rest/document-type.service';
|
import { DocumentTypeService } from 'src/app/services/rest/document-type.service';
|
||||||
import { DocumentService } from 'src/app/services/rest/document.service';
|
import { DocumentService } from 'src/app/services/rest/document.service';
|
||||||
import { environment } from 'src/environments/environment';
|
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 { 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 { 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() {
|
delete() {
|
||||||
let modal = this.modalService.open(DeleteDialogComponent, {backdrop: 'static'})
|
let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'})
|
||||||
modal.componentInstance.message = `Do you really want to delete document '${this.document.title}'?`
|
modal.componentInstance.title = "Confirm delete"
|
||||||
modal.componentInstance.message2 = `The files for this document will be deleted permanently. This operation cannot be undone.`
|
modal.componentInstance.messageBold = `Do you really want to delete document '${this.document.title}'?`
|
||||||
modal.componentInstance.deleteClicked.subscribe(() => {
|
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(() => {
|
this.documentsService.delete(this.document).subscribe(() => {
|
||||||
modal.close()
|
modal.close()
|
||||||
this.close()
|
this.close()
|
||||||
|
@ -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>
|
@ -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();
|
||||||
|
});
|
||||||
|
});
|
@ -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 {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -15,7 +15,7 @@ import { TagService } from 'src/app/services/rest/tag.service';
|
|||||||
import { SavedViewConfigService } from 'src/app/services/saved-view-config.service';
|
import { SavedViewConfigService } from 'src/app/services/saved-view-config.service';
|
||||||
import { Toast, ToastService } from 'src/app/services/toast.service';
|
import { Toast, ToastService } from 'src/app/services/toast.service';
|
||||||
import { environment } from 'src/environments/environment';
|
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 { SelectDialogComponent } from '../common/select-dialog/select-dialog.component';
|
||||||
import { SaveViewConfigDialogComponent } from './save-view-config-dialog/save-view-config-dialog.component';
|
import { SaveViewConfigDialogComponent } from './save-view-config-dialog/save-view-config-dialog.component';
|
||||||
|
|
||||||
@ -238,11 +238,14 @@ export class DocumentListComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bulkDelete() {
|
bulkDelete() {
|
||||||
let modal = this.modalService.open(DeleteDialogComponent, {backdrop: 'static'})
|
let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'})
|
||||||
modal.componentInstance.delayConfirm(5)
|
modal.componentInstance.delayConfirm(5)
|
||||||
modal.componentInstance.message = `This operation will permanently delete all ${this.list.selected.size} selected document(s).`
|
modal.componentInstance.title = "Delete confirm"
|
||||||
modal.componentInstance.message2 = `This operation cannot be undone.`
|
modal.componentInstance.messageBold = `This operation will permanently delete all ${this.list.selected.size} selected document(s).`
|
||||||
modal.componentInstance.deleteClicked.subscribe(() => {
|
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(
|
this.executeBulkOperation("delete", {}).subscribe(
|
||||||
response => {
|
response => {
|
||||||
modal.close()
|
modal.close()
|
||||||
|
@ -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 { ObjectWithId } from 'src/app/data/object-with-id';
|
||||||
import { SortableDirective, SortEvent } from 'src/app/directives/sortable.directive';
|
import { SortableDirective, SortEvent } from 'src/app/directives/sortable.directive';
|
||||||
import { AbstractPaperlessService } from 'src/app/services/rest/abstract-paperless-service';
|
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()
|
@Directive()
|
||||||
export abstract class GenericListComponent<T extends ObjectWithId> implements OnInit {
|
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) {
|
openDeleteDialog(object: T) {
|
||||||
var activeModal = this.modalService.open(DeleteDialogComponent, {backdrop: 'static'})
|
var activeModal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'})
|
||||||
activeModal.componentInstance.message = `Do you really want to delete ${this.getObjectName(object)}?`
|
activeModal.componentInstance.title = "Confirm delete"
|
||||||
activeModal.componentInstance.message2 = "Associated documents will not be deleted."
|
activeModal.componentInstance.messageBold = `Do you really want to delete ${this.getObjectName(object)}?`
|
||||||
activeModal.componentInstance.deleteClicked.subscribe(() => {
|
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(_ => {
|
this.service.delete(object).subscribe(_ => {
|
||||||
activeModal.close()
|
activeModal.close()
|
||||||
this.reloadData()
|
this.reloadData()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user