mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-02 13:45:10 -05:00
Enhancement: improve doc details close behavior (#8937)
This commit is contained in:
parent
9c6f695dbf
commit
978b072bff
@ -5,6 +5,7 @@ import { first, Subscription } from 'rxjs'
|
||||
import { ToastsComponent } from './components/common/toasts/toasts.component'
|
||||
import { FileDropComponent } from './components/file-drop/file-drop.component'
|
||||
import { SETTINGS_KEYS } from './data/ui-settings'
|
||||
import { ComponentRouterService } from './services/component-router.service'
|
||||
import { ConsumerStatusService } from './services/consumer-status.service'
|
||||
import { HotKeyService } from './services/hot-key.service'
|
||||
import {
|
||||
@ -41,7 +42,8 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||
public tourService: TourService,
|
||||
private renderer: Renderer2,
|
||||
private permissionsService: PermissionsService,
|
||||
private hotKeyService: HotKeyService
|
||||
private hotKeyService: HotKeyService,
|
||||
private componentRouterService: ComponentRouterService
|
||||
) {
|
||||
let anyWindow = window as any
|
||||
anyWindow.pdfWorkerSrc = 'assets/js/pdf.worker.min.mjs'
|
||||
|
@ -45,6 +45,7 @@ import { Tag } from 'src/app/data/tag'
|
||||
import { PermissionsGuard } from 'src/app/guards/permissions.guard'
|
||||
import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe'
|
||||
import { DocumentTitlePipe } from 'src/app/pipes/document-title.pipe'
|
||||
import { ComponentRouterService } from 'src/app/services/component-router.service'
|
||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
|
||||
import { OpenDocumentsService } from 'src/app/services/open-documents.service'
|
||||
import { PermissionsService } from 'src/app/services/permissions.service'
|
||||
@ -127,6 +128,7 @@ describe('DocumentDetailComponent', () => {
|
||||
let settingsService: SettingsService
|
||||
let customFieldsService: CustomFieldsService
|
||||
let httpTestingController: HttpTestingController
|
||||
let componentRouterService: ComponentRouterService
|
||||
|
||||
let currentUserCan = true
|
||||
let currentUserHasObjectPermissions = true
|
||||
@ -264,6 +266,7 @@ describe('DocumentDetailComponent', () => {
|
||||
customFieldsService = TestBed.inject(CustomFieldsService)
|
||||
fixture = TestBed.createComponent(DocumentDetailComponent)
|
||||
httpTestingController = TestBed.inject(HttpTestingController)
|
||||
componentRouterService = TestBed.inject(ComponentRouterService)
|
||||
component = fixture.componentInstance
|
||||
})
|
||||
|
||||
@ -568,6 +571,16 @@ describe('DocumentDetailComponent', () => {
|
||||
expect(navigateSpy).toHaveBeenCalledWith(['documents'])
|
||||
})
|
||||
|
||||
it('should allow close and navigate to the last view if available', () => {
|
||||
initNormally()
|
||||
jest
|
||||
.spyOn(componentRouterService, 'getComponentURLBefore')
|
||||
.mockReturnValue('dashboard')
|
||||
const navigateSpy = jest.spyOn(router, 'navigate')
|
||||
component.close()
|
||||
expect(navigateSpy).toHaveBeenCalledWith(['dashboard'])
|
||||
})
|
||||
|
||||
it('should allow close and navigate to documents by default', () => {
|
||||
initNormally()
|
||||
jest
|
||||
|
@ -59,6 +59,7 @@ import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe'
|
||||
import { DocumentTitlePipe } from 'src/app/pipes/document-title.pipe'
|
||||
import { FileSizePipe } from 'src/app/pipes/file-size.pipe'
|
||||
import { SafeUrlPipe } from 'src/app/pipes/safeurl.pipe'
|
||||
import { ComponentRouterService } from 'src/app/services/component-router.service'
|
||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
|
||||
import { HotKeyService } from 'src/app/services/hot-key.service'
|
||||
import { OpenDocumentsService } from 'src/app/services/open-documents.service'
|
||||
@ -272,7 +273,8 @@ export class DocumentDetailComponent
|
||||
private userService: UserService,
|
||||
private customFieldsService: CustomFieldsService,
|
||||
private http: HttpClient,
|
||||
private hotKeyService: HotKeyService
|
||||
private hotKeyService: HotKeyService,
|
||||
private componentRouterService: ComponentRouterService
|
||||
) {
|
||||
super()
|
||||
}
|
||||
@ -888,6 +890,10 @@ export class DocumentDetailComponent
|
||||
'view',
|
||||
this.documentListViewService.activeSavedViewId,
|
||||
])
|
||||
} else if (this.componentRouterService.getComponentURLBefore()) {
|
||||
this.router.navigate([
|
||||
this.componentRouterService.getComponentURLBefore(),
|
||||
])
|
||||
} else {
|
||||
this.router.navigate(['documents'])
|
||||
}
|
||||
|
102
src-ui/src/app/services/component-router.service.spec.ts
Normal file
102
src-ui/src/app/services/component-router.service.spec.ts
Normal file
@ -0,0 +1,102 @@
|
||||
import { TestBed } from '@angular/core/testing'
|
||||
import { ActivationStart, Router } from '@angular/router'
|
||||
import { Subject } from 'rxjs'
|
||||
import { ComponentRouterService } from './component-router.service'
|
||||
|
||||
describe('ComponentRouterService', () => {
|
||||
let service: ComponentRouterService
|
||||
let router: Router
|
||||
let eventsSubject: Subject<any>
|
||||
|
||||
beforeEach(() => {
|
||||
eventsSubject = new Subject<any>()
|
||||
TestBed.configureTestingModule({
|
||||
providers: [
|
||||
ComponentRouterService,
|
||||
{
|
||||
provide: Router,
|
||||
useValue: {
|
||||
events: eventsSubject.asObservable(),
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
service = TestBed.inject(ComponentRouterService)
|
||||
router = TestBed.inject(Router)
|
||||
})
|
||||
|
||||
it('should add to history and componentHistory on ActivationStart event', () => {
|
||||
eventsSubject.next(
|
||||
new ActivationStart({
|
||||
url: 'test-url',
|
||||
component: { name: 'TestComponent' },
|
||||
} as any)
|
||||
)
|
||||
|
||||
expect((service as any).history).toEqual(['test-url'])
|
||||
expect((service as any).componentHistory).toEqual(['TestComponent'])
|
||||
})
|
||||
|
||||
it('should not add duplicate component names to componentHistory', () => {
|
||||
eventsSubject.next(
|
||||
new ActivationStart({
|
||||
url: 'test-url-1',
|
||||
component: { name: 'TestComponent' },
|
||||
} as any)
|
||||
)
|
||||
eventsSubject.next(
|
||||
new ActivationStart({
|
||||
url: 'test-url-2',
|
||||
component: { name: 'TestComponent' },
|
||||
} as any)
|
||||
)
|
||||
|
||||
expect((service as any).componentHistory.length).toBe(1)
|
||||
expect((service as any).componentHistory).toEqual(['TestComponent'])
|
||||
})
|
||||
|
||||
it('should return the URL of the component before the current one', () => {
|
||||
eventsSubject.next(
|
||||
new ActivationStart({
|
||||
url: 'test-url-1',
|
||||
component: { name: 'TestComponent1' },
|
||||
} as any)
|
||||
)
|
||||
eventsSubject.next(
|
||||
new ActivationStart({
|
||||
url: 'test-url-2',
|
||||
component: { name: 'TestComponent2' },
|
||||
} as any)
|
||||
)
|
||||
|
||||
expect(service.getComponentURLBefore()).toBe('test-url-1')
|
||||
})
|
||||
|
||||
it('should update the URL of the current component if the same component is loaded via a different URL', () => {
|
||||
eventsSubject.next(
|
||||
new ActivationStart({
|
||||
url: 'test-url-1',
|
||||
component: { name: 'TestComponent' },
|
||||
} as any)
|
||||
)
|
||||
eventsSubject.next(
|
||||
new ActivationStart({
|
||||
url: 'test-url-2',
|
||||
component: { name: 'TestComponent' },
|
||||
} as any)
|
||||
)
|
||||
|
||||
expect((service as any).history).toEqual(['test-url-2'])
|
||||
})
|
||||
|
||||
it('should return null if there is no previous component', () => {
|
||||
eventsSubject.next(
|
||||
new ActivationStart({
|
||||
url: 'test-url',
|
||||
component: { name: 'TestComponent' },
|
||||
} as any)
|
||||
)
|
||||
|
||||
expect(service.getComponentURLBefore()).toBeNull()
|
||||
})
|
||||
})
|
35
src-ui/src/app/services/component-router.service.ts
Normal file
35
src-ui/src/app/services/component-router.service.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import { Injectable } from '@angular/core'
|
||||
import { ActivationStart, Event, Router } from '@angular/router'
|
||||
import { filter } from 'rxjs'
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ComponentRouterService {
|
||||
private history: string[] = []
|
||||
private componentHistory: any[] = []
|
||||
|
||||
constructor(private router: Router) {
|
||||
this.router.events
|
||||
.pipe(filter((event: Event) => event instanceof ActivationStart))
|
||||
.subscribe((event: ActivationStart) => {
|
||||
if (
|
||||
this.componentHistory[this.componentHistory.length - 1] !==
|
||||
event.snapshot.component.name
|
||||
) {
|
||||
this.history.push(event.snapshot.url.toString())
|
||||
this.componentHistory.push(event.snapshot.component.name)
|
||||
} else {
|
||||
// Update the URL of the current component in case the same component was loaded via a different URL
|
||||
this.history[this.history.length - 1] = event.snapshot.url.toString()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
public getComponentURLBefore(): any {
|
||||
if (this.componentHistory.length > 1) {
|
||||
return this.history[this.history.length - 2]
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user