Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export class AgentsStatusTableComponent extends BaseTableComponent implements On
}

ngOnDestroy(): void {
this.dataSource.stopAutoRefresh();
for (const sub of this.subscriptions) {
sub.unsubscribe();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
11 changes: 11 additions & 0 deletions src/app/core/_datasources/base.datasource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,17 @@ export abstract class BaseDataSource<T, P extends MatPaginator = MatPaginator> 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)
Expand Down
78 changes: 73 additions & 5 deletions src/app/shared/widgets/last-updated/last-updated.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,91 @@
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;
let fixture: ComponentFixture<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();
}));
});