From 149de823b5a8f6356380faa3103d53c5deb47b3e Mon Sep 17 00:00:00 2001 From: cv5ch <176032962+cv5ch@users.noreply.github.com> Date: Fri, 26 Sep 2025 12:31:47 +0200 Subject: [PATCH] Bugfix tables showing last-updated --- .../agents-status-table.component.ts | 1 + .../tasks-table/tasks-table.component.ts | 1 + src/app/core/_datasources/base.datasource.ts | 11 +++ .../last-updated.component.spec.ts | 78 +++++++++++++++++-- 4 files changed, 86 insertions(+), 5 deletions(-) diff --git a/src/app/core/_components/tables/agents-status-table/agents-status-table.component.ts b/src/app/core/_components/tables/agents-status-table/agents-status-table.component.ts index f5f4b7ac..2ee5290d 100644 --- a/src/app/core/_components/tables/agents-status-table/agents-status-table.component.ts +++ b/src/app/core/_components/tables/agents-status-table/agents-status-table.component.ts @@ -58,6 +58,7 @@ export class AgentsStatusTableComponent extends BaseTableComponent implements On } ngOnDestroy(): void { + this.dataSource.stopAutoRefresh(); for (const sub of this.subscriptions) { sub.unsubscribe(); } diff --git a/src/app/core/_components/tables/tasks-table/tasks-table.component.ts b/src/app/core/_components/tables/tasks-table/tasks-table.component.ts index 7fbf05d1..99beee87 100644 --- a/src/app/core/_components/tables/tasks-table/tasks-table.component.ts +++ b/src/app/core/_components/tables/tasks-table/tasks-table.component.ts @@ -77,6 +77,7 @@ export class TasksTableComponent extends BaseTableComponent implements OnInit, O } ngOnDestroy(): void { + this.dataSource.stopAutoRefresh(); for (const sub of this.subscriptions) { sub.unsubscribe(); } diff --git a/src/app/core/_datasources/base.datasource.ts b/src/app/core/_datasources/base.datasource.ts index 5d3c99fe..ce3187ca 100644 --- a/src/app/core/_datasources/base.datasource.ts +++ b/src/app/core/_datasources/base.datasource.ts @@ -368,6 +368,17 @@ export abstract class BaseDataSource i }); } + /** + * Stop auto-refresh and unsubscribe from refresh events + */ + stopAutoRefresh(): void { + if (this.autoRefreshSubscription) { + this.autoRefreshSubscription.unsubscribe(); + } + this.autoRefreshEnabled = false; // Keep the flag in sync + this.autoRefreshService.stopAutoRefresh(); + } + /** * Start auto-refresh without changing the current settings * (used when component is initialized and auto-refresh is already enabled) diff --git a/src/app/shared/widgets/last-updated/last-updated.component.spec.ts b/src/app/shared/widgets/last-updated/last-updated.component.spec.ts index 61eec244..d62a2090 100644 --- a/src/app/shared/widgets/last-updated/last-updated.component.spec.ts +++ b/src/app/shared/widgets/last-updated/last-updated.component.spec.ts @@ -1,6 +1,8 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ChangeDetectorRef } from '@angular/core'; +import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing'; -import { LastUpdatedComponent } from './last-updated.component'; +import { UISettingsUtilityClass } from '@src/app/shared/utils/config'; +import { LastUpdatedComponent } from '@src/app/shared/widgets/last-updated/last-updated.component'; describe('LastUpdatedComponent', () => { let component: LastUpdatedComponent; @@ -8,16 +10,82 @@ describe('LastUpdatedComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [LastUpdatedComponent] - }) - .compileComponents(); + imports: [LastUpdatedComponent], + providers: [ + { + provide: UISettingsUtilityClass, + useValue: { + getSetting: jasmine.createSpy('getSetting').and.returnValue('dd/MM/yyyy h:mm:ss') + } + }, + ChangeDetectorRef + ] + }).compileComponents(); fixture = TestBed.createComponent(LastUpdatedComponent); component = fixture.componentInstance; + fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); + + it('should format lastUpdatedDisplay using UI settings', () => { + component.lastUpdated = new Date(2025, 8, 26, 10, 30, 0); + fixture.detectChanges(); + expect(component.lastUpdatedDisplay).toContain('26/09/2025 10:30:00'); + }); + + it('should display countdown if nextRefreshTimestamp is in the future and not refreshing', fakeAsync(() => { + component.nextRefreshTimestamp = Date.now() + 5000; // 5s in the future + component.refreshing = false; + component.ngOnChanges({ + nextRefreshTimestamp: { + currentValue: component.nextRefreshTimestamp, + previousValue: null, + firstChange: true, + isFirstChange: () => true + } + }); + + tick(1000); // allow interval to run + fixture.detectChanges(); + + expect(component.nextUpdateDisplay).not.toBeNull(); + expect(component.nextUpdateDisplay).toMatch(/\d{2}:\d{2}/); // mm:ss format + })); + + it('should stop countdown if nextRefreshTimestamp is in the past', fakeAsync(() => { + component.nextRefreshTimestamp = Date.now() - 1000; // past + component.refreshing = false; + component.ngOnChanges({ + nextRefreshTimestamp: { + currentValue: component.nextRefreshTimestamp, + previousValue: null, + firstChange: true, + isFirstChange: () => true + } + }); + tick(300); + + expect(component.nextUpdateDisplay).toBe('00:00'); + })); + + it('should hide countdown if refreshing is true', fakeAsync(() => { + component.nextRefreshTimestamp = Date.now() + 5000; // future + component.refreshing = true; + component.ngOnChanges({ + nextRefreshTimestamp: { + currentValue: component.nextRefreshTimestamp, + previousValue: null, + firstChange: true, + isFirstChange: () => true + } + }); + tick(300); + + expect(component.nextUpdateDisplay).toBeNull(); + })); });