mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-02 13:45:10 -05:00
Settings navigation warning dialog
This commit is contained in:
parent
6c5f9bbabb
commit
b0fa0f2319
@ -11,6 +11,7 @@ import { SettingsComponent } from './components/manage/settings/settings.compone
|
|||||||
import { TagListComponent } from './components/manage/tag-list/tag-list.component';
|
import { TagListComponent } from './components/manage/tag-list/tag-list.component';
|
||||||
import { NotFoundComponent } from './components/not-found/not-found.component';
|
import { NotFoundComponent } from './components/not-found/not-found.component';
|
||||||
import { SearchComponent } from './components/search/search.component';
|
import { SearchComponent } from './components/search/search.component';
|
||||||
|
import { FormDirtyGuard } from './guards/dirty-form.guard';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{path: '', redirectTo: 'dashboard', pathMatch: 'full'},
|
{path: '', redirectTo: 'dashboard', pathMatch: 'full'},
|
||||||
@ -25,7 +26,7 @@ const routes: Routes = [
|
|||||||
{path: 'documenttypes', component: DocumentTypeListComponent },
|
{path: 'documenttypes', component: DocumentTypeListComponent },
|
||||||
{path: 'correspondents', component: CorrespondentListComponent },
|
{path: 'correspondents', component: CorrespondentListComponent },
|
||||||
{path: 'logs', component: LogsComponent },
|
{path: 'logs', component: LogsComponent },
|
||||||
{path: 'settings', component: SettingsComponent },
|
{path: 'settings', component: SettingsComponent, canDeactivate: [FormDirtyGuard] },
|
||||||
]},
|
]},
|
||||||
|
|
||||||
{path: '404', component: NotFoundComponent},
|
{path: '404', component: NotFoundComponent},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h4 class="modal-title" id="modal-basic-title">{{title}}</h4>
|
<h4 class="modal-title" id="modal-basic-title">{{title}}</h4>
|
||||||
<button type="button" class="close" aria-label="Close" (click)="cancelClicked()">
|
<button type="button" class="close" aria-label="Close" (click)="cancel()">
|
||||||
<span aria-hidden="true">×</span>
|
<span aria-hidden="true">×</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -9,8 +9,8 @@
|
|||||||
<p *ngIf="message">{{message}}</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()" [disabled]="!buttonsEnabled" i18n>Cancel</button>
|
<button type="button" class="btn btn-outline-dark" (click)="cancel()" [disabled]="!buttonsEnabled" i18n>Cancel</button>
|
||||||
<button type="button" class="btn" [class]="btnClass" (click)="confirmClicked.emit()" [disabled]="!confirmButtonEnabled || !buttonsEnabled">
|
<button type="button" class="btn" [class]="btnClass" (click)="confirm()" [disabled]="!confirmButtonEnabled || !buttonsEnabled">
|
||||||
{{btnCaption}}
|
{{btnCaption}}
|
||||||
<span *ngIf="!confirmButtonEnabled"> ({{seconds}})</span>
|
<span *ngIf="!confirmButtonEnabled"> ({{seconds}})</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
import { Subject } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-confirm-dialog',
|
selector: 'app-confirm-dialog',
|
||||||
@ -8,8 +9,6 @@ import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
|||||||
})
|
})
|
||||||
export class ConfirmDialogComponent implements OnInit {
|
export class ConfirmDialogComponent implements OnInit {
|
||||||
|
|
||||||
constructor(public activeModal: NgbActiveModal) { }
|
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
public confirmClicked = new EventEmitter()
|
public confirmClicked = new EventEmitter()
|
||||||
|
|
||||||
@ -34,6 +33,12 @@ export class ConfirmDialogComponent implements OnInit {
|
|||||||
confirmButtonEnabled = true
|
confirmButtonEnabled = true
|
||||||
seconds = 0
|
seconds = 0
|
||||||
|
|
||||||
|
subject: Subject<boolean>
|
||||||
|
|
||||||
|
constructor(public activeModal: NgbActiveModal) {
|
||||||
|
this.confirmClicked.asObservable()
|
||||||
|
}
|
||||||
|
|
||||||
delayConfirm(seconds: number) {
|
delayConfirm(seconds: number) {
|
||||||
this.confirmButtonEnabled = false
|
this.confirmButtonEnabled = false
|
||||||
this.seconds = seconds
|
this.seconds = seconds
|
||||||
@ -49,7 +54,15 @@ export class ConfirmDialogComponent implements OnInit {
|
|||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
cancelClicked() {
|
cancel() {
|
||||||
|
this.subject?.next(false)
|
||||||
|
this.subject?.complete()
|
||||||
this.activeModal.close()
|
this.activeModal.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
confirm() {
|
||||||
|
this.subject?.next(true)
|
||||||
|
this.subject?.complete()
|
||||||
|
this.confirmClicked.emit()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,9 +32,9 @@ export class SettingsComponent implements OnInit, OnDestroy, DirtyComponent {
|
|||||||
|
|
||||||
savedViews: PaperlessSavedView[]
|
savedViews: PaperlessSavedView[]
|
||||||
|
|
||||||
store: BehaviorSubject<any>;
|
store: BehaviorSubject<any>
|
||||||
storeSub: Subscription;
|
storeSub: Subscription
|
||||||
isDirty$: Observable<boolean>;
|
isDirty$: Observable<boolean>
|
||||||
|
|
||||||
get computedDateLocale(): string {
|
get computedDateLocale(): string {
|
||||||
return this.settingsForm.value.dateLocale || this.settingsForm.value.displayLanguage
|
return this.settingsForm.value.dateLocale || this.settingsForm.value.displayLanguage
|
||||||
@ -82,10 +82,10 @@ export class SettingsComponent implements OnInit, OnDestroy, DirtyComponent {
|
|||||||
|
|
||||||
this.storeSub = this.store.asObservable().subscribe(state => {
|
this.storeSub = this.store.asObservable().subscribe(state => {
|
||||||
this.settingsForm.patchValue(state, { emitEvent: false })
|
this.settingsForm.patchValue(state, { emitEvent: false })
|
||||||
});
|
})
|
||||||
|
|
||||||
// Initialize dirtyCheck
|
// Initialize dirtyCheck
|
||||||
this.isDirty$ = dirtyCheck(this.settingsForm, this.store.asObservable());
|
this.isDirty$ = dirtyCheck(this.settingsForm, this.store.asObservable())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
29
src-ui/src/app/guards/dirty-form.guard.ts
Normal file
29
src-ui/src/app/guards/dirty-form.guard.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { DirtyCheckGuard } from '@ngneat/dirty-check-forms';
|
||||||
|
import { Observable, Subject } from 'rxjs';
|
||||||
|
import { map } from 'rxjs/operators';
|
||||||
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
import { ConfirmDialogComponent } from 'src/app/components/common/confirm-dialog/confirm-dialog.component';
|
||||||
|
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class FormDirtyGuard extends DirtyCheckGuard {
|
||||||
|
constructor(private modalService: NgbModal) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
confirmChanges(): Observable<boolean> {
|
||||||
|
let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'})
|
||||||
|
modal.componentInstance.title = $localize`Confirm`
|
||||||
|
modal.componentInstance.messageBold = $localize`You have unsaved changes.`
|
||||||
|
modal.componentInstance.message = $localize`Are you sure you want to leave?`
|
||||||
|
modal.componentInstance.btnClass = "btn-warning"
|
||||||
|
modal.componentInstance.btnCaption = $localize`Ok`
|
||||||
|
modal.componentInstance.confirmClicked.subscribe(() => {
|
||||||
|
modal.componentInstance.buttonsEnabled = false
|
||||||
|
modal.close()
|
||||||
|
})
|
||||||
|
const subject = new Subject<boolean>()
|
||||||
|
modal.componentInstance.subject = subject
|
||||||
|
return subject.asObservable()
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user