Enhancement: auto-refresh logs & tasks (#4680)

This commit is contained in:
shamoon
2023-11-30 19:08:03 -08:00
committed by GitHub
parent 402e5b7c80
commit 8b271cc208
7 changed files with 113 additions and 53 deletions

View File

@@ -1,14 +1,19 @@
<pngx-page-header title="Logs" i18n-title>
<div class="form-check form-switch" (click)="toggleAutoRefresh()">
<input class="form-check-input" type="checkbox" role="switch" id="autoRefreshSwitch" [attr.checked]="autoRefreshInterval">
<label class="form-check-label" for="autoRefreshSwitch" i18n>Auto refresh</label>
</div>
</pngx-page-header>
<ul ngbNav #nav="ngbNav" [(activeId)]="activeLog" (activeIdChange)="reloadLogs()" class="nav-tabs">
<li *ngFor="let logFile of logFiles" [ngbNavItem]="logFile">
<a ngbNavLink>{{logFile}}.log</a>
<a ngbNavLink>
{{logFile}}.log
</a>
</li>
<div *ngIf="isLoading && !logFiles.length" class="pb-2">
<div *ngIf="isLoading || !logFiles.length" class="ps-2 d-flex align-items-center">
<div class="spinner-border spinner-border-sm me-2" role="status"></div>
<ng-container i18n>Loading...</ng-container>
<ng-container *ngIf="!logFiles.length" i18n>Loading...</ng-container>
</div>
</ul>

View File

@@ -1,4 +1,9 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'
import {
ComponentFixture,
TestBed,
fakeAsync,
tick,
} from '@angular/core/testing'
import { LogService } from 'src/app/services/rest/log.service'
import { PageHeaderComponent } from '../../common/page-header/page-header.component'
import { LogsComponent } from './logs.component'
@@ -26,6 +31,7 @@ describe('LogsComponent', () => {
let fixture: ComponentFixture<LogsComponent>
let logService: LogService
let logSpy
let reloadSpy
beforeEach(async () => {
TestBed.configureTestingModule({
@@ -42,7 +48,9 @@ describe('LogsComponent', () => {
})
fixture = TestBed.createComponent(LogsComponent)
component = fixture.componentInstance
reloadSpy = jest.spyOn(component, 'reloadLogs')
window.HTMLElement.prototype.scroll = function () {} // mock scroll
jest.useFakeTimers()
fixture.detectChanges()
})
@@ -68,4 +76,14 @@ describe('LogsComponent', () => {
component.reloadLogs()
expect(component.logs).toHaveLength(0)
})
it('should auto refresh, allow toggle', () => {
jest.advanceTimersByTime(6000)
expect(reloadSpy).toHaveBeenCalledTimes(2)
component.toggleAutoRefresh()
expect(component.autoRefreshInterval).toBeNull()
jest.advanceTimersByTime(6000)
expect(reloadSpy).toHaveBeenCalledTimes(2)
})
})

View File

@@ -27,6 +27,8 @@ export class LogsComponent implements OnInit, AfterViewChecked, OnDestroy {
public isLoading: boolean = false
public autoRefreshInterval: any
@ViewChild('logContainer') logContainer: ElementRef
ngOnInit(): void {
@@ -41,6 +43,7 @@ export class LogsComponent implements OnInit, AfterViewChecked, OnDestroy {
this.activeLog = this.logFiles[0]
this.reloadLogs()
}
this.toggleAutoRefresh()
})
}
@@ -91,4 +94,15 @@ export class LogsComponent implements OnInit, AfterViewChecked, OnDestroy {
behavior: 'auto',
})
}
toggleAutoRefresh(): void {
if (this.autoRefreshInterval) {
clearInterval(this.autoRefreshInterval)
this.autoRefreshInterval = null
} else {
this.autoRefreshInterval = setInterval(() => {
this.reloadLogs()
}, 5000)
}
}
}

View File

