diff --git a/src/portal/src/app/base/left-side-nav/gc-page/gc.module.ts b/src/portal/src/app/base/left-side-nav/gc-page/gc.module.ts
index 447fbadf87..c84aafb79b 100644
--- a/src/portal/src/app/base/left-side-nav/gc-page/gc.module.ts
+++ b/src/portal/src/app/base/left-side-nav/gc-page/gc.module.ts
@@ -3,10 +3,7 @@ import { RouterModule, Routes } from "@angular/router";
import { GcPageComponent } from "./gc-page.component";
import { GcComponent } from "./gc/gc.component";
import { GcHistoryComponent } from "./gc/gc-history/gc-history.component";
-import { GcRepoService } from "./gc/gc.service";
import { SharedModule } from "../../../shared/shared.module";
-import { GcApiDefaultRepository, GcApiRepository } from "./gc/gc.api.repository";
-import { GcViewModelFactory } from "./gc/gc.viewmodel.factory";
const routes: Routes = [
{
@@ -24,10 +21,5 @@ const routes: Routes = [
GcComponent,
GcHistoryComponent
],
- providers: [
- GcRepoService,
- {provide: GcApiRepository, useClass: GcApiDefaultRepository },
- GcViewModelFactory
- ]
})
export class GcModule {}
diff --git a/src/portal/src/app/base/left-side-nav/gc-page/gc/gc-history/gc-history.component.html b/src/portal/src/app/base/left-side-nav/gc-page/gc/gc-history/gc-history.component.html
index 42a7c9ee93..da631bb4be 100644
--- a/src/portal/src/app/base/left-side-nav/gc-page/gc/gc-history/gc-history.component.html
+++ b/src/portal/src/app/base/left-side-nav/gc-page/gc/gc-history/gc-history.component.html
@@ -1,30 +1,35 @@
-
+
-
- {{'GC.JOB_ID' | translate}}
- {{'GC.TRIGGER_TYPE' | translate}}
- {{'TAG_RETENTION.DRY_RUN' | translate}}
- {{'STATUS' | translate}}
- {{'CREATION_TIME' | translate}}
- {{'UPDATE_TIME' | translate}}
- {{'LOGS' | translate}}
-
- {{job.id }}
- {{(job.type ? 'SCHEDULE.'+ job.type.toUpperCase() : '') | translate }}
- {{isDryRun(job?.parameters) | translate}}
- {{job.status.toUpperCase() | translate}}
- {{job.createTime | harborDatetime:'medium'}}
- {{job.updateTime | harborDatetime:'medium'}}
-
-
-
-
-
-
- {{"PAGINATION.PAGE_SIZE" | translate}}
- {{'GC.LATEST_JOBS' | translate :{param: jobs.length} }}
-
-
+
+ {{'GC.JOB_ID' | translate}}
+ {{'GC.TRIGGER_TYPE' | translate}}
+ {{'TAG_RETENTION.DRY_RUN' | translate}}
+ {{'STATUS' | translate}}
+ {{'CREATION_TIME' | translate}}
+ {{'UPDATE_TIME' | translate}}
+ {{'LOGS' | translate}}
+
+ {{job.id }}
+ {{(job.schedule?.type ? 'SCHEDULE.' + job.schedule?.type.toUpperCase() : '') | translate }}
+ {{isDryRun(job?.job_parameters) | translate}}
+ {{job.job_status.toUpperCase() | translate}}
+ {{job.creation_time | harborDatetime:'medium'}}
+ {{job.update_time | harborDatetime:'medium'}}
+
+
+
+
+
+
+
+
+ {{"PAGINATION.PAGE_SIZE" | translate}}
+ {{pagination.firstItem + 1}}
+ - {{pagination.lastItem + 1}} {{'DESTINATION.OF' | translate}}
+ {{total}} {{'DESTINATION.ITEMS' | translate}}
+
+
diff --git a/src/portal/src/app/base/left-side-nav/gc-page/gc/gc-history/gc-history.component.spec.ts b/src/portal/src/app/base/left-side-nav/gc-page/gc/gc-history/gc-history.component.spec.ts
index 565a2c225a..560e0c79bb 100644
--- a/src/portal/src/app/base/left-side-nav/gc-page/gc/gc-history/gc-history.component.spec.ts
+++ b/src/portal/src/app/base/left-side-nav/gc-page/gc/gc-history/gc-history.component.spec.ts
@@ -1,100 +1,99 @@
import {
- ComponentFixture,
- ComponentFixtureAutoDetect,
- TestBed,
- waitForAsync
+ ComponentFixture,
+ ComponentFixtureAutoDetect, fakeAsync,
+ TestBed, tick,
} from '@angular/core/testing';
-import { GcRepoService } from "../gc.service";
import { of } from 'rxjs';
-import { GcViewModelFactory } from "../gc.viewmodel.factory";
-import { TranslateModule, TranslateService } from '@ngx-translate/core';
-import { ErrorHandler } from '../../../../../shared/units/error-handler';
import { GcHistoryComponent } from './gc-history.component';
-import { GcJobData } from "../gcLog";
import { SharedTestingModule } from "../../../../../shared/shared.module";
+import { GCHistory } from "../../../../../../../ng-swagger-gen/models/gchistory";
+import { HttpHeaders, HttpResponse } from "@angular/common/http";
+import { Registry } from "../../../../../../../ng-swagger-gen/models/registry";
+import { GcService } from "../../../../../../../ng-swagger-gen/services/gc.service";
+import { CURRENT_BASE_HREF } from "../../../../../shared/units/utils";
+import { delay } from "rxjs/operators";
describe('GcHistoryComponent', () => {
- let component: GcHistoryComponent;
- let fixture: ComponentFixture;
- const mockJobs: GcJobData[] = [
- {
- id: 1,
- job_name: 'test',
- job_kind: 'manual',
- schedule: null,
- job_status: 'pending',
- job_parameters: '{"dry_run":true}',
- job_uuid: 'abc',
- creation_time: null,
- update_time: null,
- delete: false
- },
- {
- id: 2,
- job_name: 'test',
- job_kind: 'manual',
- schedule: null,
- job_status: 'finished',
- job_parameters: '{"dry_run":true}',
- job_uuid: 'bcd',
- creation_time: null,
- update_time: null,
- delete: false
- }
- ];
- let fakeGcRepoService = {
- count: 0,
- getJobs() {
- if (this.count === 0) {
- this.count += 1;
- return of([mockJobs[0]]);
- } else {
- this.count += 1;
- return of([mockJobs[1]]);
- }
- },
- getLogLink() {
- return null;
- }
- };
- const fakeGcViewModelFactory = new GcViewModelFactory();
- beforeEach(() => {
- TestBed.configureTestingModule({
- declarations: [GcHistoryComponent],
- imports: [
- SharedTestingModule,
- TranslateModule.forRoot()
- ],
- providers: [
- ErrorHandler,
- TranslateService,
- GcViewModelFactory,
- { provide: GcRepoService, useValue: fakeGcRepoService },
- { provide: GcViewModelFactory, useValue: fakeGcViewModelFactory },
- // open auto detect
- { provide: ComponentFixtureAutoDetect, useValue: true }
- ]
+ let component: GcHistoryComponent;
+ let fixture: ComponentFixture;
+ const mockJobs: GCHistory[] = [
+ {
+ id: 1,
+ job_name: 'test',
+ job_kind: 'manual',
+ schedule: null,
+ job_status: 'pending',
+ job_parameters: '{"dry_run":true}',
+ creation_time: null,
+ update_time: null,
+ },
+ {
+ id: 2,
+ job_name: 'test',
+ job_kind: 'manual',
+ schedule: null,
+ job_status: 'finished',
+ job_parameters: '{"dry_run":true}',
+ creation_time: null,
+ update_time: null,
+ }
+ ];
+ const fakedGcService = {
+ count: 0,
+ getGCHistoryResponse() {
+ if (this.count === 0) {
+ this.count += 1;
+ const response: HttpResponse> = new HttpResponse>({
+ headers: new HttpHeaders({'x-total-count': [mockJobs[0]].length.toString()}),
+ body: [mockJobs[0]]
});
+ return of(response).pipe(delay(0));
+ } else {
+ this.count += 1;
+ const response: HttpResponse> = new HttpResponse>({
+ headers: new HttpHeaders({'x-total-count': [mockJobs[1]].length.toString()}),
+ body: [mockJobs[1]]
+ });
+ return of(response).pipe(delay(0));
+ }
+ }
+ };
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ declarations: [GcHistoryComponent],
+ imports: [
+ SharedTestingModule,
+ ],
+ providers: [
+ {provide: GcService, useValue: fakedGcService},
+ // open auto detect
+ {provide: ComponentFixtureAutoDetect, useValue: true}
+ ]
});
+ });
- beforeEach(() => {
- fixture = TestBed.createComponent(GcHistoryComponent);
- component = fixture.componentInstance;
- fixture.detectChanges();
+ beforeEach(() => {
+ fixture = TestBed.createComponent(GcHistoryComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+ afterEach(() => {
+ if (component && component.timerDelay) {
+ component.timerDelay.unsubscribe();
+ component.timerDelay = null;
+ }
+ });
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+ it('should retry getting jobs', fakeAsync(() => {
+ tick(10000);
+ fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ expect(component.jobs[0].job_status).toEqual('finished');
});
- afterEach(() => {
- if (component && component.timerDelay) {
- component.timerDelay.unsubscribe();
- component.timerDelay = null;
- }
- });
- it('should create', () => {
- expect(component).toBeTruthy();
- });
- it('should retry getting jobs', waitForAsync(() => {
- fixture.detectChanges();
- fixture.whenStable().then(() => {
- expect(component.jobs[1].status).toEqual('finished');
- });
- }));
+ }));
+ it('should return right log link', () => {
+ expect(component.getLogLink('1')).toEqual(`${CURRENT_BASE_HREF}/system/gc/1/log`);
+ });
});
diff --git a/src/portal/src/app/base/left-side-nav/gc-page/gc/gc-history/gc-history.component.ts b/src/portal/src/app/base/left-side-nav/gc-page/gc/gc-history/gc-history.component.ts
index 1bc51754f5..5c5fb9d407 100644
--- a/src/portal/src/app/base/left-side-nav/gc-page/gc/gc-history/gc-history.component.ts
+++ b/src/portal/src/app/base/left-side-nav/gc-page/gc/gc-history/gc-history.component.ts
@@ -1,64 +1,103 @@
import { Component, OnInit, OnDestroy } from '@angular/core';
-import { GcRepoService } from "../gc.service";
-import { GcJobViewModel } from "../gcLog";
-import { GcViewModelFactory } from "../gc.viewmodel.factory";
import { ErrorHandler } from "../../../../../shared/units/error-handler";
import { Subscription, timer } from "rxjs";
import { REFRESH_TIME_DIFFERENCE } from '../../../../../shared/entities/shared.const';
+import { GcService } from "../../../../../../../ng-swagger-gen/services/gc.service";
+import { CURRENT_BASE_HREF, DEFAULT_PAGE_SIZE, getSortingString } from "../../../../../shared/units/utils";
+import { ClrDatagridStateInterface } from "@clr/angular";
+import { finalize } from "rxjs/operators";
+import { GCHistory } from "../../../../../../../ng-swagger-gen/models/gchistory";
+
const JOB_STATUS = {
PENDING: "pending",
RUNNING: "running"
};
const YES: string = 'TAG_RETENTION.YES';
const NO: string = 'TAG_RETENTION.NO';
+
@Component({
selector: 'gc-history',
templateUrl: './gc-history.component.html',
styleUrls: ['./gc-history.component.scss']
})
export class GcHistoryComponent implements OnInit, OnDestroy {
- jobs: Array = [];
- loading: boolean;
+ jobs: Array = [];
+ loading: boolean = true;
timerDelay: Subscription;
+ pageSize: number = DEFAULT_PAGE_SIZE;
+ page: number = 1;
+ total: number = 0;
+ state: ClrDatagridStateInterface;
constructor(
- private gcRepoService: GcRepoService,
- private gcViewModelFactory: GcViewModelFactory,
+ private gcService: GcService,
private errorHandler: ErrorHandler
- ) {}
+ ) {
+ }
ngOnInit() {
+ }
+
+ refresh() {
+ this.page = 1;
+ this.total = 0;
this.getJobs();
}
- getJobs() {
+ getJobs(state?: ClrDatagridStateInterface) {
+ if (state) {
+ this.state = state;
+ }
+ if (state && state.page) {
+ this.pageSize = state.page.size;
+ }
+ let q: string;
+ if (state && state.filters && state.filters.length) {
+ q = encodeURIComponent(`${state.filters[0].property}=~${state.filters[0].value}`);
+ }
+ let sort: string;
+ if (state && state.sort && state.sort.by) {
+ sort = getSortingString(state);
+ }
this.loading = true;
- this.gcRepoService.getJobs().subscribe(jobs => {
- this.jobs = this.gcViewModelFactory.createJobViewModel(jobs);
- this.loading = false;
- // to avoid some jobs not finished.
- if (!this.timerDelay) {
- this.timerDelay = timer(REFRESH_TIME_DIFFERENCE, REFRESH_TIME_DIFFERENCE).subscribe(() => {
- let count: number = 0;
- this.jobs.forEach(job => {
- if (
- job['status'] === JOB_STATUS.PENDING ||
- job['status'] === JOB_STATUS.RUNNING
- ) {
- count++;
+ this.gcService.getGCHistoryResponse({
+ page: this.page,
+ pageSize: this.pageSize,
+ q: q,
+ sort: sort
+ }).pipe(finalize(() => this.loading = false))
+ .subscribe(res => {
+ // Get total count
+ if (res.headers) {
+ const xHeader: string = res.headers.get("X-Total-Count");
+ if (xHeader) {
+ this.total = parseInt(xHeader, 0);
+ }
+ this.jobs = res.body;
+ }
+ // to avoid some jobs not finished.
+ if (!this.timerDelay) {
+ this.timerDelay = timer(REFRESH_TIME_DIFFERENCE, REFRESH_TIME_DIFFERENCE).subscribe(() => {
+ let count: number = 0;
+ this.jobs.forEach(job => {
+ if (
+ job.job_status === JOB_STATUS.PENDING ||
+ job.job_status === JOB_STATUS.RUNNING
+ ) {
+ count++;
+ }
+ });
+ if (count > 0) {
+ this.getJobs(this.state);
+ } else {
+ this.timerDelay.unsubscribe();
+ this.timerDelay = null;
}
});
- if (count > 0) {
- this.getJobs();
- } else {
- this.timerDelay.unsubscribe();
- this.timerDelay = null;
- }
- });
- }
- }, error => {
+ }
+ }, error => {
this.errorHandler.error(error);
this.loading = false;
- });
+ });
}
isDryRun(param: string): string {
@@ -78,7 +117,7 @@ export class GcHistoryComponent implements OnInit, OnDestroy {
}
getLogLink(id): string {
- return this.gcRepoService.getLogLink(id);
+ return `${CURRENT_BASE_HREF}/system/gc/${id}/log`;
}
}
diff --git a/src/portal/src/app/base/left-side-nav/gc-page/gc/gc.api.repository.ts b/src/portal/src/app/base/left-side-nav/gc-page/gc/gc.api.repository.ts
deleted file mode 100644
index f5c8699dfc..0000000000
--- a/src/portal/src/app/base/left-side-nav/gc-page/gc/gc.api.repository.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-import { Injectable } from '@angular/core';
-import { HttpClient } from '@angular/common/http';
-import { throwError as observableThrowError, Observable } from 'rxjs';
-import { catchError } from 'rxjs/operators';
-import { CURRENT_BASE_HREF } from "../../../../shared/units/utils";
-
-export abstract class GcApiRepository {
- abstract postSchedule(param): Observable;
-
- abstract putSchedule(param): Observable;
-
- abstract getSchedule(): Observable;
-
- abstract getLog(id): Observable;
-
- abstract getStatus(id): Observable;
-
- abstract getJobs(): Observable;
-
- abstract getLogLink(id): string;
-}
-
-@Injectable()
-export class GcApiDefaultRepository extends GcApiRepository {
- constructor(
- private http: HttpClient
- ) {
- super();
- }
-
- public postSchedule(param): Observable {
- return this.http.post(`${CURRENT_BASE_HREF}/system/gc/schedule`, param)
- .pipe(catchError(error => observableThrowError(error)));
- }
-
- public putSchedule(param): Observable {
- return this.http.put(`${CURRENT_BASE_HREF}/system/gc/schedule`, param)
- .pipe(catchError(error => observableThrowError(error)));
- }
-
- public getSchedule(): Observable {
- return this.http.get(`${CURRENT_BASE_HREF}/system/gc/schedule`)
- .pipe(catchError(error => observableThrowError(error)));
- }
-
- public getLog(id): Observable {
- return this.http.get(`${CURRENT_BASE_HREF}/system/gc/${id}/log`)
- .pipe(catchError(error => observableThrowError(error)));
- }
-
- public getStatus(id): Observable {
- return this.http.get(`${CURRENT_BASE_HREF}/system/gc/${id}`)
- .pipe(catchError(error => observableThrowError(error)));
- }
-
- public getJobs(): Observable {
- return this.http.get(`${CURRENT_BASE_HREF}/system/gc`)
- .pipe(catchError(error => observableThrowError(error)));
- }
-
- public getLogLink(id) {
- return `${CURRENT_BASE_HREF}/system/gc/${id}/log`;
- }
-
-}
diff --git a/src/portal/src/app/base/left-side-nav/gc-page/gc/gc.component.html b/src/portal/src/app/base/left-side-nav/gc-page/gc/gc.component.html
index cca32fb405..39a9c58b79 100644
--- a/src/portal/src/app/base/left-side-nav/gc-page/gc/gc.component.html
+++ b/src/portal/src/app/base/left-side-nav/gc-page/gc/gc.component.html
@@ -1,6 +1,6 @@
+ [originCron]='originCron' (inputvalue)="saveGcSchedule($event)">
-
-
diff --git a/src/portal/src/app/base/left-side-nav/gc-page/gc/gc.component.spec.ts b/src/portal/src/app/base/left-side-nav/gc-page/gc/gc.component.spec.ts
index 12e112bdaf..56d3451615 100644
--- a/src/portal/src/app/base/left-side-nav/gc-page/gc/gc.component.spec.ts
+++ b/src/portal/src/app/base/left-side-nav/gc-page/gc/gc.component.spec.ts
@@ -1,35 +1,18 @@
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
import { GcComponent } from './gc.component';
-import { GcApiRepository, GcApiDefaultRepository} from './gc.api.repository';
-import { GcRepoService } from './gc.service';
import { ErrorHandler } from '../../../../shared/units/error-handler';
-import { GcViewModelFactory } from './gc.viewmodel.factory';
import { CronScheduleComponent } from '../../../../shared/components/cron-schedule';
import { CronTooltipComponent } from "../../../../shared/components/cron-schedule";
import { of } from 'rxjs';
-import { GcJobData } from './gcLog';
-import { CURRENT_BASE_HREF } from "../../../../shared/units/utils";
import { SharedTestingModule } from "../../../../shared/shared.module";
+import { GcService } from "../../../../../../ng-swagger-gen/services/gc.service";
+import { ScheduleType } from "../../../../shared/entities/shared.const";
describe('GcComponent', () => {
let component: GcComponent;
let fixture: ComponentFixture;
- let gcRepoService: GcRepoService;
+ let gcRepoService: GcService;
let mockSchedule = [];
- let mockJobs: GcJobData[] = [
- {
- id: 22222,
- schedule: null,
- job_status: 'string',
- job_parameters: '{"dry_run":true}',
- creation_time: new Date().toDateString(),
- update_time: new Date().toDateString(),
- job_name: 'string',
- job_kind: 'string',
- job_uuid: 'string',
- delete: false
- }
- ];
const fakedErrorHandler = {
error(error) {
return error;
@@ -39,7 +22,6 @@ describe('GcComponent', () => {
}
};
let spySchedule: jasmine.Spy;
- let spyJobs: jasmine.Spy;
let spyGcNow: jasmine.Spy;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
@@ -48,10 +30,7 @@ describe('GcComponent', () => {
],
declarations: [ GcComponent, CronScheduleComponent, CronTooltipComponent],
providers: [
- { provide: GcApiRepository, useClass: GcApiDefaultRepository },
{ provide: ErrorHandler, useValue: fakedErrorHandler },
- GcRepoService,
- GcViewModelFactory
]
})
.compileComponents();
@@ -61,10 +40,9 @@ describe('GcComponent', () => {
fixture = TestBed.createComponent(GcComponent);
component = fixture.componentInstance;
- gcRepoService = fixture.debugElement.injector.get(GcRepoService);
- spySchedule = spyOn(gcRepoService, "getSchedule").and.returnValues(of(mockSchedule));
- spyJobs = spyOn(gcRepoService, "getJobs").and.returnValues(of(mockJobs));
- spyGcNow = spyOn(gcRepoService, "manualGc").and.returnValues(of(true));
+ gcRepoService = fixture.debugElement.injector.get(GcService);
+ spySchedule = spyOn(gcRepoService, "getGCSchedule").and.returnValues(of(mockSchedule));
+ spyGcNow = spyOn(gcRepoService, "createGCSchedule").and.returnValues(of(true));
fixture.detectChanges();
});
it('should create', () => {
@@ -72,12 +50,25 @@ describe('GcComponent', () => {
});
it('should get schedule and job', () => {
expect(spySchedule.calls.count()).toEqual(1);
- expect(spyJobs.calls.count()).toEqual(1);
});
it('should trigger gcNow', () => {
- const ele: HTMLButtonElement = fixture.nativeElement.querySelector('.gc-start-btn');
+ const ele: HTMLButtonElement = fixture.nativeElement.querySelector('#gc-now');
ele.click();
fixture.detectChanges();
expect(spyGcNow.calls.count()).toEqual(1);
});
+ it('should trigger dry run', () => {
+ const ele: HTMLButtonElement = fixture.nativeElement.querySelector('#gc-dry-run');
+ ele.click();
+ fixture.detectChanges();
+ expect(spyGcNow.calls.count()).toEqual(1);
+ });
+ it('getScheduleType function should work', () => {
+ expect(GcComponent.getScheduleType).toBeTruthy();
+ expect(GcComponent.getScheduleType(null)).toEqual(ScheduleType.NONE);
+ expect(GcComponent.getScheduleType('0 0 0 0 0 0')).toEqual(ScheduleType.CUSTOM);
+ expect(GcComponent.getScheduleType('0 0 * * * *')).toEqual(ScheduleType.HOURLY);
+ expect(GcComponent.getScheduleType('0 0 0 * * *')).toEqual(ScheduleType.DAILY);
+ expect(GcComponent.getScheduleType('0 0 0 * * 0')).toEqual(ScheduleType.WEEKLY);
+ });
});
diff --git a/src/portal/src/app/base/left-side-nav/gc-page/gc/gc.component.ts b/src/portal/src/app/base/left-side-nav/gc-page/gc/gc.component.ts
index 6d17e50338..f8aa046c73 100644
--- a/src/portal/src/app/base/left-side-nav/gc-page/gc/gc.component.ts
+++ b/src/portal/src/app/base/left-side-nav/gc-page/gc/gc.component.ts
@@ -1,32 +1,26 @@
import {
Component,
- Input,
Output,
EventEmitter,
ViewChild,
OnInit
} from "@angular/core";
-import { TranslateService } from "@ngx-translate/core";
-import { GcJobViewModel } from "./gcLog";
-import { GcViewModelFactory } from "./gc.viewmodel.factory";
-import { GcRepoService } from "./gc.service";
-import {
- SCHEDULE_TYPE_NONE,
- ONE_MINITUE,
- THREE_SECONDS, GCSchedule
-} from "./gc.const";
import { ErrorHandler } from "../../../../shared/units/error-handler";
-import { CronScheduleComponent } from "../../../../shared/components/cron-schedule/cron-schedule.component";
-import { OriginCron } from '../../../../shared/services/interface';
+import { CronScheduleComponent } from "../../../../shared/components/cron-schedule";
+import { OriginCron } from '../../../../shared/services';
import { finalize } from "rxjs/operators";
+import { GcService } from "../../../../../../ng-swagger-gen/services/gc.service";
+import { GCHistory } from "../../../../../../ng-swagger-gen/models/gchistory";
+import { ScheduleType } from "../../../../shared/entities/shared.const";
+
+const ONE_MINUTE = 60000;
+
@Component({
selector: "gc-config",
templateUrl: "./gc.component.html",
styleUrls: ["./gc.component.scss"]
})
export class GcComponent implements OnInit {
- jobs: Array = [];
- schedule: GCSchedule = {};
originCron: OriginCron;
disableGC: boolean = false;
getLabelCurrent = 'GC.CURRENT_SCHEDULE';
@@ -35,67 +29,66 @@ export class GcComponent implements OnInit {
CronScheduleComponent: CronScheduleComponent;
shouldDeleteUntagged: boolean;
dryRunOnGoing: boolean = false;
+
constructor(
- private gcRepoService: GcRepoService,
- private gcViewModelFactory: GcViewModelFactory,
+ private gcService: GcService,
private errorHandler: ErrorHandler,
- private translate: TranslateService
) {
- translate.setDefaultLang("en-us");
}
ngOnInit() {
this.getCurrentSchedule();
- this.getJobs();
}
getCurrentSchedule() {
this.loadingGcStatus.emit(true);
- this.gcRepoService.getSchedule()
- .pipe(finalize(() => {
- this.loadingGcStatus.emit(false);
- }))
- .subscribe(schedule => {
- this.initSchedule(schedule);
- }, error => {
- this.errorHandler.error(error);
- });
+ this.gcService.getGCSchedule()
+ .pipe(finalize(() => {
+ this.loadingGcStatus.emit(false);
+ }))
+ .subscribe(schedule => {
+ this.initSchedule(schedule);
+ }, error => {
+ this.errorHandler.error(error);
+ });
}
- public initSchedule(schedule: GCSchedule) {
- if (schedule && schedule.schedule !== null) {
- this.schedule = schedule;
- this.originCron = this.schedule.schedule;
+ private initSchedule(gcHistory: GCHistory) {
+ if (gcHistory && gcHistory.schedule) {
+ this.originCron = {
+ type: gcHistory.schedule.type,
+ cron: gcHistory.schedule.cron
+ };
} else {
this.originCron = {
- type: SCHEDULE_TYPE_NONE,
+ type: ScheduleType.NONE,
cron: ''
};
}
- if (schedule && schedule.job_parameters) {
- this.shouldDeleteUntagged = JSON.parse(schedule.job_parameters).delete_untagged;
+ if (gcHistory && gcHistory.job_parameters) {
+ this.shouldDeleteUntagged = JSON.parse(gcHistory.job_parameters).delete_untagged;
} else {
this.shouldDeleteUntagged = false;
}
}
- getJobs() {
- this.gcRepoService.getJobs().subscribe(jobs => {
- this.jobs = this.gcViewModelFactory.createJobViewModel(jobs);
- });
- }
-
gcNow(): void {
this.disableGC = true;
setTimeout(() => {
this.enableGc();
- }, ONE_MINITUE);
+ }, ONE_MINUTE);
- this.gcRepoService.manualGc(this.shouldDeleteUntagged, false).subscribe(
+ this.gcService.createGCSchedule({
+ parameters: {
+ delete_untagged: this.shouldDeleteUntagged,
+ dry_run: false
+ },
+ schedule: {
+ type: ScheduleType.MANUAL
+ }
+ }).subscribe(
response => {
- this.translate.get("GC.MSG_SUCCESS").subscribe((res: string) => {
- this.errorHandler.info(res);
- });
+ this.errorHandler.info("GC.MSG_SUCCESS");
},
error => {
this.errorHandler.error(error);
@@ -105,62 +98,66 @@ export class GcComponent implements OnInit {
dryRun() {
this.dryRunOnGoing = true;
- this.gcRepoService.manualGc(this.shouldDeleteUntagged, true)
+ this.gcService.createGCSchedule({
+ parameters: {
+ delete_untagged: this.shouldDeleteUntagged,
+ dry_run: true
+ },
+ schedule: {
+ type: ScheduleType.MANUAL
+ }
+ })
.pipe(finalize(() => this.dryRunOnGoing = false))
.subscribe(
- response => {
- this.translate.get("GC.DRY_RUN_SUCCESS").subscribe((res: string) => {
- this.errorHandler.info(res);
- });
- },
- error => {
- this.errorHandler.error(error);
- }
- );
+ response => {
+ this.errorHandler.info("GC.DRY_RUN_SUCCESS");
+ },
+ error => {
+ this.errorHandler.error(error);
+ }
+ );
}
private enableGc() {
this.disableGC = false;
}
- private resetSchedule(cron) {
- this.schedule = {
- schedule: {
- type: this.CronScheduleComponent.scheduleType,
- cron: cron
- }
- };
- if (!cron) {
- this.shouldDeleteUntagged = false;
- }
- this.getJobs();
- }
-
- scheduleGc(cron: string) {
- let schedule = this.schedule;
- if (schedule && schedule.schedule && schedule.schedule.type !== SCHEDULE_TYPE_NONE) {
- this.gcRepoService.putScheduleGc(this.shouldDeleteUntagged, this.CronScheduleComponent.scheduleType, cron).subscribe(
+ saveGcSchedule(cron: string) {
+ if (this.originCron && this.originCron.type !== ScheduleType.NONE) {// no schedule, then create
+ this.gcService.createGCSchedule({
+ parameters: {
+ delete_untagged: this.shouldDeleteUntagged,
+ dry_run: false
+ },
+ schedule: {
+ type: GcComponent.getScheduleType(cron),
+ cron: cron
+ }
+ }).subscribe(
response => {
- this.translate
- .get("GC.MSG_SCHEDULE_RESET")
- .subscribe((res) => {
- this.errorHandler.info(res);
- this.CronScheduleComponent.resetSchedule();
- });
- this.resetSchedule(cron);
+ this.errorHandler.info("GC.MSG_SCHEDULE_RESET");
+ this.CronScheduleComponent.resetSchedule();
+ this.getCurrentSchedule(); // refresh schedule
},
error => {
this.errorHandler.error(error);
}
);
} else {
- this.gcRepoService.postScheduleGc(this.shouldDeleteUntagged, this.CronScheduleComponent.scheduleType, cron).subscribe(
+ this.gcService.updateGCSchedule({
+ parameters: {
+ delete_untagged: this.shouldDeleteUntagged,
+ dry_run: false
+ },
+ schedule: {
+ type: GcComponent.getScheduleType(cron),
+ cron: cron
+ }
+ }).subscribe(
response => {
- this.translate.get("GC.MSG_SCHEDULE_SET").subscribe((res) => {
- this.errorHandler.info(res);
- this.CronScheduleComponent.resetSchedule();
- });
- this.resetSchedule(cron);
+ this.errorHandler.info("GC.MSG_SCHEDULE_RESET");
+ this.CronScheduleComponent.resetSchedule();
+ this.getCurrentSchedule(); // refresh schedule
},
error => {
this.errorHandler.error(error);
@@ -168,4 +165,20 @@ export class GcComponent implements OnInit {
);
}
}
+
+ static getScheduleType(cron: string): 'Hourly' | 'Daily' | 'Weekly' | 'Custom' | 'Manual' | 'None' {
+ if (cron) {
+ if (cron === '0 0 * * * *') {
+ return ScheduleType.HOURLY;
+ }
+ if (cron === '0 0 0 * * *') {
+ return ScheduleType.DAILY;
+ }
+ if (cron === '0 0 0 * * 0') {
+ return ScheduleType.WEEKLY;
+ }
+ return ScheduleType.CUSTOM;
+ }
+ return ScheduleType.NONE;
+ }
}
diff --git a/src/portal/src/app/base/left-side-nav/gc-page/gc/gc.const.ts b/src/portal/src/app/base/left-side-nav/gc-page/gc/gc.const.ts
deleted file mode 100644
index d16beb88e5..0000000000
--- a/src/portal/src/app/base/left-side-nav/gc-page/gc/gc.const.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { OriginCron } from "../../../../shared/services";
-
-
-export const SCHEDULE_TYPE_NONE = "None";
-
-export const ONE_MINITUE = 60000;
-export const THREE_SECONDS = 3000;
-
-export interface GCSchedule {
- schedule?: OriginCron;
- parameters?: {[key: string]: any};
- id?: number;
- job_name?: string;
- job_kind?: string;
- job_parameters?: string;
- job_status?: string;
- deleted?: boolean;
- creation_time?: Date;
- update_time?: Date;
-}
-
-
-
-
-
diff --git a/src/portal/src/app/base/left-side-nav/gc-page/gc/gc.service.ts b/src/portal/src/app/base/left-side-nav/gc-page/gc/gc.service.ts
deleted file mode 100644
index ee5ab69eac..0000000000
--- a/src/portal/src/app/base/left-side-nav/gc-page/gc/gc.service.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-import { Injectable } from '@angular/core';
-import { Observable, Subscription, Subject, of } from 'rxjs';
-import { catchError, map } from 'rxjs/operators';
-import { GcApiRepository } from './gc.api.repository';
-import { ErrorHandler } from '../../../../shared/units/error-handler';
-import { GcJobData } from './gcLog';
-
-
-@Injectable()
-export class GcRepoService {
-
- constructor(
- private gcApiRepository: GcApiRepository,
- ) {}
-
- public manualGc(shouldDeleteUntagged: boolean, isDryRun: boolean): Observable {
- const param = {
- "schedule": {
- "type": "Manual"
- },
- parameters: {
- delete_untagged: shouldDeleteUntagged,
- dry_run: isDryRun
- }
- };
- return this.gcApiRepository.postSchedule(param);
- }
-
- public getJobs(): Observable {
- return this.gcApiRepository.getJobs();
- }
-
- public getLog(id): Observable {
- return this.gcApiRepository.getLog(id);
- }
-
- public getSchedule(): Observable {
- return this.gcApiRepository.getSchedule();
- }
-
- public postScheduleGc(shouldDeleteUntagged: boolean, type, cron): Observable {
- let param = {
- "schedule": {
- "type": type,
- "cron": cron,
- },
- parameters: {
- delete_untagged: shouldDeleteUntagged
- }
- };
-
- return this.gcApiRepository.postSchedule(param);
- }
-
- public putScheduleGc(shouldDeleteUntagged, type, cron): Observable {
- let param = {
- "schedule": {
- "type": type,
- "cron": cron,
- },
- parameters: {
- delete_untagged: shouldDeleteUntagged
- }
- };
-
- return this.gcApiRepository.putSchedule(param);
- }
-
- public getLogLink(id): string {
- return this.gcApiRepository.getLogLink(id);
- }
-}
diff --git a/src/portal/src/app/base/left-side-nav/gc-page/gc/gc.viewmodel.factory.ts b/src/portal/src/app/base/left-side-nav/gc-page/gc/gc.viewmodel.factory.ts
deleted file mode 100644
index 0266a7bff2..0000000000
--- a/src/portal/src/app/base/left-side-nav/gc-page/gc/gc.viewmodel.factory.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import { Injectable } from '@angular/core';
-import { GcJobData, GcJobViewModel } from './gcLog';
-
-@Injectable()
-export class GcViewModelFactory {
- public createJobViewModel(jobs: GcJobData[]): GcJobViewModel[] {
- let gcViewModels: GcJobViewModel[] = [];
- for (let job of jobs) {
-
- let createTime = new Date(job.creation_time);
- let updateTime = new Date(job.update_time);
- gcViewModels.push({
- id: job.id,
- type: job.schedule ? job.schedule.type : null,
- status: job.job_status,
- parameters: job.job_parameters,
- createTime: createTime,
- updateTime: updateTime,
- details: null
- });
- }
- return gcViewModels;
- }
-}
diff --git a/src/portal/src/app/base/left-side-nav/gc-page/gc/gcLog.ts b/src/portal/src/app/base/left-side-nav/gc-page/gc/gcLog.ts
deleted file mode 100644
index 04f54311db..0000000000
--- a/src/portal/src/app/base/left-side-nav/gc-page/gc/gcLog.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-export class GcJobData {
- id: number;
- job_name: string;
- job_kind: string;
- schedule: Schedule;
- job_status: string;
- job_parameters: string;
- job_uuid: string;
- creation_time: string;
- update_time: string;
- delete: boolean;
-}
-
-export class Schedule {
- type: string;
- cron: string;
-}
-export class GcJobViewModel {
- id: number;
- type: string;
- status: string;
- parameters: string;
- createTime: Date;
- updateTime: Date;
- details: string;
-}
-
-
diff --git a/src/portal/src/app/shared/entities/shared.const.ts b/src/portal/src/app/shared/entities/shared.const.ts
index b2f7e153e1..f7e6ffdaee 100644
--- a/src/portal/src/app/shared/entities/shared.const.ts
+++ b/src/portal/src/app/shared/entities/shared.const.ts
@@ -242,3 +242,12 @@ export enum ResourceType {
}
export const CARD_VIEW_LOCALSTORAGE_KEY = 'card-view';
+
+export enum ScheduleType {
+ NONE = "None",
+ DAILY = "Daily",
+ WEEKLY = "Weekly",
+ HOURLY = "Hourly",
+ CUSTOM = "Custom",
+ MANUAL = 'Manual'
+}
diff --git a/src/portal/src/app/shared/units/error-handler/error-handler.ts b/src/portal/src/app/shared/units/error-handler/error-handler.ts
index 51b63470b4..86543c87be 100644
--- a/src/portal/src/app/shared/units/error-handler/error-handler.ts
+++ b/src/portal/src/app/shared/units/error-handler/error-handler.ts
@@ -47,4 +47,4 @@ export abstract class ErrorHandler {
abstract log(log: any): void;
abstract handleErrorPopupUnauthorized(error: any): void;
-}
\ No newline at end of file
+}