diff --git a/src/portal/src/app/base/left-side-nav/job-service-dashboard/job-service-dashboard-shared-data.service.spec.ts b/src/portal/src/app/base/left-side-nav/job-service-dashboard/job-service-dashboard-shared-data.service.spec.ts new file mode 100644 index 000000000..f31b1f33c --- /dev/null +++ b/src/portal/src/app/base/left-side-nav/job-service-dashboard/job-service-dashboard-shared-data.service.spec.ts @@ -0,0 +1,24 @@ +import { TestBed } from '@angular/core/testing'; +import { JobServiceDashboardSharedDataService } from './job-service-dashboard-shared-data.service'; +import { SharedTestingModule } from '../../../shared/shared.module'; + +describe('JobServiceDashboardSharedDataService', () => { + let service: JobServiceDashboardSharedDataService; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [SharedTestingModule], + providers: [JobServiceDashboardSharedDataService], + }); + service = TestBed.inject(JobServiceDashboardSharedDataService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); + + it('should have initial value', () => { + expect(service.getAllWorkers().length).toEqual(0); + expect(service.getJobQueues().length).toEqual(0); + }); +}); diff --git a/src/portal/src/app/base/left-side-nav/job-service-dashboard/job-service-dashboard-shared-data.service.ts b/src/portal/src/app/base/left-side-nav/job-service-dashboard/job-service-dashboard-shared-data.service.ts new file mode 100644 index 000000000..da8ade60b --- /dev/null +++ b/src/portal/src/app/base/left-side-nav/job-service-dashboard/job-service-dashboard-shared-data.service.ts @@ -0,0 +1,136 @@ +import { Injectable } from '@angular/core'; +import { JobQueue } from '../../../../../ng-swagger-gen/models/job-queue'; +import { JobserviceService } from '../../../../../ng-swagger-gen/services/jobservice.service'; +import { map, Observable } from 'rxjs'; +import { All, ScheduleListResponse } from './job-service-dashboard.interface'; +import { Worker } from 'ng-swagger-gen/models'; +import { ScheduleService } from '../../../../../ng-swagger-gen/services/schedule.service'; +import { ClrDatagridStateInterface } from '@clr/angular/data/datagrid/interfaces/state.interface'; +import { doSorting } from '../../../shared/units/utils'; + +@Injectable() +export class JobServiceDashboardSharedDataService { + private _jobQueues: JobQueue[] = []; + private _allWorkers: Worker[] = []; + private _scheduleListResponse: ScheduleListResponse; + + private _scheduleListParam: ScheduleService.ListSchedulesParams = { + page: 1, + pageSize: 1, + }; + + private _state: ClrDatagridStateInterface; + constructor( + private jobServiceService: JobserviceService, + private scheduleService: ScheduleService + ) {} + getJobQueues(): JobQueue[] { + return this._jobQueues; + } + getAllWorkers(): Worker[] { + return this._allWorkers; + } + getScheduleListResponse(): ScheduleListResponse { + return this._scheduleListResponse; + } + + retrieveJobQueues(isAutoRefresh?: boolean): Observable { + return this.jobServiceService.listJobQueues().pipe( + map(res => { + // For auto-refresh + // if execute this._jobQueues = res, the selected rows of the datagrid will be reset + // so only refresh properties here + if (isAutoRefresh && this._jobQueues?.length && res?.length) { + this._jobQueues.forEach(item => { + res.forEach(item2 => { + if (item2.job_type === item.job_type) { + item.count = item2.count; + item.latency = item2.latency; + item.paused = item2.paused; + } + }); + }); + } else { + this._jobQueues = res; + } + // map null and undefined to 0 + this._jobQueues.forEach(item => { + if (!item.count) { + item.count = 0; + } + }); + return this._jobQueues; + }) + ); + } + retrieveScheduleListResponse( + params?: ScheduleService.ListSchedulesParams, + state?: ClrDatagridStateInterface + ): Observable { + if (params) { + this._scheduleListParam = params; + } + if (state) { + this._state = state; + } + return this.scheduleService + .listSchedulesResponse(this._scheduleListParam) + .pipe( + map(res => { + const result: ScheduleListResponse = { + pageSize: this._scheduleListParam?.pageSize | 1, + currentPage: this._scheduleListParam?.page | 1, + scheduleList: res.body, + total: Number.parseInt( + res.headers.get('x-total-count'), + 10 + ), + }; + this._scheduleListResponse = result; + if ( + this._state && + this._scheduleListResponse?.scheduleList?.length + ) { + this._scheduleListResponse.scheduleList = doSorting( + this._scheduleListResponse?.scheduleList, + this._state + ); + } + return this._scheduleListResponse; + }) + ); + } + retrieveAllWorkers(isAutoRefresh?: boolean): Observable { + return this.jobServiceService + .getWorkers({ + poolId: All.ALL_WORKERS.toString(), + }) + .pipe( + map(res => { + // For auto-refresh + // if execute this._allWorkers = res, the selected rows of the datagrid will be reset + // so only refresh properties here + if ( + isAutoRefresh && + this._allWorkers?.length && + res?.length + ) { + this._allWorkers.forEach(item => { + res.forEach(item2 => { + if (item2.id === item.id) { + item.job_id = item2.job_id; + item.job_name = item2.job_name; + item.check_in = item2.check_in; + item.checkin_at = item2.checkin_at; + item.start_at = item2.start_at; + } + }); + }); + } else { + this._allWorkers = res; + } + return this._allWorkers; + }) + ); + } +} diff --git a/src/portal/src/app/base/left-side-nav/job-service-dashboard/job-service-dashboard.interface.ts b/src/portal/src/app/base/left-side-nav/job-service-dashboard/job-service-dashboard.interface.ts index 9b0abf16a..55a8a3ead 100644 --- a/src/portal/src/app/base/left-side-nav/job-service-dashboard/job-service-dashboard.interface.ts +++ b/src/portal/src/app/base/left-side-nav/job-service-dashboard/job-service-dashboard.interface.ts @@ -1,3 +1,5 @@ +import { ScheduleTask } from '../../../../../ng-swagger-gen/models/schedule-task'; + export enum All { ALL_WORKERS = 'all', } @@ -32,3 +34,10 @@ export const CronTypeI18nMap = { Hourly: 'SCHEDULE.HOURLY', Custom: 'SCHEDULE.CUSTOM', }; + +export interface ScheduleListResponse { + pageSize: number; + currentPage: number; + total: number; + scheduleList: ScheduleTask[]; +} diff --git a/src/portal/src/app/base/left-side-nav/job-service-dashboard/job-service-dashboard.module.ts b/src/portal/src/app/base/left-side-nav/job-service-dashboard/job-service-dashboard.module.ts index 55be68337..8bd8ccd64 100644 --- a/src/portal/src/app/base/left-side-nav/job-service-dashboard/job-service-dashboard.module.ts +++ b/src/portal/src/app/base/left-side-nav/job-service-dashboard/job-service-dashboard.module.ts @@ -9,6 +9,7 @@ import { ScheduleListComponent } from './schedule-list/schedule-list.component'; import { DonutChartComponent } from './worker-card/donut-chart/donut-chart.component'; import { WorkerCardComponent } from './worker-card/worker-card.component'; import { WorkerListComponent } from './worker-list/worker-list.component'; +import { JobServiceDashboardSharedDataService } from './job-service-dashboard-shared-data.service'; const routes: Routes = [ { @@ -47,5 +48,6 @@ const routes: Routes = [ ScheduleListComponent, WorkerListComponent, ], + providers: [JobServiceDashboardSharedDataService], }) export class JobServiceDashboardModule {} diff --git a/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-card/pending-job-card.component.html b/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-card/pending-job-card.component.html index af01e01e0..8e7e4a5a1 100644 --- a/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-card/pending-job-card.component.html +++ b/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-card/pending-job-card.component.html @@ -1,35 +1,35 @@
-
+
{{ 'JOB_SERVICE_DASHBOARD.PENDING_JOBS' | translate }}
-
+
{{ 'REPLICATION.TOTAL' | translate }}: {{ total() }}
-
-
-
-
-
-
diff --git a/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-card/pending-job-card.component.scss b/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-card/pending-job-card.component.scss index db0c4ea05..8a8a8e6ed 100644 --- a/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-card/pending-job-card.component.scss +++ b/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-card/pending-job-card.component.scss @@ -2,7 +2,9 @@ width: 100%; text-align: center; font-size: 50px; - margin: 1.5rem 0 1rem; + margin: 1rem 0; + line-height: 2rem; + height: 2rem; } .card-block { diff --git a/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-card/pending-job-card.component.spec.ts b/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-card/pending-job-card.component.spec.ts index 3b39ad913..3dc3835f0 100644 --- a/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-card/pending-job-card.component.spec.ts +++ b/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-card/pending-job-card.component.spec.ts @@ -4,6 +4,7 @@ import { SharedTestingModule } from '../../../../shared/shared.module'; import { JobQueue } from '../../../../../../ng-swagger-gen/models/job-queue'; import { of } from 'rxjs'; import { delay } from 'rxjs/operators'; +import { JobServiceDashboardSharedDataService } from '../job-service-dashboard-shared-data.service'; describe('PendingCardComponent', () => { let component: PendingCardComponent; @@ -24,8 +25,12 @@ describe('PendingCardComponent', () => { }, ]; - const fakedJobserviceService = { - listJobQueues() { + const fakedJobServiceDashboardSharedDataService = { + _jobQueues: [], + getJobQueues(): JobQueue[] { + return this._jobQueues; + }, + retrieveJobQueues() { return of(mockedJobs).pipe(delay(0)); }, }; @@ -34,19 +39,28 @@ describe('PendingCardComponent', () => { await TestBed.configureTestingModule({ declarations: [PendingCardComponent], imports: [SharedTestingModule], + providers: [ + { + provide: JobServiceDashboardSharedDataService, + useValue: fakedJobServiceDashboardSharedDataService, + }, + ], }).compileComponents(); fixture = TestBed.createComponent(PendingCardComponent); component = fixture.componentInstance; spyOn(component, 'loopGetPendingJobs').and.callFake(() => { - fakedJobserviceService.listJobQueues().subscribe(res => { - component.loading = false; - component.jobQueue = res.sort((a, b) => { - const ACount: number = a?.count | 0; - const BCount: number = b?.count | 0; - return BCount - ACount; + fakedJobServiceDashboardSharedDataService + .retrieveJobQueues() + .subscribe(res => { + component.loading = false; + fakedJobServiceDashboardSharedDataService._jobQueues = + res.sort((a, b) => { + const ACount: number = a?.count | 0; + const BCount: number = b?.count | 0; + return BCount - ACount; + }); }); - }); }); fixture.autoDetectChanges(); }); diff --git a/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-card/pending-job-card.component.ts b/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-card/pending-job-card.component.ts index 88c0a2c96..3a3bccbf5 100644 --- a/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-card/pending-job-card.component.ts +++ b/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-card/pending-job-card.component.ts @@ -2,7 +2,6 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { ConfirmationDialogService } from '../../../global-confirmation-dialog/confirmation-dialog.service'; import { JobserviceService } from '../../../../../../ng-swagger-gen/services/jobservice.service'; import { MessageHandlerService } from '../../../../shared/services/message-handler.service'; -import { JobQueue } from '../../../../../../ng-swagger-gen/models/job-queue'; import { finalize } from 'rxjs/operators'; import { INTERVAL, @@ -14,11 +13,7 @@ import { ConfirmationState, ConfirmationTargets, } from '../../../../shared/entities/shared.const'; -import { of, Subscription } from 'rxjs'; -import { - EventService, - HarborEvent, -} from '../../../../services/event-service/event.service'; +import { Subscription } from 'rxjs'; import { operateChanges, OperateInfo, @@ -26,6 +21,7 @@ import { } from '../../../../shared/components/operation/operate'; import { errorHandler } from '../../../../shared/units/shared.utils'; import { OperationService } from '../../../../shared/components/operation/operation.service'; +import { JobServiceDashboardSharedDataService } from '../job-service-dashboard-shared-data.service'; @Component({ selector: 'app-pending-job-card', @@ -34,7 +30,6 @@ import { OperationService } from '../../../../shared/components/operation/operat }) export class PendingCardComponent implements OnInit, OnDestroy { loading: boolean = false; - jobQueue: JobQueue[] = []; timeout: any; loadingStopAll: boolean = false; confirmSub: Subscription; @@ -42,8 +37,8 @@ export class PendingCardComponent implements OnInit, OnDestroy { private operateDialogService: ConfirmationDialogService, private jobServiceService: JobserviceService, private messageHandlerService: MessageHandlerService, - private eventService: EventService, - private operationService: OperationService + private operationService: OperationService, + private jobServiceDashboardSharedDataService: JobServiceDashboardSharedDataService ) {} ngOnInit() { @@ -60,7 +55,15 @@ export class PendingCardComponent implements OnInit, OnDestroy { this.confirmSub = null; } } - + get jobQueue() { + return this.jobServiceDashboardSharedDataService + .getJobQueues() + .sort((a, b) => { + const ACount: number = a?.count | 0; + const BCount: number = b?.count | 0; + return BCount - ACount; + }); + } initSub() { if (!this.confirmSub) { this.confirmSub = @@ -86,17 +89,10 @@ export class PendingCardComponent implements OnInit, OnDestroy { if (withLoading) { this.loading = true; } - this.jobServiceService - .listJobQueues() + this.jobServiceDashboardSharedDataService + .retrieveJobQueues(true) .pipe(finalize(() => (this.loading = false))) .subscribe(res => { - if (res?.length) { - this.jobQueue = res.sort((a, b) => { - const ACount: number = a?.count | 0; - const BCount: number = b?.count | 0; - return BCount - ACount; - }); - } this.timeout = setTimeout(() => { this.loopGetPendingJobs(); }, INTERVAL); @@ -159,9 +155,6 @@ export class PendingCardComponent implements OnInit, OnDestroy { 'JOB_SERVICE_DASHBOARD.STOP_ALL_SUCCESS' ); this.refreshNow(); - this.eventService.publish( - HarborEvent.REFRESH_JOB_SERVICE_DASHBOARD - ); operateChanges(operationMessage, OperationState.success); }, error: err => { diff --git a/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-list/pending-job-list.component.html b/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-list/pending-job-list.component.html index 6102bb1ec..f363110d6 100644 --- a/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-list/pending-job-list.component.html +++ b/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-list/pending-job-list.component.html @@ -65,10 +65,10 @@ {{ 'JOB_SERVICE_DASHBOARD.JOB_TYPE' | translate }} - {{ + {{ 'JOB_SERVICE_DASHBOARD.PENDING_COUNT' | translate }} - {{ + {{ 'JOB_SERVICE_DASHBOARD.LATENCY' | translate }} {{ diff --git a/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-list/pending-job-list.component.spec.ts b/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-list/pending-job-list.component.spec.ts index 287584c80..2bde2808c 100644 --- a/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-list/pending-job-list.component.spec.ts +++ b/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-list/pending-job-list.component.spec.ts @@ -2,9 +2,9 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { PendingListComponent } from './pending-job-list.component'; import { JobQueue } from '../../../../../../ng-swagger-gen/models/job-queue'; import { of } from 'rxjs'; -import { delay, finalize } from 'rxjs/operators'; +import { delay } from 'rxjs/operators'; import { SharedTestingModule } from '../../../../shared/shared.module'; -import { JobserviceService } from '../../../../../../ng-swagger-gen/services/jobservice.service'; +import { JobServiceDashboardSharedDataService } from '../job-service-dashboard-shared-data.service'; describe('PendingListComponent', () => { let component: PendingListComponent; @@ -25,8 +25,12 @@ describe('PendingListComponent', () => { }, ]; - const fakedJobserviceService = { - listJobQueues() { + const fakedJobServiceDashboardSharedDataService = { + _jobQueues: mockedJobs, + getJobQueues(): JobQueue[] { + return this._jobQueues; + }, + retrieveJobQueues() { return of(mockedJobs).pipe(delay(0)); }, }; @@ -37,8 +41,8 @@ describe('PendingListComponent', () => { imports: [SharedTestingModule], providers: [ { - provide: JobserviceService, - useValue: fakedJobserviceService, + provide: JobServiceDashboardSharedDataService, + useValue: fakedJobServiceDashboardSharedDataService, }, ], }).compileComponents(); diff --git a/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-list/pending-job-list.component.ts b/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-list/pending-job-list.component.ts index 4afaa6210..923aee8b3 100644 --- a/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-list/pending-job-list.component.ts +++ b/src/portal/src/app/base/left-side-nav/job-service-dashboard/pending-job-list/pending-job-list.component.ts @@ -14,10 +14,6 @@ import { NO, YES } from '../../clearing-job/clearing-job-interfact'; import { PendingJobsActions } from '../job-service-dashboard.interface'; import { forkJoin, Subscription } from 'rxjs'; import { ConfirmationDialogService } from '../../../global-confirmation-dialog/confirmation-dialog.service'; -import { - EventService, - HarborEvent, -} from '../../../../services/event-service/event.service'; import { ConfirmationButtons, ConfirmationState, @@ -30,6 +26,7 @@ import { } from '../../../../shared/components/operation/operate'; import { OperationService } from '../../../../shared/components/operation/operation.service'; import { errorHandler } from '../../../../shared/units/shared.utils'; +import { JobServiceDashboardSharedDataService } from '../job-service-dashboard-shared-data.service'; @Component({ selector: 'app-pending-job-list', @@ -42,23 +39,20 @@ export class PendingListComponent implements OnInit, OnDestroy { pageSize: number = getPageSizeFromLocalStorage( PageSizeMapKeys.PENDING_LIST_COMPONENT ); - jobQueue: JobQueue[] = []; loadingStop: boolean = false; loadingPause: boolean = false; loadingResume: boolean = false; confirmSub: Subscription; - eventSub: Subscription; constructor( private jobServiceService: JobserviceService, private messageHandlerService: MessageHandlerService, private operateDialogService: ConfirmationDialogService, - private eventService: EventService, - private operationService: OperationService + private operationService: OperationService, + private jobServiceDashboardSharedDataService: JobServiceDashboardSharedDataService ) {} ngOnInit() { this.getJobs(); - this.initEventSub(); this.initSub(); } ngOnDestroy() { @@ -66,10 +60,10 @@ export class PendingListComponent implements OnInit, OnDestroy { this.confirmSub.unsubscribe(); this.confirmSub = null; } - if (this.eventSub) { - this.eventSub.unsubscribe(); - this.eventSub = null; - } + } + + get jobQueue() { + return this.jobServiceDashboardSharedDataService.getJobQueues(); } initSub() { @@ -105,27 +99,14 @@ export class PendingListComponent implements OnInit, OnDestroy { } } - initEventSub() { - if (!this.eventSub) { - this.eventSub = this.eventService.subscribe( - HarborEvent.REFRESH_JOB_SERVICE_DASHBOARD, - () => { - this.getJobs(); - } - ); - } - } - getJobs() { this.selectedRows = []; this.loading = true; - this.jobServiceService - .listJobQueues() + this.jobServiceDashboardSharedDataService + .retrieveJobQueues() .pipe(finalize(() => (this.loading = false))) .subscribe({ - next: res => { - this.jobQueue = res; - }, + next: res => {}, error: err => { this.messageHandlerService.error(err); }, diff --git a/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-card/schedule-card.component.html b/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-card/schedule-card.component.html index 1dcfaa283..d688aeb44 100644 --- a/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-card/schedule-card.component.html +++ b/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-card/schedule-card.component.html @@ -1,14 +1,14 @@
-
+
{{ 'JOB_SERVICE_DASHBOARD.SCHEDULES' | translate }}
-
+
{{ 'REPLICATION.TOTAL' | translate }}: {{ scheduleCount }}
-
diff --git a/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-card/schedule-card.component.scss b/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-card/schedule-card.component.scss index f068c348b..578ff55bb 100644 --- a/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-card/schedule-card.component.scss +++ b/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-card/schedule-card.component.scss @@ -2,7 +2,9 @@ width: 100%; text-align: center; font-size: 50px; - margin: 1.5rem 0 1rem; + margin: 1rem 0; + line-height: 2rem; + height: 2rem; } .card-block { diff --git a/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-card/schedule-card.component.spec.ts b/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-card/schedule-card.component.spec.ts index 87938ae46..233a7190a 100644 --- a/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-card/schedule-card.component.spec.ts +++ b/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-card/schedule-card.component.spec.ts @@ -4,10 +4,14 @@ import { of } from 'rxjs'; import { delay } from 'rxjs/operators'; import { SharedTestingModule } from '../../../../shared/shared.module'; import { JobserviceService } from '../../../../../../ng-swagger-gen/services/jobservice.service'; -import { ScheduleStatusString } from '../job-service-dashboard.interface'; +import { + ScheduleListResponse, + ScheduleStatusString, +} from '../job-service-dashboard.interface'; import { HttpHeaders, HttpResponse } from '@angular/common/http'; import { ScheduleTask } from '../../../../../../ng-swagger-gen/models/schedule-task'; import { ScheduleService } from '../../../../../../ng-swagger-gen/services/schedule.service'; +import { JobServiceDashboardSharedDataService } from '../job-service-dashboard-shared-data.service'; describe('ScheduleCardComponent', () => { let component: ScheduleCardComponent; @@ -30,6 +34,16 @@ describe('ScheduleCardComponent', () => { }, }; + const fakedJobServiceDashboardSharedDataService = { + _scheduleListResponse: {}, + getScheduleListResponse(): ScheduleListResponse { + return this._scheduleListResponse; + }, + retrieveScheduleListResponse() { + return of({}); + }, + }; + beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [ScheduleCardComponent], @@ -43,6 +57,10 @@ describe('ScheduleCardComponent', () => { provide: ScheduleService, useValue: fakedScheduleService, }, + { + provide: JobServiceDashboardSharedDataService, + useValue: fakedJobServiceDashboardSharedDataService, + }, ], }).compileComponents(); diff --git a/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-card/schedule-card.component.ts b/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-card/schedule-card.component.ts index cb946f484..94395fa7f 100644 --- a/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-card/schedule-card.component.ts +++ b/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-card/schedule-card.component.ts @@ -16,10 +16,7 @@ import { ConfirmationTargets, } from '../../../../shared/entities/shared.const'; import { Subscription } from 'rxjs'; -import { - EventService, - HarborEvent, -} from '../../../../services/event-service/event.service'; +import { EventService } from '../../../../services/event-service/event.service'; import { OperationService } from '../../../../shared/components/operation/operation.service'; import { operateChanges, @@ -28,6 +25,7 @@ import { } from '../../../../shared/components/operation/operate'; import { errorHandler } from '../../../../shared/units/shared.utils'; import { ScheduleService } from '../../../../../../ng-swagger-gen/services/schedule.service'; +import { JobServiceDashboardSharedDataService } from '../job-service-dashboard-shared-data.service'; @Component({ selector: 'app-schedule-card', @@ -35,7 +33,6 @@ import { ScheduleService } from '../../../../../../ng-swagger-gen/services/sched styleUrls: ['./schedule-card.component.scss'], }) export class ScheduleCardComponent implements OnInit, OnDestroy { - scheduleCount: number = 0; isPaused: boolean = false; loadingStatus: boolean = false; confirmSub: Subscription; @@ -47,7 +44,8 @@ export class ScheduleCardComponent implements OnInit, OnDestroy { private messageHandlerService: MessageHandlerService, private eventService: EventService, private operationService: OperationService, - private scheduleService: ScheduleService + private scheduleService: ScheduleService, + private jobServiceDashboardSharedDataService: JobServiceDashboardSharedDataService ) {} ngOnInit() { @@ -67,6 +65,13 @@ export class ScheduleCardComponent implements OnInit, OnDestroy { } } + get scheduleCount(): number { + return ( + this.jobServiceDashboardSharedDataService.getScheduleListResponse() + ?.total | 0 + ); + } + initSub() { if (!this.confirmSub) { this.confirmSub = @@ -113,21 +118,10 @@ export class ScheduleCardComponent implements OnInit, OnDestroy { } getScheduleCount() { - this.scheduleService - .listSchedulesResponse({ - page: 1, - pageSize: 1, - }) + this.jobServiceDashboardSharedDataService + .retrieveScheduleListResponse() .subscribe({ - next: res => { - // Get total count - if (res.headers) { - let xHeader: string = res.headers.get('x-total-count'); - if (xHeader) { - this.scheduleCount = Number.parseInt(xHeader, 10); - } - } - }, + next: res => {}, error: err => { this.messageHandlerService.error(err); }, @@ -198,9 +192,9 @@ export class ScheduleCardComponent implements OnInit, OnDestroy { ); } this.refreshNow(); - this.eventService.publish( - HarborEvent.REFRESH_JOB_SERVICE_DASHBOARD - ); + this.jobServiceDashboardSharedDataService + .retrieveJobQueues() + .subscribe(); operateChanges(operationMessage, OperationState.success); }, error: err => { diff --git a/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-list/schedule-list.component.html b/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-list/schedule-list.component.html index 24c45f94f..10ed46e45 100644 --- a/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-list/schedule-list.component.html +++ b/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-list/schedule-list.component.html @@ -18,7 +18,7 @@ {{ 'JOB_SERVICE_DASHBOARD.CRON' | translate }} - {{ + {{ 'REPLICATION.UPDATE_TIME' | translate }} {{ diff --git a/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-list/schedule-list.component.spec.ts b/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-list/schedule-list.component.spec.ts index 375ffb6de..775a29406 100644 --- a/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-list/schedule-list.component.spec.ts +++ b/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-list/schedule-list.component.spec.ts @@ -2,10 +2,9 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ScheduleListComponent } from './schedule-list.component'; import { ScheduleTask } from '../../../../../../ng-swagger-gen/models/schedule-task'; import { of } from 'rxjs'; -import { delay } from 'rxjs/operators'; import { SharedTestingModule } from '../../../../shared/shared.module'; -import { HttpHeaders, HttpResponse } from '@angular/common/http'; -import { ScheduleService } from '../../../../../../ng-swagger-gen/services/schedule.service'; +import { JobServiceDashboardSharedDataService } from '../job-service-dashboard-shared-data.service'; +import { ScheduleListResponse } from '../job-service-dashboard.interface'; describe('ScheduleListComponent', () => { let component: ScheduleListComponent; @@ -16,15 +15,15 @@ describe('ScheduleListComponent', () => { { id: 2, vendor_type: 'test2' }, ]; - const fakedScheduleService = { - listSchedulesResponse() { - const res: HttpResponse> = new HttpResponse< - Array - >({ - headers: new HttpHeaders({ 'x-total-count': '2' }), - body: mockedSchedules, - }); - return of(res).pipe(delay(0)); + const fakedJobServiceDashboardSharedDataService = { + _scheduleListResponse: { + scheduleList: mockedSchedules, + }, + getScheduleListResponse(): ScheduleListResponse { + return this._scheduleListResponse; + }, + retrieveScheduleListResponse() { + return of({}); }, }; @@ -34,15 +33,15 @@ describe('ScheduleListComponent', () => { imports: [SharedTestingModule], providers: [ { - provide: ScheduleService, - useValue: fakedScheduleService, + provide: JobServiceDashboardSharedDataService, + useValue: fakedJobServiceDashboardSharedDataService, }, ], }).compileComponents(); fixture = TestBed.createComponent(ScheduleListComponent); component = fixture.componentInstance; - component.loadingSchedules = true; + component.loadingSchedules = false; fixture.detectChanges(); }); @@ -52,7 +51,6 @@ describe('ScheduleListComponent', () => { it('should render list', async () => { await fixture.whenStable(); - component.loadingSchedules = false; fixture.detectChanges(); await fixture.whenStable(); const rows = fixture.nativeElement.querySelectorAll('clr-dg-row'); diff --git a/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-list/schedule-list.component.ts b/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-list/schedule-list.component.ts index 53014ab46..e12a0f584 100644 --- a/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-list/schedule-list.component.ts +++ b/src/portal/src/app/base/left-side-nav/job-service-dashboard/schedule-list/schedule-list.component.ts @@ -1,4 +1,4 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Component } from '@angular/core'; import { ClrDatagridStateInterface } from '@clr/angular/data/datagrid/interfaces/state.interface'; import { doSorting, @@ -9,53 +9,30 @@ import { import { MessageHandlerService } from '../../../../shared/services/message-handler.service'; import { finalize } from 'rxjs/operators'; import { ScheduleTask } from '../../../../../../ng-swagger-gen/models/schedule-task'; -import { - EventService, - HarborEvent, -} from '../../../../services/event-service/event.service'; -import { Subscription } from 'rxjs'; -import { ScheduleService } from '../../../../../../ng-swagger-gen/services/schedule.service'; +import { JobServiceDashboardSharedDataService } from '../job-service-dashboard-shared-data.service'; @Component({ selector: 'app-schedule-list', templateUrl: './schedule-list.component.html', styleUrls: ['./schedule-list.component.scss'], }) -export class ScheduleListComponent implements OnInit, OnDestroy { - loadingSchedules: boolean = false; - schedules: ScheduleTask[] = []; +export class ScheduleListComponent { + loadingSchedules: boolean = true; total: number = 0; page: number = 1; pageSize: number = getPageSizeFromLocalStorage( PageSizeMapKeys.SCHEDULE_LIST_COMPONENT ); - eventSub: Subscription; constructor( private messageHandlerService: MessageHandlerService, - private eventService: EventService, - private scheduleService: ScheduleService + private jobServiceDashboardSharedDataService: JobServiceDashboardSharedDataService ) {} - ngOnInit() { - this.initEventSub(); - } - - ngOnDestroy() { - if (this.eventSub) { - this.eventSub.unsubscribe(); - this.eventSub = null; - } - } - - initEventSub() { - if (!this.eventSub) { - this.eventSub = this.eventService.subscribe( - HarborEvent.REFRESH_JOB_SERVICE_DASHBOARD, - () => { - this.clrLoad(); - } - ); - } + get schedules(): ScheduleTask[] { + return ( + this.jobServiceDashboardSharedDataService.getScheduleListResponse() + ?.scheduleList || [] + ); } clrLoad(state?: ClrDatagridStateInterface): void { @@ -67,22 +44,18 @@ export class ScheduleListComponent implements OnInit, OnDestroy { ); } this.loadingSchedules = true; - this.scheduleService - .listSchedulesResponse({ - page: this.page, - pageSize: this.pageSize, - }) + this.jobServiceDashboardSharedDataService + .retrieveScheduleListResponse( + { + page: this.page, + pageSize: this.pageSize, + }, + state + ) .pipe(finalize(() => (this.loadingSchedules = false))) .subscribe({ next: res => { - // Get total count - if (res.headers) { - let xHeader: string = res.headers.get('x-total-count'); - if (xHeader) { - this.total = Number.parseInt(xHeader, 10); - } - } - this.schedules = doSorting(res.body, state); + doSorting(res.scheduleList, state); }, error: err => { this.messageHandlerService.error(err); diff --git a/src/portal/src/app/base/left-side-nav/job-service-dashboard/worker-card/worker-card.component.html b/src/portal/src/app/base/left-side-nav/job-service-dashboard/worker-card/worker-card.component.html index 6eace60a4..c15ee4d5f 100644 --- a/src/portal/src/app/base/left-side-nav/job-service-dashboard/worker-card/worker-card.component.html +++ b/src/portal/src/app/base/left-side-nav/job-service-dashboard/worker-card/worker-card.component.html @@ -1,5 +1,5 @@
-
+
{{ 'JOB_SERVICE_DASHBOARD.WORKERS' | translate }}
diff --git a/src/portal/src/app/base/left-side-nav/job-service-dashboard/worker-card/worker-card.component.spec.ts b/src/portal/src/app/base/left-side-nav/job-service-dashboard/worker-card/worker-card.component.spec.ts index bce8492f0..c0c958fbf 100644 --- a/src/portal/src/app/base/left-side-nav/job-service-dashboard/worker-card/worker-card.component.spec.ts +++ b/src/portal/src/app/base/left-side-nav/job-service-dashboard/worker-card/worker-card.component.spec.ts @@ -1,10 +1,11 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { SharedTestingModule } from '../../../../shared/shared.module'; -import { JobserviceService } from '../../../../../../ng-swagger-gen/services/jobservice.service'; import { of } from 'rxjs'; import { WorkerCardComponent } from './worker-card.component'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { Worker } from '../../../../../../ng-swagger-gen/models/worker'; +import { ScheduleListResponse } from '../job-service-dashboard.interface'; +import { JobServiceDashboardSharedDataService } from '../job-service-dashboard-shared-data.service'; describe('WorkerCardComponent', () => { let component: WorkerCardComponent; @@ -15,8 +16,12 @@ describe('WorkerCardComponent', () => { { id: '2', job_id: '2', job_name: 'test2' }, ]; - const fakedJobserviceService = { - getWorkers() { + const fakedJobServiceDashboardSharedDataService = { + _allWorkers: mockedWorkers, + getAllWorkers(): ScheduleListResponse { + return this._allWorkers; + }, + retrieveAllWorkers() { return of(mockedWorkers); }, }; @@ -28,8 +33,8 @@ describe('WorkerCardComponent', () => { imports: [SharedTestingModule], providers: [ { - provide: JobserviceService, - useValue: fakedJobserviceService, + provide: JobServiceDashboardSharedDataService, + useValue: fakedJobServiceDashboardSharedDataService, }, ], }).compileComponents(); diff --git a/src/portal/src/app/base/left-side-nav/job-service-dashboard/worker-card/worker-card.component.ts b/src/portal/src/app/base/left-side-nav/job-service-dashboard/worker-card/worker-card.component.ts index 062955aa4..7bb143908 100644 --- a/src/portal/src/app/base/left-side-nav/job-service-dashboard/worker-card/worker-card.component.ts +++ b/src/portal/src/app/base/left-side-nav/job-service-dashboard/worker-card/worker-card.component.ts @@ -10,10 +10,6 @@ import { } from 'src/app/shared/entities/shared.const'; import { MessageHandlerService } from 'src/app/shared/services/message-handler.service'; import { All, INTERVAL } from '../job-service-dashboard.interface'; -import { - EventService, - HarborEvent, -} from '../../../../services/event-service/event.service'; import { OperationService } from '../../../../shared/components/operation/operation.service'; import { operateChanges, @@ -21,6 +17,7 @@ import { OperationState, } from '../../../../shared/components/operation/operate'; import { errorHandler } from '../../../../shared/units/shared.utils'; +import { JobServiceDashboardSharedDataService } from '../job-service-dashboard-shared-data.service'; @Component({ selector: 'app-worker-card', @@ -38,8 +35,8 @@ export class WorkerCardComponent implements OnInit, OnDestroy { private operateDialogService: ConfirmationDialogService, private jobServiceService: JobserviceService, private messageHandlerService: MessageHandlerService, - private eventService: EventService, - private operationService: OperationService + private operationService: OperationService, + private jobServiceDashboardSharedDataService: JobServiceDashboardSharedDataService ) {} ngOnInit(): void { @@ -78,9 +75,9 @@ export class WorkerCardComponent implements OnInit, OnDestroy { } } - loopWorkerStatus() { - this.jobServiceService - .getWorkers({ poolId: All.ALL_WORKERS.toString() }) + loopWorkerStatus(isAutoRefresh?: boolean) { + this.jobServiceDashboardSharedDataService + .retrieveAllWorkers(isAutoRefresh) .subscribe(res => { if (res) { this.denominator = res.length; @@ -91,7 +88,7 @@ export class WorkerCardComponent implements OnInit, OnDestroy { } }); this.statusTimeout = setTimeout(() => { - this.loopWorkerStatus(); + this.loopWorkerStatus(true); }, INTERVAL); } }); @@ -123,9 +120,6 @@ export class WorkerCardComponent implements OnInit, OnDestroy { 'JOB_SERVICE_DASHBOARD.FREE_ALL_SUCCESS' ); this.refreshNow(); - this.eventService.publish( - HarborEvent.REFRESH_JOB_SERVICE_DASHBOARD - ); operateChanges(operationMessage, OperationState.success); }, error: err => { diff --git a/src/portal/src/app/base/left-side-nav/job-service-dashboard/worker-list/worker-list.component.html b/src/portal/src/app/base/left-side-nav/job-service-dashboard/worker-list/worker-list.component.html index 48e5b57da..844f8603e 100644 --- a/src/portal/src/app/base/left-side-nav/job-service-dashboard/worker-list/worker-list.component.html +++ b/src/portal/src/app/base/left-side-nav/job-service-dashboard/worker-list/worker-list.component.html @@ -2,7 +2,7 @@ @@ -86,7 +86,7 @@
- + diff --git a/src/portal/src/app/base/left-side-nav/job-service-dashboard/worker-list/worker-list.component.spec.ts b/src/portal/src/app/base/left-side-nav/job-service-dashboard/worker-list/worker-list.component.spec.ts index 9f3612d5a..081300a91 100644 --- a/src/portal/src/app/base/left-side-nav/job-service-dashboard/worker-list/worker-list.component.spec.ts +++ b/src/portal/src/app/base/left-side-nav/job-service-dashboard/worker-list/worker-list.component.spec.ts @@ -5,14 +5,16 @@ import { delay } from 'rxjs/operators'; import { SharedTestingModule } from '../../../../shared/shared.module'; import { JobserviceService } from '../../../../../../ng-swagger-gen/services/jobservice.service'; import { Worker, WorkerPool } from 'ng-swagger-gen/models'; +import { ScheduleListResponse } from '../job-service-dashboard.interface'; +import { JobServiceDashboardSharedDataService } from '../job-service-dashboard-shared-data.service'; describe('WorkerListComponent', () => { let component: WorkerListComponent; let fixture: ComponentFixture; const mockedWorkers: Worker[] = [ - { id: '1', job_id: '1', job_name: 'test1' }, - { id: '2', job_id: '2', job_name: 'test2' }, + { id: '1', job_id: '1', job_name: 'test1', pool_id: '1' }, + { id: '2', job_id: '2', job_name: 'test2', pool_id: '1' }, ]; const mockedPools: WorkerPool[] = [ @@ -20,13 +22,19 @@ describe('WorkerListComponent', () => { ]; const fakedJobserviceService = { - getWorkers() { - return of(mockedWorkers).pipe(delay(0)); - }, getWorkerPools() { return of(mockedPools).pipe(delay(0)); }, }; + const fakedJobServiceDashboardSharedDataService = { + _allWorkers: mockedWorkers, + getAllWorkers(): ScheduleListResponse { + return this._allWorkers; + }, + retrieveAllWorkers() { + return of([]); + }, + }; beforeEach(async () => { await TestBed.configureTestingModule({ @@ -37,6 +45,10 @@ describe('WorkerListComponent', () => { provide: JobserviceService, useValue: fakedJobserviceService, }, + { + provide: JobServiceDashboardSharedDataService, + useValue: fakedJobServiceDashboardSharedDataService, + }, ], }).compileComponents(); fixture = TestBed.createComponent(WorkerListComponent); @@ -49,10 +61,10 @@ describe('WorkerListComponent', () => { }); it('should render worker list', async () => { - component.selectionChanged(); await fixture.whenStable(); component.loadingPools = false; component.loadingWorkers = false; + component.selectedPool = mockedPools[0]; fixture.detectChanges(); await fixture.whenStable(); const rows = fixture.nativeElement.querySelectorAll('clr-dg-row'); diff --git a/src/portal/src/app/base/left-side-nav/job-service-dashboard/worker-list/worker-list.component.ts b/src/portal/src/app/base/left-side-nav/job-service-dashboard/worker-list/worker-list.component.ts index ad5c8a1a3..120c7d6be 100644 --- a/src/portal/src/app/base/left-side-nav/job-service-dashboard/worker-list/worker-list.component.ts +++ b/src/portal/src/app/base/left-side-nav/job-service-dashboard/worker-list/worker-list.component.ts @@ -17,10 +17,6 @@ import { ConfirmationTargets, } from '../../../../shared/entities/shared.const'; import { ConfirmationDialogService } from '../../../global-confirmation-dialog/confirmation-dialog.service'; -import { - EventService, - HarborEvent, -} from '../../../../services/event-service/event.service'; import { OperationService } from '../../../../shared/components/operation/operation.service'; import { operateChanges, @@ -28,6 +24,7 @@ import { OperationState, } from '../../../../shared/components/operation/operate'; import { errorHandler } from '../../../../shared/units/shared.utils'; +import { JobServiceDashboardSharedDataService } from '../job-service-dashboard-shared-data.service'; @Component({ selector: 'app-worker-list', @@ -39,7 +36,6 @@ export class WorkerListComponent implements OnInit, OnDestroy { selectedPool: WorkerPool; pools: WorkerPool[] = []; loadingWorkers: boolean = false; - workers: Worker[] = []; selected: Worker[] = []; poolPageSize: number = getPageSizeFromLocalStorage( @@ -52,29 +48,29 @@ export class WorkerListComponent implements OnInit, OnDestroy { ); loadingFree: boolean = false; confirmSub: Subscription; - eventSub: Subscription; constructor( private jobServiceService: JobserviceService, private messageHandlerService: MessageHandlerService, private operateDialogService: ConfirmationDialogService, - private eventService: EventService, - private operationService: OperationService + private operationService: OperationService, + private jobServiceDashboardSharedDataService: JobServiceDashboardSharedDataService ) {} ngOnInit(): void { this.getPools(); this.initSub(); - this.initEventSub(); } ngOnDestroy() { if (this.confirmSub) { this.confirmSub.unsubscribe(); this.confirmSub = null; } - if (this.eventSub) { - this.eventSub.unsubscribe(); - this.eventSub = null; - } + } + + get workers(): Worker[] { + return this.jobServiceDashboardSharedDataService + .getAllWorkers() + .filter(item => item.pool_id === this.selectedPool?.worker_pool_id); } initSub() { @@ -98,17 +94,6 @@ export class WorkerListComponent implements OnInit, OnDestroy { } } - initEventSub() { - if (!this.eventSub) { - this.eventSub = this.eventService.subscribe( - HarborEvent.REFRESH_JOB_SERVICE_DASHBOARD, - () => { - this.selectionChanged(); - } - ); - } - } - getPools() { this.loadingPools = true; this.jobServiceService @@ -119,7 +104,6 @@ export class WorkerListComponent implements OnInit, OnDestroy { this.pools = res; if (res?.length) { this.selectedPool = res[0]; - this.selectionChanged(); } }, error: err => { @@ -128,21 +112,6 @@ export class WorkerListComponent implements OnInit, OnDestroy { }); } - selectionChanged() { - this.loadingWorkers = true; - this.jobServiceService - .getWorkers({ poolId: this.selectedPool?.worker_pool_id }) - .pipe(finalize(() => (this.loadingWorkers = false))) - .subscribe({ - next: res => { - this.workers = res; - }, - error: err => { - this.messageHandlerService.error(err); - }, - }); - } - string(v: any) { if (v) { return JSON.stringify(v); @@ -196,6 +165,14 @@ export class WorkerListComponent implements OnInit, OnDestroy { this.operateDialogService.openComfirmDialog(deletionMessage); } + refreshWorkers() { + this.loadingWorkers = true; + this.jobServiceDashboardSharedDataService + .retrieveAllWorkers() + .pipe(finalize(() => (this.loadingWorkers = false))) + .subscribe(); + } + executeFreeWorkers() { this.loadingFree = true; const operationMessage = new OperateInfo(); @@ -219,7 +196,7 @@ export class WorkerListComponent implements OnInit, OnDestroy { this.messageHandlerService.info( 'JOB_SERVICE_DASHBOARD.FREE_WORKER_SUCCESS' ); - this.selectionChanged(); + this.refreshWorkers(); operateChanges(operationMessage, OperationState.success); }, error: err => { diff --git a/src/portal/src/app/services/event-service/event.service.ts b/src/portal/src/app/services/event-service/event.service.ts index 5e9b0b0aa..dedca6de2 100644 --- a/src/portal/src/app/services/event-service/event.service.ts +++ b/src/portal/src/app/services/event-service/event.service.ts @@ -79,5 +79,4 @@ export enum HarborEvent { STOP_SCAN_ARTIFACT = 'stopScanArtifact', UPDATE_VULNERABILITY_INFO = 'UpdateVulnerabilityInfo', REFRESH_EXPORT_JOBS = 'refreshExportJobs', - REFRESH_JOB_SERVICE_DASHBOARD = 'refreshJobServiceDashboard', }