Merge pull request #7641 from pureshine/cron-validator

Remove the frontend check of cron
This commit is contained in:
Fangyuan Cheng 2019-05-06 20:52:00 +08:00 committed by GitHub
commit 0988a38e84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 133 additions and 41 deletions

View File

@ -1,4 +1,4 @@
<div class="cron-selection">
<cron-selection [labelCurrent]="getLabelCurrent" [labelEdit]='getText' [originCron]='originCron' (inputvalue)="scheduleGc($event)"></cron-selection>
<cron-selection [labelCurrent]="getLabelCurrent" #CronScheduleComponent [labelEdit]='getText' [originCron]='originCron' (inputvalue)="scheduleGc($event)"></cron-selection>
<button class="btn btn-outline btn-sm gc-start-btn" (click)="gcNow()" [disabled]="disableGC">{{'GC.GC_NOW' | translate}}</button>
</div>

View File

@ -122,6 +122,7 @@ export class GcComponent implements OnInit {
.get("GC.MSG_SCHEDULE_RESET")
.subscribe((res) => {
this.errorHandler.info(res);
this.CronScheduleComponent.resetSchedule();
});
this.resetSchedule(cron);
},
@ -134,6 +135,7 @@ export class GcComponent implements OnInit {
response => {
this.translate.get("GC.MSG_SCHEDULE_SET").subscribe((res) => {
this.errorHandler.info(res);
this.CronScheduleComponent.resetSchedule();
});
this.resetSchedule(cron);
},

View File

@ -24,7 +24,7 @@
<span *ngIf="isClairDBFullyReady && !showScanningNamespaces">{{ updatedTimestamp | date:'MM/dd/y HH:mm:ss' }} AM</span>
</div>
<div class="button-group">
<cron-selection [labelCurrent]="getLabelCurrent" [labelEdit]='getLabelCurrent' [originCron]='originCron' (inputvalue)="scanAll($event)"></cron-selection>
<cron-selection #CronScheduleComponent [labelCurrent]="getLabelCurrent" [labelEdit]='getLabelCurrent' [originCron]='originCron' (inputvalue)="scanAll($event)"></cron-selection>
<div class="btn-scan-right btn-scan">
<button class="btn btn-outline btn-sm btn-scan" (click)="scanNow()" [disabled]="!scanAvailable">{{ 'CONFIG.SCANNING.SCAN_NOW' | translate }}</button><br>
</div>

View File

@ -192,6 +192,7 @@ export class VulnerabilityConfigComponent implements OnInit {
.get("CONFIG.SAVE_SUCCESS")
.subscribe((res) => {
this.errorHandler.info(res);
this.CronScheduleComponent.resetSchedule();
});
this.reset(cron);
},
@ -204,6 +205,7 @@ export class VulnerabilityConfigComponent implements OnInit {
.subscribe(response => {
this.translate.get("CONFIG.SAVE_SUCCESS").subscribe((res) => {
this.errorHandler.info(res);
this.CronScheduleComponent.resetSchedule();
});
this.reset(cron);
},

View File

@ -138,8 +138,8 @@
<div formGroupName="trigger_settings">
<div [hidden]="isNotSchedule()" class="form-group form-cron">
<label class="required">Cron String</label>
<label for="targetCron" aria-haspopup="true" role="tooltip"class="tooltip tooltip-validation tooltip-md tooltip-top-right"
[class.invalid]="!isNotSchedule() && cronTouched || !cronInputValid(ruleForm.value.trigger?.trigger_settings?.cron || '')" >
<label for="targetCron" aria-haspopup="true" role="tooltip"class="tooltip tooltip-validation tooltip-sm tooltip-top-right"
[class.invalid]="!isNotSchedule() && cronTouched && !cronInputValid(ruleForm.value.trigger?.trigger_settings?.cron || '')" >
<input type="text" name=targetCron id="targetCron" required class="form-control cron-input" formControlName="cron">
<span class="tooltip-content">
{{'TOOLTIP.CRON_REQUIRED' | translate }}

View File

@ -464,7 +464,6 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
if (!trigger_settingsControls) {
return false;
}
return trigger_settingsControls.controls.cron.touched && trigger_settingsControls.controls.cron.dirty
&& !trigger_settingsControls.controls.cron.value;
return trigger_settingsControls.controls.cron.touched || trigger_settingsControls.controls.cron.dirty;
}
}

View File

@ -1,5 +1,5 @@
<div class="normal-wrapper flex-layout" *ngIf="!isEditMode">
<div>
<div class="normal-wrapper-box flex-layout" *ngIf="!isEditMode">
<div class="normal-wrapper">
<span class="font-style">{{ labelCurrent | translate }}</span>
<span>{{(originScheduleType ? 'SCHEDULE.'+ originScheduleType.toUpperCase(): "") | translate}}</span>
<a [hidden]="originScheduleType!==SCHEDULE_TYPE.HOURLY" href="javascript:void(0)" role="tooltip" aria-haspopup="true" class="tooltip tooltip-top-right">
@ -32,15 +32,71 @@
<option [value]="SCHEDULE_TYPE.CUSTOM">{{'SCHEDULE.CUSTOM' | translate}}</option>
</select>
</div>
<span [hidden]="scheduleType!==SCHEDULE_TYPE.CUSTOM">{{ "SCHEDULE.CRON" | translate }} :</span>
<span class="required" [hidden]="scheduleType!==SCHEDULE_TYPE.CUSTOM">{{ "SCHEDULE.CRON" | translate }}</span>
<div [hidden]="scheduleType!==SCHEDULE_TYPE.CUSTOM" class="cron-input">
<label for="targetCron" aria-haspopup="true" role="tooltip" [class.invalid]="dateInvalid" class="tooltip tooltip-validation tooltip-md tooltip-top-right cron-label">
<input type="text" (blur)="blurInvalid()" (input)="inputInvalid()" name=targetCron id="targetCron" #cronStringInput="ngModel" required class="form-control"
<label for="targetCron" aria-haspopup="true" role="tooltip" [class.invalid]="dateInvalid" class="tooltip tooltip-validation tooltip-md tooltip-top-left cron-label">
<input type="text" (blur)="blurInvalid()" (input)="inputInvalid()" name=targetCron id="targetCron" #cronStringInput="ngModel" required class="form-control"
[(ngModel)]="cronString">
<span class="tooltip-content" *ngIf="dateInvalid">
{{'TOOLTIP.CRON_REQUIRED' | translate }}
</span>
</label>
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true" class="tooltip tooltip-lg tooltip-right top-7 cron-tooltip">
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
<table class="table table-noborder tooltip-content table-style">
<caption class="table-title">
<span>
{{ 'REPLICATION.CRON-TITLE' | translate }}
</span>
</caption>
<thead>
<tr>
<th>{{ 'REPLICATION.FIELD_NAME' | translate }}</th>
<th>{{ 'REPLICATION.MANDATORY' | translate }}</th>
<th>{{ 'REPLICATION.ALLOWED_VALUES' | translate }}</th>
<th>{{ 'REPLICATION.ALLOWED_CHARACTERS' | translate }}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{'REPLICATION.SECONDS' | translate}}</td>
<td>{{'REPLICATION.YES' | translate}}</td>
<td>0-59</td>
<td>* / , -</td>
</tr>
<tr>
<td>{{'REPLICATION.MINUTES' | translate}}</td>
<td>{{'REPLICATION.YES' | translate}}</td>
<td>0-59</td>
<td>* / , -</td>
</tr>
<tr>
<td>{{'REPLICATION.HOURS' | translate}}</td>
<td>{{'REPLICATION.YES' | translate}}</td>
<td>0-23</td>
<td>* / , -</td>
</tr>
<tr>
<td>{{'REPLICATION.DAY_MONTH' | translate}}</td>
<td>{{'REPLICATION.YES' | translate}}</td>
<td>1-31</td>
<td>* / , - ?</td>
</tr>
<tr>
<td>{{'REPLICATION.MONTH' | translate}}</td>
<td>{{'REPLICATION.YES' | translate}}</td>
<td>1-12 or JAN-DEC</td>
<td>* / , -</td>
</tr>
<tr>
<td>{{'REPLICATION.DAY_WEEK' | translate}}</td>
<td>{{'REPLICATION.YES' | translate}}</td>
<td>0-6 or SUN-SAT</td>
<td>* / , - ?</td>
</tr>
</tbody>
</table>
</a>
</div>
<div class="confirm-button">
<button class="btn btn-primary btn-sm"

