mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-27 04:35:16 +01:00
Update for date-validators.
This commit is contained in:
parent
45ef8adca2
commit
b26902448d
@ -179,11 +179,6 @@ export class CreateEditRuleComponent implements OnInit, AfterViewChecked {
|
||||
openCreateEditRule(editable: boolean, ruleId?: number | string): void {
|
||||
this.createEditRuleOpened = true;
|
||||
this.createEditRule = this.initCreateEditRule;
|
||||
|
||||
if(!this.createEditRule) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.editable = editable;
|
||||
|
||||
this.isCreateEndpoint = false;
|
||||
@ -200,6 +195,7 @@ export class CreateEditRuleComponent implements OnInit, AfterViewChecked {
|
||||
toPromise<ReplicationRule>(this.replicationService
|
||||
.getReplicationRule(ruleId))
|
||||
.then(rule=>{
|
||||
if(rule) {
|
||||
this.createEditRule.ruleId = ruleId;
|
||||
this.createEditRule.name = rule.name;
|
||||
this.createEditRule.description = rule.description;
|
||||
@ -210,7 +206,7 @@ export class CreateEditRuleComponent implements OnInit, AfterViewChecked {
|
||||
this.initVal.description = this.createEditRule.description;
|
||||
this.initVal.enable = this.createEditRule.enable;
|
||||
}
|
||||
)
|
||||
}).catch(err=>this.errorHandler.error(err));
|
||||
} else {
|
||||
this.actionType = ActionType.ADD_NEW;
|
||||
this.translateService.get('REPLICATION.ADD_POLICY').subscribe(res=>this.modalTitle=res);
|
||||
@ -243,7 +239,7 @@ export class CreateEditRuleComponent implements OnInit, AfterViewChecked {
|
||||
getRuleByForm(): ReplicationRule {
|
||||
let rule: ReplicationRule = this.initReplicationRule;
|
||||
rule.project_id = this.projectId;
|
||||
rule.id = this.createEditRule.endpointId;
|
||||
rule.id = this.createEditRule.ruleId;
|
||||
rule.name = this.createEditRule.name;
|
||||
rule.description = this.createEditRule.description;
|
||||
rule.enabled = this.createEditRule.enable ? 1 : 0;
|
||||
|
@ -0,0 +1,50 @@
|
||||
// Copyright (c) 2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import { Directive, OnChanges, Input, SimpleChanges } from '@angular/core';
|
||||
import { NG_VALIDATORS, Validator, Validators, ValidatorFn, AbstractControl } from '@angular/forms';
|
||||
|
||||
@Directive({
|
||||
selector: '[dateValidator]',
|
||||
providers: [{provide: NG_VALIDATORS, useExisting: DateValidatorDirective, multi: true}]
|
||||
})
|
||||
export class DateValidatorDirective implements Validator, OnChanges {
|
||||
@Input() dateValidator: string;
|
||||
private valFn = Validators.nullValidator;
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
const change = changes['dateValidator'];
|
||||
if (change) {
|
||||
this.valFn = dateValidator();
|
||||
} else {
|
||||
this.valFn = Validators.nullValidator;
|
||||
}
|
||||
}
|
||||
validate(control: AbstractControl): {[key: string]: any} {
|
||||
return this.valFn(control) || Validators.nullValidator;
|
||||
}
|
||||
}
|
||||
|
||||
export function dateValidator(): ValidatorFn {
|
||||
return (control: AbstractControl): {[key: string]: any} => {
|
||||
let controlValue = control.value;
|
||||
let valid = true;
|
||||
if(controlValue) {
|
||||
const regYMD=/^(19|20)\d\d([- /.])(0[1-9]|1[012])\2(0[1-9]|[12][0-9]|3[01])$/g;
|
||||
const regDMY=/^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$/g;
|
||||
valid = (regYMD.test(controlValue) || regDMY.test(controlValue));
|
||||
}
|
||||
return valid ? Validators.nullValidator : {'dateValidator': { value: controlValue }};
|
||||
};
|
||||
}
|
||||
|
@ -0,0 +1,9 @@
|
||||
export const DATETIME_PICKER_TEMPLATE: string = `
|
||||
<clr-icon shape="date"></clr-icon>
|
||||
<label aria-haspopup="true" role="tooltip" [class.invalid]="dateInvalid" class="tooltip tooltip-validation tooltip-sm">
|
||||
<input type="date" #searchTime="ngModel" [(ngModel)]="dateInput" name="searchTime" placeholder="dd/mm/yyyy" dateValidator (change)="doSearch()">
|
||||
<span *ngIf="dateInvalid" class="tooltip-content">
|
||||
{{'AUDIT_LOG.INVALID_DATE' | translate }}
|
||||
</span>
|
||||
</label>
|
||||
`;
|
@ -0,0 +1,43 @@
|
||||
import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core';
|
||||
import { NgModel } from '@angular/forms';
|
||||
|
||||
import { DATETIME_PICKER_TEMPLATE } from './datetime-picker.component.html';
|
||||
|
||||
@Component({
|
||||
selector: 'hbr-datetime',
|
||||
template: DATETIME_PICKER_TEMPLATE
|
||||
})
|
||||
export class DatePickerComponent {
|
||||
|
||||
@Input() dateInput: string;
|
||||
@Input() oneDayOffset: boolean;
|
||||
|
||||
@ViewChild('searchTime')
|
||||
searchTime: NgModel;
|
||||
|
||||
@Output() search = new EventEmitter<string>();
|
||||
|
||||
get dateInvalid(): boolean {
|
||||
return (this.searchTime.errors && this.searchTime.errors.dateValidator && (this.searchTime.dirty || this.searchTime.touched)) || false;
|
||||
}
|
||||
|
||||
convertDate(strDate: string): string {
|
||||
if(/^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$/.test(strDate)) {
|
||||
let parts = strDate.split(/[-\/]/);
|
||||
strDate = parts[2] /*Year*/ + '-' +parts[1] /*Month*/ + '-' + parts[0] /*Date*/;
|
||||
}
|
||||
return strDate;
|
||||
}
|
||||
|
||||
doSearch() {
|
||||
let searchTerm: string = '';
|
||||
if(this.searchTime.valid && this.dateInput) {
|
||||
let timestamp: number = new Date(this.convertDate(this.searchTime.value)).getTime() / 1000;
|
||||
if(this.oneDayOffset) {
|
||||
timestamp += 3600 * 24;
|
||||
}
|
||||
searchTerm = timestamp.toString();
|
||||
}
|
||||
this.search.emit(searchTerm);
|
||||
}
|
||||
}
|
8
src/ui_ng/lib/src/datetime-picker/index.ts
Normal file
8
src/ui_ng/lib/src/datetime-picker/index.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { Type } from '@angular/core';
|
||||
|
||||
import { DatePickerComponent } from './datetime-picker.component';
|
||||
import { DateValidatorDirective } from './date-validator.directive';
|
||||
export const DATETIME_PICKER_DIRECTIVES: Type<any>[] = [
|
||||
DatePickerComponent,
|
||||
DateValidatorDirective
|
||||
];
|
@ -18,6 +18,7 @@ import { SERVICE_CONFIG, IServiceConfig } from './service.config';
|
||||
|
||||
import { CONFIRMATION_DIALOG_DIRECTIVES } from './confirmation-dialog/index';
|
||||
import { INLINE_ALERT_DIRECTIVES } from './inline-alert/index';
|
||||
import { DATETIME_PICKER_DIRECTIVES } from './datetime-picker/index';
|
||||
|
||||
import {
|
||||
AccessLogService,
|
||||
@ -137,7 +138,8 @@ export function initConfig(translateService: TranslateService, config: IServiceC
|
||||
REPLICATION_DIRECTIVES,
|
||||
LIST_REPLICATION_RULE_DIRECTIVES,
|
||||
LIST_REPLICATION_JOB_DIRECTIVES,
|
||||
CREATE_EDIT_RULE_DIRECTIVES
|
||||
CREATE_EDIT_RULE_DIRECTIVES,
|
||||
DATETIME_PICKER_DIRECTIVES
|
||||
],
|
||||
exports: [
|
||||
LOG_DIRECTIVES,
|
||||
@ -152,7 +154,8 @@ export function initConfig(translateService: TranslateService, config: IServiceC
|
||||
REPLICATION_DIRECTIVES,
|
||||
LIST_REPLICATION_RULE_DIRECTIVES,
|
||||
LIST_REPLICATION_JOB_DIRECTIVES,
|
||||
CREATE_EDIT_RULE_DIRECTIVES
|
||||
CREATE_EDIT_RULE_DIRECTIVES,
|
||||
DATETIME_PICKER_DIRECTIVES
|
||||
],
|
||||
providers: []
|
||||
})
|
||||
|
@ -40,20 +40,8 @@ export const REPLICATION_TEMPLATE: string = `
|
||||
</select>
|
||||
</div>
|
||||
<div class="flex-items-xs-middle">
|
||||
<clr-icon shape="date"></clr-icon>
|
||||
<label for="fromDateInput" aria-haspopup="true" role="tooltip" [class.invalid]="fromTimeInvalid" class="tooltip tooltip-validation invalid tooltip-sm">
|
||||
<input id="fromDateInput" type="date" #fromTime="ngModel" name="from" [(ngModel)]="search.startTime" dateValidator placeholder="dd/mm/yyyy" (change)="doJobSearchByStartTime(fromTime.value)">
|
||||
<span *ngIf="fromTimeInvalid" class="tooltip-content">
|
||||
{{'AUDIT_LOG.INVALID_DATE' | translate }}
|
||||
</span>
|
||||
</label>
|
||||
<clr-icon shape="date"></clr-icon>
|
||||
<label for="toDateInput" aria-haspopup="true" role="tooltip" [class.invalid]="toTimeInvalid" class="tooltip tooltip-validation invalid tooltip-sm">
|
||||
<input id="toDateInput" type="date" #toTime="ngModel" name="to" [(ngModel)]="search.endTime" dateValidator placeholder="dd/mm/yyyy" (change)="doJobSearchByEndTime(toTime.value)">
|
||||
<span *ngIf="toTimeInvalid" class="tooltip-content">
|
||||
{{'AUDIT_LOG.INVALID_DATE' | translate }}
|
||||
</span>
|
||||
</label>
|
||||
<hbr-datetime [dateInput]="search.startTime" (search)="doJobSearchByStartTime($event)"></hbr-datetime>
|
||||
<hbr-datetime [dateInput]="search.endTime" [oneDayOffset]="true" (search)="doJobSearchByEndTime($event)"></hbr-datetime>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -99,17 +99,6 @@ export class ReplicationComponent implements OnInit {
|
||||
@ViewChild(CreateEditRuleComponent)
|
||||
createEditPolicyComponent: CreateEditRuleComponent;
|
||||
|
||||
@ViewChild('fromTime') fromTimeInput: NgModel;
|
||||
@ViewChild('toTime') toTimeInput: NgModel;
|
||||
|
||||
get fromTimeInvalid(): boolean {
|
||||
return (this.fromTimeInput.errors && this.fromTimeInput.errors.dateValidator && (this.fromTimeInput.dirty || this.fromTimeInput.touched)) || false;
|
||||
}
|
||||
|
||||
get toTimeInvalid(): boolean {
|
||||
return (this.toTimeInput.errors && this.toTimeInput.errors.dateValidator && (this.toTimeInput.dirty || this.toTimeInput.touched)) || false;
|
||||
}
|
||||
|
||||
constructor(
|
||||
private errorHandler: ErrorHandler,
|
||||
private replicationService: ReplicationService,
|
||||
@ -122,11 +111,6 @@ export class ReplicationComponent implements OnInit {
|
||||
this.currentJobStatus = this.jobStatus[0];
|
||||
this.currentJobSearchOption = 0;
|
||||
this.retrievePolicies();
|
||||
|
||||
// let isCreate = this.route.snapshot.parent.queryParams['is_create'];
|
||||
// if (isCreate && <boolean>isCreate) {
|
||||
// this.openModal();
|
||||
// }
|
||||
}
|
||||
|
||||
retrievePolicies(): void {
|
||||
@ -181,21 +165,17 @@ export class ReplicationComponent implements OnInit {
|
||||
this.jobsTotalPage = Math.ceil(this.jobsTotalRecordCount / this.search.pageSize);
|
||||
this.changedJobs = response.json();
|
||||
this.jobs = this.changedJobs;
|
||||
for(let i = 0; i < this.jobs.length; i++) {
|
||||
let j = this.jobs[i];
|
||||
if(j.status == 'retrying' || j.status == 'error') {
|
||||
this.jobs.forEach(j=>{
|
||||
if(j.status === 'retrying' || j.status === 'error') {
|
||||
this.translateService.get('REPLICATION.FOUND_ERROR_IN_JOBS')
|
||||
.subscribe(res=>this.errorHandler.error(res));
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
error=>this.errorHandler.error(error)
|
||||
);
|
||||
})
|
||||
}).catch(error=>this.errorHandler.error(error));
|
||||
}
|
||||
|
||||
selectOneRule(rule: ReplicationRule) {
|
||||
if(rule) {
|
||||
if (rule) {
|
||||
this.search.ruleId = rule.id || '';
|
||||
this.search.repoName = '';
|
||||
this.search.status = '';
|
||||
@ -258,30 +238,13 @@ export class ReplicationComponent implements OnInit {
|
||||
(option === 1) ? this.currentJobSearchOption = 0 : this.currentJobSearchOption = 1;
|
||||
}
|
||||
|
||||
convertDate(strDate: string): string {
|
||||
if(/^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$/.test(strDate)) {
|
||||
let parts = strDate.split(/[-\/]/);
|
||||
strDate = parts[2] /*Year*/ + '-' +parts[1] /*Month*/ + '-' + parts[0] /*Date*/;
|
||||
}
|
||||
return strDate;
|
||||
}
|
||||
|
||||
doJobSearchByStartTime(strDate: string) {
|
||||
this.search.startTimestamp = '';
|
||||
if(this.fromTimeInput.valid && strDate) {
|
||||
strDate = this.convertDate(strDate);
|
||||
this.search.startTimestamp = new Date(strDate).getTime() / 1000 + '';
|
||||
}
|
||||
doJobSearchByStartTime(fromTimestamp: string) {
|
||||
this.search.startTimestamp = fromTimestamp;
|
||||
this.fetchReplicationJobs();
|
||||
}
|
||||
|
||||
doJobSearchByEndTime(strDate: string) {
|
||||
this.search.endTimestamp = '';
|
||||
if(this.toTimeInput.valid && strDate) {
|
||||
strDate = this.convertDate(strDate);
|
||||
let oneDayOffset = 3600 * 24;
|
||||
this.search.endTimestamp = (new Date(strDate).getTime() / 1000 + oneDayOffset) + '';
|
||||
}
|
||||
doJobSearchByEndTime(toTimestamp: string) {
|
||||
this.search.endTimestamp = toTimestamp;
|
||||
this.fetchReplicationJobs();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user