From 5a93d46a0cb48a49d55c81d1988ed05445dd87ad Mon Sep 17 00:00:00 2001 From: shamoon <4887959+shamoon@users.noreply.github.com> Date: Tue, 7 Jul 2026 16:56:23 -0700 Subject: [PATCH] Convert management component, custom fields to signals --- .../custom-fields/custom-fields.component.ts | 18 ++-- .../document-attributes.component.ts | 35 ++++---- .../management-list.component.ts | 85 ++++++++++++++++--- 3 files changed, 103 insertions(+), 35 deletions(-) diff --git a/src-ui/src/app/components/manage/document-attributes/custom-fields/custom-fields.component.ts b/src-ui/src/app/components/manage/document-attributes/custom-fields/custom-fields.component.ts index 9b9eb98bf..e264cbb8f 100644 --- a/src-ui/src/app/components/manage/document-attributes/custom-fields/custom-fields.component.ts +++ b/src-ui/src/app/components/manage/document-attributes/custom-fields/custom-fields.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject } from '@angular/core' +import { Component, OnInit, inject, signal } from '@angular/core' import { RouterModule } from '@angular/router' import { NgbDropdownModule, @@ -6,7 +6,7 @@ import { NgbPaginationModule, } from '@ng-bootstrap/ng-bootstrap' import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons' -import { delay, takeUntil, tap } from 'rxjs' +import { takeUntil, tap } from 'rxjs' import { ConfirmDialogComponent } from 'src/app/components/common/confirm-dialog/confirm-dialog.component' import { CustomFieldEditDialogComponent } from 'src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component' import { EditDialogMode } from 'src/app/components/common/edit-dialog/edit-dialog.component' @@ -51,21 +51,29 @@ export class CustomFieldsComponent private readonly documentService = inject(DocumentService) private readonly savedViewService = inject(SavedViewService) - public fields: CustomField[] = [] + private fieldsSignal = signal([]) + + public get fields(): CustomField[] { + return this.fieldsSignal() + } + + public set fields(fields: CustomField[]) { + this.fieldsSignal.set(fields) + } ngOnInit() { this.reload() } reload() { + this.loading = true this.customFieldsService .listAll() .pipe( takeUntil(this.unsubscribeNotifier), tap((r) => { this.fields = r.results - }), - delay(100) + }) ) .subscribe(() => { this.show = true diff --git a/src-ui/src/app/components/manage/document-attributes/document-attributes.component.ts b/src-ui/src/app/components/manage/document-attributes/document-attributes.component.ts index 8396ca6b2..f65694827 100644 --- a/src-ui/src/app/components/manage/document-attributes/document-attributes.component.ts +++ b/src-ui/src/app/components/manage/document-attributes/document-attributes.component.ts @@ -1,11 +1,10 @@ import { NgComponentOutlet } from '@angular/common' import { - AfterViewChecked, - ChangeDetectorRef, Component, inject, OnDestroy, OnInit, + signal, Type, ViewChild, } from '@angular/core' @@ -70,13 +69,10 @@ interface DocumentAttributesSection { ClearableBadgeComponent, ], }) -export class DocumentAttributesComponent - implements OnInit, OnDestroy, AfterViewChecked -{ +export class DocumentAttributesComponent implements OnInit, OnDestroy { private readonly permissionsService = inject(PermissionsService) private readonly activatedRoute = inject(ActivatedRoute) private readonly router = inject(Router) - private readonly cdr = inject(ChangeDetectorRef) private readonly unsubscribeNotifier = new Subject() protected readonly PermissionAction = PermissionAction @@ -136,11 +132,20 @@ export class DocumentAttributesComponent ] @ViewChild('activeOutlet', { read: NgComponentOutlet }) - private readonly activeOutlet?: NgComponentOutlet + set activeOutlet(outlet: NgComponentOutlet | undefined) { + this.activeComponentSignal.set(outlet?.componentInstance ?? null) + } - private lastHeaderLoading: boolean + private activeComponentSignal = signal(null) + private activeNavIDSignal = signal(null) - activeNavID: number = null + get activeNavID(): number { + return this.activeNavIDSignal() + } + + set activeNavID(activeNavID: number) { + this.activeNavIDSignal.set(activeNavID) + } get visibleSections(): DocumentAttributesSection[] { return this.sections.filter((section) => @@ -163,14 +168,14 @@ export class DocumentAttributesComponent this.activeSection?.kind !== DocumentAttributesSectionKind.ManagementList ) return null - const instance = this.activeOutlet?.componentInstance + const instance = this.activeComponentSignal() return instance instanceof ManagementListComponent ? instance : null } get activeCustomFields(): CustomFieldsComponent | null { if (this.activeSection?.kind !== DocumentAttributesSectionKind.CustomFields) return null - const instance = this.activeOutlet?.componentInstance + const instance = this.activeComponentSignal() return instance instanceof CustomFieldsComponent ? instance : null } @@ -221,14 +226,6 @@ export class DocumentAttributesComponent this.unsubscribeNotifier.complete() } - ngAfterViewChecked(): void { - const current = this.activeHeaderLoading - if (this.lastHeaderLoading !== current) { - this.lastHeaderLoading = current - this.cdr.detectChanges() - } - } - onNavChange(navChangeEvent: NgbNavChangeEvent): void { const nextSection = this.getSectionForNavID(navChangeEvent.nextId) if (!nextSection) { diff --git a/src-ui/src/app/components/manage/document-attributes/management-list/management-list.component.ts b/src-ui/src/app/components/manage/document-attributes/management-list/management-list.component.ts index fd7c1ae11..01e4a8949 100644 --- a/src-ui/src/app/components/manage/document-attributes/management-list/management-list.component.ts +++ b/src-ui/src/app/components/manage/document-attributes/management-list/management-list.component.ts @@ -5,13 +5,13 @@ import { OnDestroy, OnInit, QueryList, + signal, ViewChildren, } from '@angular/core' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { Subject } from 'rxjs' import { debounceTime, - delay, distinctUntilChanged, takeUntil, tap, @@ -88,25 +88,89 @@ export abstract class ManagementListComponent @ViewChildren(SortableDirective) headers: QueryList - public data: T[] = [] - private unfilteredData: T[] = [] + private dataSignal = signal([]) + private unfilteredDataSignal = signal([]) private currentExtraParams: { [key: string]: any } = null private allSelectionActive = false - public page = 1 + private pageSignal = signal(1) - public collectionSize = 0 - public displayCollectionSize = 0 + private collectionSizeSignal = signal(0) + private displayCollectionSizeSignal = signal(0) - public sortField: string - public sortReverse: boolean + private sortFieldSignal = signal(undefined) + private sortReverseSignal = signal(undefined) private nameFilterDebounce: Subject protected unsubscribeNotifier: Subject = new Subject() protected _nameFilter: string public selectedObjects: Set = new Set() - public togggleAll: boolean = false + private togggleAllSignal = signal(false) + + public get data(): T[] { + return this.dataSignal() + } + + public set data(data: T[]) { + this.dataSignal.set(data) + } + + private get unfilteredData(): T[] { + return this.unfilteredDataSignal() + } + + private set unfilteredData(data: T[]) { + this.unfilteredDataSignal.set(data) + } + + public get page(): number { + return this.pageSignal() + } + + public set page(page: number) { + this.pageSignal.set(page) + } + + public get collectionSize(): number { + return this.collectionSizeSignal() + } + + public set collectionSize(collectionSize: number) { + this.collectionSizeSignal.set(collectionSize) + } + + public get displayCollectionSize(): number { + return this.displayCollectionSizeSignal() + } + + public set displayCollectionSize(displayCollectionSize: number) { + this.displayCollectionSizeSignal.set(displayCollectionSize) + } + + public get sortField(): string { + return this.sortFieldSignal() + } + + public set sortField(sortField: string) { + this.sortFieldSignal.set(sortField) + } + + public get sortReverse(): boolean { + return this.sortReverseSignal() + } + + public set sortReverse(sortReverse: boolean) { + this.sortReverseSignal.set(sortReverse) + } + + public get togggleAll(): boolean { + return this.togggleAllSignal() + } + + public set togggleAll(togggleAll: boolean) { + this.togggleAllSignal.set(togggleAll) + } public get hasSelection(): boolean { return this.selectedObjects.size > 0 || this.allSelectionActive @@ -201,8 +265,7 @@ export abstract class ManagementListComponent this.data = this.filterData(c.results) this.collectionSize = this.getCollectionSize(c) this.displayCollectionSize = this.getDisplayCollectionSize(c) - }), - delay(100) + }) ) .subscribe({ error: (error: HttpErrorResponse) => {