@@ -1,5 +1,5 @@
<pngx-page-header title="File Tasks" i18n-title>
<div class="btn-toolbar col col-md-auto">
<div class="btn-toolbar col col-md-auto align-items-center">
<button class="btn btn-sm btn-outline-secondary me-2" (click)="clearSelection()" [hidden]="selectedTasks.size === 0">
<svg class="sidebaricon" fill="currentColor">
<use xlink:href="assets/bootstrap-icons.svg#x"/>
@@ -10,15 +10,10 @@
<use xlink:href="assets/bootstrap-icons.svg#check2-all"/>
</svg>&nbsp;<ng-container i18n>{{dismissButtonText}}</ng-container>
</button>
<button class="btn btn-sm btn-outline-primary" (click)="tasksService.reload()">
<svg *ngIf="!tasksService.loading" class="sidebaricon" fill="currentColor">
<use xlink:href="assets/bootstrap-icons.svg#arrow-clockwise"/>
</svg>
<ng-container *ngIf="tasksService.loading">
<div class="spinner-border spinner-border-sm fw-normal" role="status"></div>
<div class="visually-hidden" i18n>Loading...</div>
</ng-container>&nbsp;<ng-container i18n>Refresh</ng-container>
</button>
<div class="form-check form-switch mb-0" (click)="toggleAutoRefresh()">
<input class="form-check-input" type="checkbox" role="switch" id="autoRefreshSwitch" [attr.checked]="autoRefreshInterval">
<label class="form-check-label" for="autoRefreshSwitch" i18n>Auto refresh</label>
</div>
</div>
</pngx-page-header>

View File

@@ -112,6 +112,7 @@ describe('TasksComponent', () => {
let modalService: NgbModal
let router: Router
let httpTestingController: HttpTestingController
let reloadSpy
beforeEach(async () => {
TestBed.configureTestingModule({
@@ -141,11 +142,13 @@ describe('TasksComponent', () => {
}).compileComponents()
tasksService = TestBed.inject(TasksService)
reloadSpy = jest.spyOn(tasksService, 'reload')
httpTestingController = TestBed.inject(HttpTestingController)
modalService = TestBed.inject(NgbModal)
router = TestBed.inject(Router)
fixture = TestBed.createComponent(TasksComponent)
component = fixture.componentInstance
jest.useFakeTimers()
fixture.detectChanges()
httpTestingController
.expectOne(`${environment.apiBaseUrl}tasks/`)
@@ -164,7 +167,7 @@ describe('TasksComponent', () => {
`Failed${currentTasksLength}`
)
expect(
fixture.debugElement.queryAll(By.css('input[type="checkbox"]'))
fixture.debugElement.queryAll(By.css('table input[type="checkbox"]'))
).toHaveLength(currentTasksLength + 1)
currentTasksLength = tasks.filter(
@@ -245,7 +248,7 @@ describe('TasksComponent', () => {
it('should support toggle all tasks', () => {
const toggleCheck = fixture.debugElement.query(
By.css('input[type=checkbox]')
By.css('table input[type=checkbox]')
)
toggleCheck.nativeElement.dispatchEvent(new MouseEvent('click'))
fixture.detectChanges()
@@ -269,4 +272,15 @@ describe('TasksComponent', () => {
tasks[3].related_document,
])
})
it('should auto refresh, allow toggle', () => {
expect(reloadSpy).toHaveBeenCalledTimes(1)
jest.advanceTimersByTime(5000)
expect(reloadSpy).toHaveBeenCalledTimes(2)
component.toggleAutoRefresh()
expect(component.autoRefreshInterval).toBeNull()
jest.advanceTimersByTime(6000)
expect(reloadSpy).toHaveBeenCalledTimes(2)
})
})

View File

@@ -23,6 +23,8 @@ export class TasksComponent
public pageSize: number = 25
public page: number = 1
public autoRefreshInterval: any
get dismissButtonText(): string {
return this.selectedTasks.size > 0
? $localize`Dismiss selected`
@@ -39,6 +41,7 @@ export class TasksComponent
ngOnInit() {
this.tasksService.reload()
this.toggleAutoRefresh()
}
ngOnDestroy() {
@@ -135,4 +138,15 @@ export class TasksComponent
return $localize`failed`
}
}
toggleAutoRefresh(): void {
if (this.autoRefreshInterval) {
clearInterval(this.autoRefreshInterval)
this.autoRefreshInterval = null
} else {
this.autoRefreshInterval = setInterval(() => {
this.tasksService.reload()
}, 5000)
}
}
}