diff --git a/portal-frontend/src/app/worklist/worklist-list/worklist-list.html b/portal-frontend/src/app/worklist/worklist-list/worklist-list.html index ed2d28b..e2780db 100644 --- a/portal-frontend/src/app/worklist/worklist-list/worklist-list.html +++ b/portal-frontend/src/app/worklist/worklist-list/worklist-list.html @@ -1 +1,43 @@ -

worklist-list works!

+

Werkvoorraad

+ +
+ + + +
+ + + + + + + + + + + + + + + @for (item of items(); track keyOf(item).id) { + + + + + + + + + + } + +
OriginReferentieNaamBSNOntvangenUitkomstProcesstatus
{{ item.origin }}{{ keyOf(item).id }}{{ item.surname }}, {{ item.initials }}{{ item.bsn }}{{ item.receivedOn }}{{ item.assessmentOutcome ?? 'n.v.t.' }}{{ item.processStatus ?? 'n.v.t.' }}
diff --git a/portal-frontend/src/app/worklist/worklist-list/worklist-list.spec.ts b/portal-frontend/src/app/worklist/worklist-list/worklist-list.spec.ts index d531ca7..122c47c 100644 --- a/portal-frontend/src/app/worklist/worklist-list/worklist-list.spec.ts +++ b/portal-frontend/src/app/worklist/worklist-list/worklist-list.spec.ts @@ -1,22 +1,91 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { Router, provideRouter } from '@angular/router'; +import { of } from 'rxjs'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { WorklistService } from '../worklist.service'; +import { WorklistItem, WorklistPage, WorklistQuery } from '../worklist.types'; import { WorklistList } from './worklist-list'; +const legacyItem: WorklistItem = { + origin: 'Legacy', + legacyAanvraagId: 1001, + registrationApplicationId: null, + surname: 'de Vries', + initials: 'A.', + bsn: '123456782', + receivedOn: '2026-01-01', + bucket: 'ToBeAssessed', + assessmentOutcome: null, + processStatus: null, +}; + +const ownedItem: WorklistItem = { + ...legacyItem, + origin: 'Owned', + legacyAanvraagId: null, + registrationApplicationId: '00000000-0000-0000-0000-000000000002', +}; + +function pageOf(items: WorklistItem[]): WorklistPage { + return { items, page: 1, pageSize: 10, totalCount: items.length }; +} + describe('WorklistList', () => { - let component: WorklistList; let fixture: ComponentFixture; + let getWorklist: ReturnType; + let router: Router; + + function createComponent() { + fixture = TestBed.createComponent(WorklistList); + fixture.detectChanges(); + router = TestBed.inject(Router); + } beforeEach(async () => { + getWorklist = vi.fn().mockReturnValue(of(pageOf([legacyItem, ownedItem]))); + await TestBed.configureTestingModule({ imports: [WorklistList], + providers: [provideRouter([]), { provide: WorklistService, useValue: { getWorklist } }], }).compileComponents(); - - fixture = TestBed.createComponent(WorklistList); - component = fixture.componentInstance; - await fixture.whenStable(); }); - it('should create', () => { - expect(component).toBeTruthy(); + it('loads and renders the worklist on init', () => { + createComponent(); + + expect(getWorklist).toHaveBeenCalledWith({ bucket: undefined, origin: undefined, search: undefined }); + const rows = fixture.nativeElement.querySelectorAll('[data-testid="worklist-row"]'); + expect(rows.length).toBe(2); + }); + + it('given a legacy-origin row, navigates to legacy/:id on click', () => { + createComponent(); + const navigate = vi.spyOn(router, 'navigate'); + + const rows = fixture.nativeElement.querySelectorAll('[data-testid="worklist-row"]'); + rows[0].click(); + + expect(navigate).toHaveBeenCalledWith(['legacy', 1001]); + }); + + it('given an owned-origin row, navigates to owned/:id on click', () => { + createComponent(); + const navigate = vi.spyOn(router, 'navigate'); + + const rows = fixture.nativeElement.querySelectorAll('[data-testid="worklist-row"]'); + rows[1].click(); + + expect(navigate).toHaveBeenCalledWith(['owned', '00000000-0000-0000-0000-000000000002']); + }); + + it('reloads with the new query when a filter changes', () => { + createComponent(); + getWorklist.mockClear(); + + fixture.componentInstance.bucket = 'ToBeAssessed'; + fixture.componentInstance.onFilterChange(); + + expect(getWorklist).toHaveBeenCalledWith({ bucket: 'ToBeAssessed', origin: undefined, search: undefined } satisfies WorklistQuery); }); }); diff --git a/portal-frontend/src/app/worklist/worklist-list/worklist-list.ts b/portal-frontend/src/app/worklist/worklist-list/worklist-list.ts index 2635d9b..f009611 100644 --- a/portal-frontend/src/app/worklist/worklist-list/worklist-list.ts +++ b/portal-frontend/src/app/worklist/worklist-list/worklist-list.ts @@ -1,9 +1,51 @@ -import { Component } from '@angular/core'; +import { Component, inject, signal } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { Router } from '@angular/router'; + +import { WorklistService } from '../worklist.service'; +import { WorklistItem, WorklistQuery } from '../worklist.types'; @Component({ selector: 'app-worklist-list', - imports: [], + imports: [FormsModule], templateUrl: './worklist-list.html', styleUrl: './worklist-list.css', }) -export class WorklistList {} +export class WorklistList { + private readonly worklistService = inject(WorklistService); + private readonly router = inject(Router); + + readonly items = signal([]); + + bucket = ''; + origin = ''; + search = ''; + + constructor() { + this.load(); + } + + onFilterChange(): void { + this.load(); + } + + keyOf(item: WorklistItem): { segment: 'legacy' | 'owned'; id: number | string } { + return item.origin === 'Legacy' + ? { segment: 'legacy', id: item.legacyAanvraagId! } + : { segment: 'owned', id: item.registrationApplicationId! }; + } + + openDetail(item: WorklistItem): void { + const { segment, id } = this.keyOf(item); + this.router.navigate([segment, id]); + } + + private load(): void { + const query: WorklistQuery = { + bucket: this.bucket || undefined, + origin: this.origin || undefined, + search: this.search || undefined, + }; + this.worklistService.getWorklist(query).subscribe((page) => this.items.set(page.items)); + } +}