From 0d242fc0ba84822aba8f3606d371f718a7cbc023 Mon Sep 17 00:00:00 2001 From: FangyuanCheng Date: Wed, 6 Mar 2019 02:09:48 +0800 Subject: [PATCH] Refactoring gc ui support cron Signed-off-by: FangyuanCheng --- .../lib/src/config/gc/gc.component.html | 32 +--- .../lib/src/config/gc/gc.component.scss | 4 + .../lib/src/config/gc/gc.component.spec.ts | 7 +- src/portal/lib/src/config/gc/gc.component.ts | 173 ++++++++---------- src/portal/lib/src/config/gc/gc.const.ts | 16 +- src/portal/lib/src/config/gc/gc.service.ts | 16 +- src/portal/lib/src/config/gc/gc.utility.ts | 62 ------- src/portal/lib/src/config/gc/gcLog.ts | 13 +- src/portal/lib/src/config/gc/index.ts | 1 - .../config/registry-config.component.spec.ts | 4 +- .../cron-schedule.component.html | 50 +++++ .../cron-schedule.component.scss | 45 +++++ .../cron-schedule/cron-schedule.component.ts | 78 ++++++++ src/portal/lib/src/cron-schedule/index.ts | 6 + src/portal/lib/src/harbor-library.module.ts | 14 +- src/portal/lib/src/service/interface.ts | 5 + src/portal/src/i18n/lang/en-us-lang.json | 9 +- src/portal/src/i18n/lang/es-es-lang.json | 6 +- src/portal/src/i18n/lang/fr-fr-lang.json | 6 +- src/portal/src/i18n/lang/pt-br-lang.json | 6 +- src/portal/src/i18n/lang/zh-cn-lang.json | 6 +- 21 files changed, 321 insertions(+), 238 deletions(-) delete mode 100644 src/portal/lib/src/config/gc/gc.utility.ts create mode 100644 src/portal/lib/src/cron-schedule/cron-schedule.component.html create mode 100644 src/portal/lib/src/cron-schedule/cron-schedule.component.scss create mode 100644 src/portal/lib/src/cron-schedule/cron-schedule.component.ts create mode 100644 src/portal/lib/src/cron-schedule/index.ts diff --git a/src/portal/lib/src/config/gc/gc.component.html b/src/portal/lib/src/config/gc/gc.component.html index 5384058e9..2f4d4bb1e 100644 --- a/src/portal/lib/src/config/gc/gc.component.html +++ b/src/portal/lib/src/config/gc/gc.component.html @@ -1,33 +1,5 @@ -
- {{'GC.CURRENT_SCHEDULE' | translate}} - {{(originScheduleType ? 'SCHEDULE.'+ originScheduleType.toUpperCase(): "") | translate}} - {{'SCHEDULE.ON' | translate}} - {{originWeekDay.text | translate}} - {{'SCHEDULE.AT' | translate}} - {{originOffTime.text}} AM - -
-
- -
- -
-
- {{'SCHEDULE.ON' | translate}} - -
-
- {{'SCHEDULE.AT' | translate}} - -
- - +
+
{{'GC.JOB_HISTORY' | translate}}
diff --git a/src/portal/lib/src/config/gc/gc.component.scss b/src/portal/lib/src/config/gc/gc.component.scss index b560ccc6a..217f9d3ea 100644 --- a/src/portal/lib/src/config/gc/gc.component.scss +++ b/src/portal/lib/src/config/gc/gc.component.scss @@ -10,6 +10,10 @@ font-size: .541667rem; } +.cron-selection { + margin-top: 20px; +} + .setting-wrapper { label { width: 228px; diff --git a/src/portal/lib/src/config/gc/gc.component.spec.ts b/src/portal/lib/src/config/gc/gc.component.spec.ts index 6ea81f5e9..635ba8eb1 100644 --- a/src/portal/lib/src/config/gc/gc.component.spec.ts +++ b/src/portal/lib/src/config/gc/gc.component.spec.ts @@ -6,7 +6,7 @@ import { GcRepoService } from './gc.service'; import { SharedModule } from "../../shared/shared.module"; import { ErrorHandler } from '../../error-handler/error-handler'; import { GcViewModelFactory } from './gc.viewmodel.factory'; -import { GcUtility } from './gc.utility'; +import { CronScheduleComponent } from '../../cron-schedule/cron-schedule.component'; import { of } from 'rxjs'; describe('GcComponent', () => { @@ -33,14 +33,13 @@ describe('GcComponent', () => { imports: [ SharedModule ], - declarations: [ GcComponent ], + declarations: [ GcComponent, CronScheduleComponent], providers: [ { provide: GcApiRepository, useClass: GcApiDefaultRepository }, { provide: SERVICE_CONFIG, useValue: config }, GcRepoService, ErrorHandler, - GcViewModelFactory, - GcUtility + GcViewModelFactory ] }) .compileComponents(); diff --git a/src/portal/lib/src/config/gc/gc.component.ts b/src/portal/lib/src/config/gc/gc.component.ts index f8e5a6c71..b4b2f7cc9 100644 --- a/src/portal/lib/src/config/gc/gc.component.ts +++ b/src/portal/lib/src/config/gc/gc.component.ts @@ -1,40 +1,47 @@ -import { Component, Input, Output, EventEmitter, ViewChild, OnInit } from '@angular/core'; -import { TranslateService } from '@ngx-translate/core'; -import { GcJobViewModel, WeekDay } from "./gcLog"; +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 { WEEKDAYS, SCHEDULE_TYPE, ONE_MINITUE, THREE_SECONDS} from './gc.const'; -import { GcUtility } from './gc.utility'; -import { ErrorHandler } from '../../error-handler/index'; +import { + SCHEDULE_TYPE_NONE, + ONE_MINITUE, + THREE_SECONDS +} from "./gc.const"; +import { ErrorHandler } from "../../error-handler/index"; +import { CronScheduleComponent } from "../../cron-schedule/cron-schedule.component"; +import { OriginCron } from '../../service/interface'; @Component({ - selector: 'gc-config', - templateUrl: './gc.component.html', - styleUrls: ['./gc.component.scss'] + selector: "gc-config", + templateUrl: "./gc.component.html", + styleUrls: ["./gc.component.scss"] }) export class GcComponent implements OnInit { jobs: Array = []; schedule: any; - originScheduleType: string; - originOffTime: any = { value: null, text: "" }; - originWeekDay: any = { value: null, text: "" }; - scheduleType: string; - isEditMode: boolean = false; - weekDays = WEEKDAYS; - SCHEDULE_TYPE = SCHEDULE_TYPE; - weekDay: WeekDay = WEEKDAYS[0]; - dailyTime: string; + originCron: OriginCron; disableGC: boolean = false; - - constructor(private gcRepoService: GcRepoService, + getText = 'CONFIG.GC'; + getLabelCurrent = 'GC.CURRENT_SCHEDULE'; + @ViewChild(CronScheduleComponent) + CronScheduleComponent: CronScheduleComponent; + constructor( + private gcRepoService: GcRepoService, private gcViewModelFactory: GcViewModelFactory, - private gcUtility: GcUtility, private errorHandler: ErrorHandler, - private translate: TranslateService) { - translate.setDefaultLang('en-us'); + private translate: TranslateService + ) { + translate.setDefaultLang("en-us"); } - ngOnInit() { this.getCurrentSchedule(); this.getJobs(); @@ -46,32 +53,15 @@ export class GcComponent implements OnInit { }); } - private initSchedule(schedule: any) { + public initSchedule(schedule: any) { if (schedule && schedule.length > 0) { this.schedule = schedule[0]; - const cron = this.schedule.schedule; - this.originScheduleType = cron.type; - this.originWeekDay = this.weekDays[cron.weekday]; - let dailyTime = this.gcUtility.getDailyTime(cron.offtime); - this.originOffTime = { value: cron.offtime, text: dailyTime }; + this.originCron = this.schedule.schedule; } else { - this.originScheduleType = SCHEDULE_TYPE.NONE; - } - } - - editSchedule() { - this.isEditMode = true; - this.scheduleType = this.originScheduleType; - if (this.originWeekDay.value) { - this.weekDay = this.originWeekDay; - } else { - this.weekDay = this.weekDays[0]; - } - - if (this.originOffTime.value) { - this.dailyTime = this.originOffTime.text; - } else { - this.dailyTime = "00:00"; + this.originCron = { + type: SCHEDULE_TYPE_NONE, + cron: '' + }; } } @@ -83,59 +73,58 @@ export class GcComponent implements OnInit { gcNow(): void { this.disableGC = true; - setTimeout(() => {this.enableGc(); }, ONE_MINITUE); + setTimeout(() => { + this.enableGc(); + }, ONE_MINITUE); - this.gcRepoService.manualGc().subscribe(response => { - this.translate.get('GC.MSG_SUCCESS').subscribe((res: string) => { - this.errorHandler.info(res); - }); - this.getJobs(); - setTimeout(() => {this.getJobs(); }, THREE_SECONDS); // to avoid some jobs not finished. - }, error => { - this.errorHandler.error(error); - }); + this.gcRepoService.manualGc().subscribe( + response => { + this.translate.get("GC.MSG_SUCCESS").subscribe((res: string) => { + this.errorHandler.info(res); + }); + this.getJobs(); + setTimeout(() => { + this.getJobs(); + }, THREE_SECONDS); // to avoid some jobs not finished. + }, + error => { + this.errorHandler.error(error); + } + ); } - private enableGc () { + private enableGc() { this.disableGC = false; } - private resetSchedule(offTime) { - this.schedule = { - schedule: { - type: this.scheduleType, - offTime: offTime, - weekDay: this.weekDay.value - } - }; - this.originScheduleType = this.scheduleType; - this.originWeekDay = this.weekDay; - this.originOffTime = { value: offTime, text: this.dailyTime }; - this.isEditMode = false; - this.getJobs(); - } - - scheduleGc(): void { - let offTime = this.gcUtility.getOffTime(this.dailyTime); + getcron(cron: string) { let schedule = this.schedule; - if (schedule && schedule.schedule && schedule.schedule.type !== SCHEDULE_TYPE.NONE) { - this.gcRepoService.putScheduleGc(this.scheduleType, offTime, this.weekDay.value).subscribe(response => { - this.translate.get('GC.MSG_SCHEDULE_RESET').subscribe((res: string) => { - this.errorHandler.info(res); - }); - this.resetSchedule(offTime); - }, error => { - this.errorHandler.error(error); - }); + if (schedule && schedule.schedule && schedule.schedule.type !== SCHEDULE_TYPE_NONE) { + this.gcRepoService.putScheduleGc(this.CronScheduleComponent.scheduleType, cron).subscribe( + response => { + this.translate + .get("GC.MSG_SCHEDULE_RESET") + .subscribe((res) => { + this.errorHandler.info(res); + }); + this.getJobs(); + }, + error => { + this.errorHandler.error(error); + } + ); } else { - this.gcRepoService.postScheduleGc(this.scheduleType, offTime, this.weekDay.value).subscribe(response => { - this.translate.get('GC.MSG_SCHEDULE_SET').subscribe((res: string) => { - this.errorHandler.info(res); - }); - this.resetSchedule(offTime); - }, error => { - this.errorHandler.error(error); - }); + this.gcRepoService.postScheduleGc(this.CronScheduleComponent.scheduleType, cron).subscribe( + response => { + this.translate.get("GC.MSG_SCHEDULE_SET").subscribe((res) => { + this.errorHandler.info(res); + }); + this.getJobs(); + }, + error => { + this.errorHandler.error(error); + } + ); } } } diff --git a/src/portal/lib/src/config/gc/gc.const.ts b/src/portal/lib/src/config/gc/gc.const.ts index f095adb0f..2407b098c 100644 --- a/src/portal/lib/src/config/gc/gc.const.ts +++ b/src/portal/lib/src/config/gc/gc.const.ts @@ -1,18 +1,6 @@ -export const WEEKDAYS = [ - {value: 0, text: "WEEKLY.MONDAY"}, - {value: 1, text: "WEEKLY.TUESDAY"}, - {value: 2, text: "WEEKLY.WEDNESDAY"}, - {value: 3, text: "WEEKLY.THURSDAY"}, - {value: 4, text: "WEEKLY.FRIDAY"}, - {value: 5, text: "WEEKLY.SATURDAY"}, - {value: 6, text: "WEEKLY.SUNDAY"} -]; -export const SCHEDULE_TYPE = { - NONE: "None", - DAILY: "Daily", - WEEKLY: "Weekly" -}; + +export const SCHEDULE_TYPE_NONE = "None"; export const ONE_MINITUE = 60000; export const THREE_SECONDS = 3000; diff --git a/src/portal/lib/src/config/gc/gc.service.ts b/src/portal/lib/src/config/gc/gc.service.ts index 126ad7580..9bca2c3b2 100644 --- a/src/portal/lib/src/config/gc/gc.service.ts +++ b/src/portal/lib/src/config/gc/gc.service.ts @@ -36,29 +36,25 @@ export class GcRepoService { return this.gcApiRepository.getSchedule(); } - public postScheduleGc(type, offTime, weekday ?): Observable { + public postScheduleGc(type, cron): Observable { let param = { "schedule": { "type": type, - "offtime": offTime, + "cron": cron, } }; - if (weekday) { - param.schedule["weekday"] = weekday; - } + return this.gcApiRepository.postSchedule(param); } - public putScheduleGc(type, offTime, weekday ?): Observable { + public putScheduleGc(type, cron): Observable { let param = { "schedule": { "type": type, - "offtime": offTime, + "cron": cron, } }; - if (weekday) { - param.schedule["weekday"] = weekday; - } + return this.gcApiRepository.putSchedule(param); } } diff --git a/src/portal/lib/src/config/gc/gc.utility.ts b/src/portal/lib/src/config/gc/gc.utility.ts deleted file mode 100644 index 6c06e55ea..000000000 --- a/src/portal/lib/src/config/gc/gc.utility.ts +++ /dev/null @@ -1,62 +0,0 @@ - -import { Injectable } from '@angular/core'; - -const ONE_HOUR_SECONDS: number = 3600; -const ONE_DAY_SECONDS: number = 24 * ONE_HOUR_SECONDS; - -@Injectable() -export class GcUtility { - private _localTime: Date = new Date(); - public getOffTime(v: string) { - let values: string[] = v.split(":"); - if (!values || values.length !== 2) { - return; - } - let hours: number = +values[0]; - let minutes: number = +values[1]; - // Convert to UTC time - let timezoneOffset: number = this._localTime.getTimezoneOffset(); - let utcTimes: number = hours * ONE_HOUR_SECONDS + minutes * 60; - utcTimes += timezoneOffset * 60; - if (utcTimes < 0) { - utcTimes += ONE_DAY_SECONDS; - } - if (utcTimes >= ONE_DAY_SECONDS) { - utcTimes -= ONE_DAY_SECONDS; - } - return utcTimes; - } - - public getDailyTime(v: number ) { - let timeOffset: number = 0; // seconds - timeOffset = + v; - // Convert to current time - let timezoneOffset: number = this._localTime.getTimezoneOffset(); - // Local time - timeOffset = timeOffset - timezoneOffset * 60; - if (timeOffset < 0) { - timeOffset = timeOffset + ONE_DAY_SECONDS; - } - - if (timeOffset >= ONE_DAY_SECONDS) { - timeOffset -= ONE_DAY_SECONDS; - } - - // To time string - let hours: number = Math.floor(timeOffset / ONE_HOUR_SECONDS); - let minutes: number = Math.floor((timeOffset - hours * ONE_HOUR_SECONDS) / 60); - - let timeStr: string = "" + hours; - if (hours < 10) { - timeStr = "0" + timeStr; - } - if (minutes < 10) { - timeStr += ":0"; - } else { - timeStr += ":"; - } - timeStr += minutes; - - return timeStr; - } -} diff --git a/src/portal/lib/src/config/gc/gcLog.ts b/src/portal/lib/src/config/gc/gcLog.ts index 8de1d4137..e55dd3751 100644 --- a/src/portal/lib/src/config/gc/gcLog.ts +++ b/src/portal/lib/src/config/gc/gcLog.ts @@ -12,8 +12,7 @@ export class GcJobData { export class Schedule { type: string; - weekday: number; - offtime: number; + cron: string; } export class GcJobViewModel { id: number; @@ -24,14 +23,4 @@ export class GcJobViewModel { details: string; } -export class WeekDay { - value: number; - text: string; -} - -export class GcScheduleViewModel { - type: string; - weekDay: string; - dailyTime: string; -} diff --git a/src/portal/lib/src/config/gc/index.ts b/src/portal/lib/src/config/gc/index.ts index 8bc26568d..b80853d74 100644 --- a/src/portal/lib/src/config/gc/index.ts +++ b/src/portal/lib/src/config/gc/index.ts @@ -2,6 +2,5 @@ export * from "./gc.component"; export * from "./gc.const"; export * from "./gc.api.repository"; export * from "./gc.service"; -export * from "./gc.utility"; export * from "./gc.viewmodel.factory"; export * from "./gcLog"; diff --git a/src/portal/lib/src/config/registry-config.component.spec.ts b/src/portal/lib/src/config/registry-config.component.spec.ts index a3a183702..a7159b9e7 100644 --- a/src/portal/lib/src/config/registry-config.component.spec.ts +++ b/src/portal/lib/src/config/registry-config.component.spec.ts @@ -9,6 +9,7 @@ import { VulnerabilityConfigComponent } from './vulnerability/vulnerability-conf import { RegistryConfigComponent } from './registry-config.component'; import { ConfirmationDialogComponent } from '../confirmation-dialog/confirmation-dialog.component'; import { GcComponent } from './gc/gc.component'; +import { CronScheduleComponent } from '../cron-schedule/cron-schedule.component'; import { ConfigurationService, @@ -64,7 +65,8 @@ describe('RegistryConfigComponent (inline template)', () => { VulnerabilityConfigComponent, RegistryConfigComponent, ConfirmationDialogComponent, - GcComponent + GcComponent, + CronScheduleComponent ], providers: [ ErrorHandler, diff --git a/src/portal/lib/src/cron-schedule/cron-schedule.component.html b/src/portal/lib/src/cron-schedule/cron-schedule.component.html new file mode 100644 index 000000000..2312de378 --- /dev/null +++ b/src/portal/lib/src/cron-schedule/cron-schedule.component.html @@ -0,0 +1,50 @@ +
+ {{ labelCurrent | translate }} + {{(originScheduleType ? 'SCHEDULE.'+ originScheduleType.toUpperCase(): "") | translate}} + + + {{'CONFIG.TOOLTIP.HOURLY_CRON' | translate}} + + + + {{'CONFIG.TOOLTIP.WEEKLY_CRON' | translate}} + + + + {{'CONFIG.TOOLTIP.DAILY_CRON' | translate}} + + {{ "SCHEDULE.CRON" | translate }} : + {{ oriCron }} + +
+
+ {{ labelEdit | translate }} +
+ +
+ {{ "SCHEDULE.CRON" | translate }} : +
+ +
+ + +
\ No newline at end of file diff --git a/src/portal/lib/src/cron-schedule/cron-schedule.component.scss b/src/portal/lib/src/cron-schedule/cron-schedule.component.scss new file mode 100644 index 000000000..944262fec --- /dev/null +++ b/src/portal/lib/src/cron-schedule/cron-schedule.component.scss @@ -0,0 +1,45 @@ +.flex-layout { + display: flex; + align-items: center; + margin: 20px 0; + font-size: .541667rem; + } + + .normal-wrapper { + > span:first-child { + width: 228px; + } + + > span:not(:first-child) { + margin-right: 18px; + } + > a { + margin-left: -10px; + } + button { + margin-left: 10px; + } + } + + .setting-wrapper { + > span:first-child { + width: 228px; + } + + *:not(:first-child) { + margin-right: 18px; + } + + .select-schedule { + display: inline-block; + width: 100px; + } + + .cron-input { + width: 195px; + } + } + .font-style { + color: #000; + font-size: .541667rem; + } \ No newline at end of file diff --git a/src/portal/lib/src/cron-schedule/cron-schedule.component.ts b/src/portal/lib/src/cron-schedule/cron-schedule.component.ts new file mode 100644 index 000000000..46e53960a --- /dev/null +++ b/src/portal/lib/src/cron-schedule/cron-schedule.component.ts @@ -0,0 +1,78 @@ +import { + Component, + EventEmitter, + Output, + Input, + OnChanges, + SimpleChanges, + SimpleChange +} from "@angular/core"; +import { OriginCron } from "../service/interface"; +const SCHEDULE_TYPE = { + NONE: "None", + DAILY: "Daily", + WEEKLY: "Weekly", + HOURLY: "Hourly", + CUSTOM: "Custom" +}; +@Component({ + selector: "cron-selection", + templateUrl: "./cron-schedule.component.html", + styleUrls: ["./cron-schedule.component.scss"] +}) +export class CronScheduleComponent implements OnChanges { + @Input() originCron: OriginCron; + @Input() labelEdit: string; + @Input() labelCurrent: string; + originScheduleType: string; + oriCron: string; + cronString: string; + isEditMode: boolean = false; + SCHEDULE_TYPE = SCHEDULE_TYPE; + scheduleType: string; + @Output() inputvalue = new EventEmitter(); + + ngOnChanges(changes: SimpleChanges): void { + let cronChange: SimpleChange = changes["originCron"]; + if (cronChange.currentValue) { + this.originScheduleType = cronChange.currentValue.type; + this.oriCron = cronChange.currentValue.cron; + } + } + editSchedule() { + if (!this.originScheduleType) { + return; + } + this.isEditMode = true; + this.scheduleType = this.originScheduleType; + if (this.scheduleType && this.scheduleType === SCHEDULE_TYPE.CUSTOM) { + this.cronString = this.oriCron; + } else { + this.cronString = ""; + } + } + + public resetSchedule() { + this.originScheduleType = this.scheduleType; + this.oriCron = this.cronString; + this.isEditMode = false; + } + + save(): void { + let scheduleTerm: string = ""; + this.resetSchedule(); + if (this.scheduleType && this.scheduleType === SCHEDULE_TYPE.NONE) { + scheduleTerm = ""; + } else if (this.scheduleType && this.scheduleType === SCHEDULE_TYPE.HOURLY) { + scheduleTerm = "0 0 * * * *"; + } else if (this.scheduleType && this.scheduleType === SCHEDULE_TYPE.DAILY) { + scheduleTerm = "0 0 0 * * *"; + } else if (this.scheduleType && this.scheduleType === SCHEDULE_TYPE.WEEKLY) { + scheduleTerm = "0 0 0 * * 0"; + } else { + scheduleTerm = this.cronString; + } + scheduleTerm = scheduleTerm.replace(/\s+/g, " ").trim(); + this.inputvalue.emit(scheduleTerm); + } +} diff --git a/src/portal/lib/src/cron-schedule/index.ts b/src/portal/lib/src/cron-schedule/index.ts new file mode 100644 index 000000000..b70e5071e --- /dev/null +++ b/src/portal/lib/src/cron-schedule/index.ts @@ -0,0 +1,6 @@ +import { Type } from "@angular/core"; + +import { CronScheduleComponent } from "./cron-schedule.component"; +export const CRON_SCHEDULE_DIRECTIVES: Type[] = [ + CronScheduleComponent +]; diff --git a/src/portal/lib/src/harbor-library.module.ts b/src/portal/lib/src/harbor-library.module.ts index fffd8432e..44baa557c 100644 --- a/src/portal/lib/src/harbor-library.module.ts +++ b/src/portal/lib/src/harbor-library.module.ts @@ -29,6 +29,7 @@ import { CREATE_EDIT_LABEL_DIRECTIVES } from "./create-edit-label/index"; import { LABEL_PIECE_DIRECTIVES } from "./label-piece/index"; import { HELMCHART_DIRECTIVE } from "./helm-chart/index"; import { IMAGE_NAME_INPUT_DIRECTIVES } from "./image-name-input/index"; +import { CRON_SCHEDULE_DIRECTIVES } from "./cron-schedule/index"; import { SystemInfoService, SystemInfoDefaultService, @@ -60,7 +61,6 @@ import { UserPermissionDefaultService } from './service/index'; import { GcRepoService } from './config/gc/gc.service'; -import { GcUtility } from './config/gc/gc.utility'; import {GcViewModelFactory} from './config/gc/gc.viewmodel.factory'; import {GcApiRepository, GcApiDefaultRepository} from './config/gc/gc.api.repository'; import { @@ -210,7 +210,8 @@ export function initConfig(translateInitializer: TranslateServiceInitializer, co REPOSITORY_GRIDVIEW_DIRECTIVES, OPERATION_DIRECTIVES, HELMCHART_DIRECTIVE, - IMAGE_NAME_INPUT_DIRECTIVES + IMAGE_NAME_INPUT_DIRECTIVES, + CRON_SCHEDULE_DIRECTIVES ], exports: [ LOG_DIRECTIVES, @@ -237,7 +238,8 @@ export function initConfig(translateInitializer: TranslateServiceInitializer, co REPOSITORY_GRIDVIEW_DIRECTIVES, OPERATION_DIRECTIVES, HELMCHART_DIRECTIVE, - IMAGE_NAME_INPUT_DIRECTIVES + IMAGE_NAME_INPUT_DIRECTIVES, + CRON_SCHEDULE_DIRECTIVES ], providers: [] }) @@ -275,8 +277,7 @@ export class HarborLibraryModule { ChannelService, OperationService, GcRepoService, - GcViewModelFactory, - GcUtility + GcViewModelFactory ] }; } @@ -305,8 +306,7 @@ export class HarborLibraryModule { ChannelService, OperationService, GcRepoService, - GcViewModelFactory, - GcUtility + GcViewModelFactory ] }; } diff --git a/src/portal/lib/src/service/interface.ts b/src/portal/lib/src/service/interface.ts index 7bd1c8993..91c34601a 100644 --- a/src/portal/lib/src/service/interface.ts +++ b/src/portal/lib/src/service/interface.ts @@ -446,3 +446,8 @@ export interface UserPrivilegeServeItem { action: string; } +export class OriginCron { + type: string; + cron: string; +} + diff --git a/src/portal/src/i18n/lang/en-us-lang.json b/src/portal/src/i18n/lang/en-us-lang.json index ca2ce6bf2..111d25b55 100644 --- a/src/portal/src/i18n/lang/en-us-lang.json +++ b/src/portal/src/i18n/lang/en-us-lang.json @@ -65,6 +65,7 @@ "ITEM_REQUIRED": "Field is required.", "NUMBER_REQUIRED": "Field is required and should be numbers.", "PORT_REQUIRED": "Field is required and should be valid port number.", + "CRON_REQUIRED": "Field is required and should be in cron format.", "EMAIL_EXISTING": "Email address already exists.", "USER_EXISTING": "Username is already in use.", "RULE_USER_EXISTING": "Name is already in use.", @@ -642,7 +643,10 @@ "SCANNING_POLICY": "Set image scanning policy based on different requirements. 'None': No active policy; 'Daily At': Triggering scanning at the specified time everyday.", "VERIFY_CERT": "Verify Cert from LDAP Server", "READONLY_TOOLTIP": "In read-only mode, you can not delete repositories or tags or push images. ", - "REPO_TOOLTIP": "Users can not do any operations to the images in this mode." + "REPO_TOOLTIP": "Users can not do any operations to the images in this mode.", + "HOURLY_CRON":"Run once an hour, beginning of hour", + "WEEKLY_CRON":"Run once a week, midnight between Sat/Sun", + "DAILY_CRON":"Run once a day, midnight" }, "LDAP": { "URL": "LDAP URL", @@ -876,7 +880,10 @@ "NONE": "None", "DAILY": "Daily", "WEEKLY": "Weekly", + "HOURLY": "Hourly", + "CUSTOM": "Custom", "MANUAL": "Manual", + "CRON": "cron", "ON": "on", "AT": "at" }, diff --git a/src/portal/src/i18n/lang/es-es-lang.json b/src/portal/src/i18n/lang/es-es-lang.json index 8e626b631..e00eb2a2c 100644 --- a/src/portal/src/i18n/lang/es-es-lang.json +++ b/src/portal/src/i18n/lang/es-es-lang.json @@ -65,6 +65,7 @@ "ITEM_REQUIRED": "Campo obligatorio.", "NUMBER_REQUIRED": "El campo es obligatorio y debería ser un número.", "PORT_REQUIRED": "El campo es obligatorio y debería ser un número de puerto válido.", + "CRON_REQUIRED": "El campo es obligatorio y debe estar en formato cron.", "EMAIL_EXISTING": "Esa dirección de email ya existe.", "USER_EXISTING": "Ese nombre de usuario ya existe.", "RULE_USER_EXISTING": "Name is already in use.", @@ -641,7 +642,10 @@ "SCANNING_POLICY": "Set image scanning policy based on different requirements. 'None': No active policy; 'Daily At': Triggering scanning at the specified time everyday.", "VERIFY_CERT": "Verify Cert from LDAP Server", "READONLY_TOOLTIP": "In read-only mode, you can not delete repositories or tags or push images. ", - "GC_POLICY": "" + "GC_POLICY": "", + "HOURLY_CRON":"Run once an hour, beginning of hour", + "WEEKLY_CRON":"Run once a week, midnight between Sat/Sun", + "DAILY_CRON":"Run once a day, midnight" }, "LDAP": { diff --git a/src/portal/src/i18n/lang/fr-fr-lang.json b/src/portal/src/i18n/lang/fr-fr-lang.json index 1f8f7492b..1dc0ff454 100644 --- a/src/portal/src/i18n/lang/fr-fr-lang.json +++ b/src/portal/src/i18n/lang/fr-fr-lang.json @@ -54,6 +54,7 @@ "ITEM_REQUIRED": "Le champ est obligatoire.", "NUMBER_REQUIRED": "Le champ est obligatoire et doit être numérique.", "PORT_REQUIRED": "Le champ est obligatoire et doit être un numéro de port valide.", + "CRON_REQUIRED": "Le champ est obligatoire et doit être au format cron.", "EMAIL_EXISTING": "L'adresse e-mail existe déjà.", "USER_EXISTING": "Le nom d'utilisateur est déjà utilisé.", "NONEMPTY": "Can't be empty", @@ -613,7 +614,10 @@ "ROOT_CERT_DOWNLOAD": "Téléchargez le certificat racine du dépôt.", "SCANNING_POLICY": "Définissez la politique d'analyse des images en fonction des différentes exigences. 'Aucune' : pas de politique active; 'Tousles jours à' : déclenchement du balayage à l'heure spécifiée tous les jours.", "READONLY_TOOLTIP": "In read-only mode, you can not delete repositories or tags or push images. ", - "GC_POLICY": "" + "GC_POLICY": "", + "HOURLY_CRON":"Run once an hour, beginning of hour", + "WEEKLY_CRON":"Run once a week, midnight between Sat/Sun", + "DAILY_CRON":"Run once a day, midnight" }, "LDAP": { "URL": "URL LDAP", diff --git a/src/portal/src/i18n/lang/pt-br-lang.json b/src/portal/src/i18n/lang/pt-br-lang.json index 377ca279b..f1d8099eb 100644 --- a/src/portal/src/i18n/lang/pt-br-lang.json +++ b/src/portal/src/i18n/lang/pt-br-lang.json @@ -65,6 +65,7 @@ "ITEM_REQUIRED": "Campo é obrigatório.", "NUMBER_REQUIRED": "Campo é obrigatório e deve ser numerico.", "PORT_REQUIRED": "Campo é obrigatório e deve ser um número de porta válido.", + "CRON_REQUIRED": "O campo é obrigatório e deve estar no formato cron.", "EMAIL_EXISTING": "Email já existe.", "USER_EXISTING": "Nome de usuário já está em uso.", "RULE_USER_EXISTING": "Nome já em uso.", @@ -635,7 +636,10 @@ "SCANNING_POLICY": "Configura a política de análise das imagens baseado em diferentes requisitos. 'Nenhum': Nenhuma política ativa; 'Diariamente em': Dispara a análise diariamente no horário especificado.", "VERIFY_CERT": "Verificar o Certificado do Servidor LDAP", "READONLY_TOOLTIP": "Em modo somente leitura, você não pode remover repositórios ou tags ou enviar imagens. ", - "REPO_TOOLTIP": "Usuários não podem efetuar qualquer operação nas imagens nesse modo." + "REPO_TOOLTIP": "Usuários não podem efetuar qualquer operação nas imagens nesse modo.", + "HOURLY_CRON":"Run once an hour, beginning of hour", + "WEEKLY_CRON":"Run once a week, midnight between Sat/Sun", + "DAILY_CRON":"Run once a day, midnight" }, "LDAP": { "URL": "URL LDAP", diff --git a/src/portal/src/i18n/lang/zh-cn-lang.json b/src/portal/src/i18n/lang/zh-cn-lang.json index cc34a0665..2b6627ff4 100644 --- a/src/portal/src/i18n/lang/zh-cn-lang.json +++ b/src/portal/src/i18n/lang/zh-cn-lang.json @@ -65,6 +65,7 @@ "ITEM_REQUIRED": "此项为必填项。", "NUMBER_REQUIRED": "此项为必填项且为数字。", "PORT_REQUIRED": "此项为必填项且为合法端口号。", + "CRON_REQUIRED": "此项为必填项且为cron格式。", "EMAIL_EXISTING": "邮件地址已经存在。", "USER_EXISTING": "用户名已经存在。", "RULE_USER_EXISTING": "名称已经存在。", @@ -641,7 +642,10 @@ "SCANNING_POLICY": "基于不同需求设置镜像扫描策略。‘无’:不设置任何策略;‘每日定时’:每天在设置的时间定时执行扫描。", "VERIFY_CERT": "检查来自LDAP服务端的证书", "READONLY_TOOLTIP": "选中,表示正在维护状态,不可删除仓库及标签,也不可以推送镜像。", - "REPO_TOOLTIP": "用户在此模式下无法对图像执行任何操作。" + "REPO_TOOLTIP": "用户在此模式下无法对图像执行任何操作。", + "HOURLY_CRON":"每小时运行一次", + "WEEKLY_CRON":"每周一次,周六/周日午夜之间开始", + "DAILY_CRON":"每天午夜运行一次" }, "LDAP": { "URL": "LDAP URL",