View File

@ -3,23 +3,29 @@
font-size: .541667rem;
}
.normal-wrapper {
> span:first-child {
width: 200px;
}
> span:not(:first-child) {
margin-right: 18px;
}
> a {
margin-left: -10px;
.normal-wrapper-box {
position: relative;
.normal-wrapper {
position: absolute;
width: 700px;
> span:first-child {
width: 200px;
}
> span:not(:first-child) {
margin-right: 18px;
}
> a {
margin-left: -10px;
}
}
button {
margin: 20px 20px 0 200px;
margin: 35px 20px 0 200px;
}
}
.setting-wrapper {
position: relative;
> span:first-child {
width: 200px;
}
@ -46,6 +52,27 @@
.cron-label {
width: 195px;
}
.cron-tooltip {
color: gray;
cursor: default;
.table-style {
margin-right: 462px;
width: 20rem;
border-top-left-radius: 0;
border-top-right-radius: 0;
.table-title {
border-top-left-radius: 0.125rem;
border-top-right-radius: 0.125rem;
height: 40px;
line-height: 40px;
background: #000;
color: #fff;
span {
font-size: 16px;
}
}
}
}
}
.font-style {
@ -54,3 +81,13 @@
font-size: .541667rem;
width: 200px;
}
span.required {
&:after {
content: '*';
font-size: .58479532rem;
line-height: .5rem;
color: #c92100;
margin-left: .25rem;
}
}

View File

@ -49,13 +49,15 @@ export class CronScheduleComponent implements OnChanges {
this.scheduleType = this.originScheduleType;
if (this.scheduleType && this.scheduleType === SCHEDULE_TYPE.CUSTOM) {
this.cronString = this.oriCron;
this.dateInvalid = !cronRegex(this.cronString);
} else {
this.cronString = "";
this.dateInvalid = false;
}
}
inputInvalid() {
this.dateInvalid = cronRegex(this.cronString) ? false : true;
this.dateInvalid = !cronRegex(this.cronString);
}
blurInvalid() {
@ -71,11 +73,13 @@ export class CronScheduleComponent implements OnChanges {
}
save(): void {
if (this.dateInvalid && this.scheduleType === SCHEDULE_TYPE.CUSTOM) {
if (this.scheduleType === SCHEDULE_TYPE.CUSTOM && this.cronString === '') {
this.dateInvalid = true;
}
if (this.dateInvalid) {
return;
}
let scheduleTerm: string = "";
this.resetSchedule();
if (this.scheduleType && this.scheduleType === SCHEDULE_TYPE.NONE) {
scheduleTerm = "";
} else if (this.scheduleType && this.scheduleType === SCHEDULE_TYPE.HOURLY) {

View File

@ -345,22 +345,14 @@ export function getChanges(original: any, afterChange: any): { [key: string]: an
}
export function cronRegex(testValue: any): boolean {
const regSecond = "^($|#|\\w+\\s*=|(\\?|\\*|(?:[0-5]?\\d)(?:(?:-|\/|\\,)(?:[0-5]?\\d))?" +
"(?:,(?:[0-5]?\\d)(?:(?:-|\/|\\,)(?:[0-5]?\\d))?)*)\\s+";
const regMinute = "(\\?|\\*|(?:[0-5]?\\d)(?:(?:-|\/|\\,)(?:[0-5]?\\d))?(?:,(?:[0-5]?\\d)(?:(?:-|\/|\\,)(?:[0-5]?\\d))?)*)\\s+";
const regHour = "(\\?|\\*|(?:[01]?\\d|2[0-3])(?:(?:-|\/|\\,)(?:[01]?\\d|2[0-3]))?(?:,(?:[01]?\\d|2[0-3])" +
"(?:(?:-|\/|\\,)(?:[01]?\\d|2[0-3]))?)*)\\s+";
const regDay = "(\\?|\\*|(?:0?[1-9]|[12]\\d|3[01])(?:(?:-|\/|\\,)(?:0?[1-9]|[12]\\d|3[01]))?(?:,(?:0?[1-9]|[12]\\d|3[01])" +
"(?:(?:-|\/|\\,)(?:0?[1-9]|[12]\\d|3[01]))?)*)\\s+";
const regMonth = "(\\?|\\*|(?:[1-9]|1[012])(?:(?:-|\/|\\,)(?:[1-9]|1[012]))?(?:L|W)?(?:,(?:[1-9]|1[012])(?:(?:-|\/|\\,)" +
"(?:[1-9]|1[012]))?(?:L|W)?)*|\\?|\\*|(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(?:(?:-)" +
"(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?(?:,(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)" +
"(?:(?:-)(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?)*)\\s+";
const regWeek = "(\\?|\\*|(?:[0-6])(?:(?:-|\/|\\,|#)(?:[0-6]))?(?:L)?(?:,(?:[0-6])(?:(?:-|\/|\\,|#)" +
"(?:[0-6]))?(?:L)?)*|\\?|\\*|(?:MON|TUE|WED|THU|FRI|SAT|SUN)(?:(?:-)(?:MON|TUE|WED|THU|FRI|SAT|SUN))?" +
"(?:,(?:MON|TUE|WED|THU|FRI|SAT|SUN)(?:(?:-)(?:MON|TUE|WED|THU|FRI|SAT|SUN))?)*)(|\\s)+";
const regYear = "(\\?|\\*|(?:|\\d{4})(?:(?:-|\/|\\,)(?:|\\d{4}))?(?:,(?:|\\d{4})(?:(?:-|\/|\\,)(?:|\\d{4}))?)*))$";
const regSecond = "^((([0-9])*|(\\*))(\\-|\\,|\\/)?([0-9])*)*\\s+";
const regMinute = "((([0-9])*|(\\*))(\\-|\\,|\\/)?([0-9])*)*\\s+";
const regHour = "((([0-9])*|(\\*))(\\-|\\,|\\/)?([0-9])*)*\\s+";
const regDay = "((([0-9])*|(\\*|\\?))(\\-|\\,|\\/)?([0-9])*)*\\s+";
const regMonth = "((([0-9a-zA-Z])*|(\\*))(\\-|\\,|\\/)?([0-9a-zA-Z])*)*\\s+";
const regWeek = "(((([0-9a-zA-Z])*|(\\*|\\?))(\\-|\\,|\\/)?([0-9a-zA-Z])*))*(|\\s)+";
const regYear = "((([0-9])*|(\\*|\\?))(\\-|\\,|\\/)?([0-9])*)$";
const regEx = regSecond + regMinute + regHour + regDay + regMonth + regWeek + regYear;
let reg = new RegExp(regEx, "i");
return reg.test(testValue);
return reg.test(testValue.trim());
}