Improve input validator for copy-component (#17310)

Signed-off-by: AllForNothing <sshijun@vmware.com>
This commit is contained in:
Shijun Sun 2022-08-09 12:15:17 +08:00 committed by GitHub
parent 893cb0a655
commit 423647ea33
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 37 additions and 24 deletions

View File

@ -46,7 +46,8 @@
[disabled]=" [disabled]="
imageNameInput.projectName.invalid || imageNameInput.projectName.invalid ||
imageNameInput.repoName.invalid || imageNameInput.repoName.invalid ||
imageNameInput.noProjectInfo !== '' imageNameInput.notExist ||
imageNameInput.checkingName
" "
class="btn btn-primary" class="btn btn-primary"
(click)="onRetag()"> (click)="onRetag()">

View File

@ -849,7 +849,9 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
this.retagDialogOpened = true; this.retagDialogOpened = true;
this.imageNameInput.imageNameForm.reset({ this.imageNameInput.imageNameForm.reset({
repoName: this.repoName, repoName: this.repoName,
projectName: null,
}); });
this.imageNameInput.notExist = false;
this.retagSrcImage = this.retagSrcImage =
this.repoName + ':' + this.selectedRow[0].digest; this.repoName + ':' + this.selectedRow[0].digest;
} }

View File

@ -9,7 +9,9 @@
<div <div
class="clr-control-container" class="clr-control-container"
[class.clr-error]=" [class.clr-error]="
noProjectInfo && (projectName.dirty || projectName.touched) (projectName.invalid &&
(projectName.dirty || projectName.touched)) ||
notExist
"> ">
<div class="clr-input-wrapper"> <div class="clr-input-wrapper">
<input <input
@ -22,6 +24,9 @@
<clr-icon <clr-icon
class="clr-validate-icon" class="clr-validate-icon"
shape="exclamation-circle"></clr-icon> shape="exclamation-circle"></clr-icon>
<span
class="spinner spinner-inline"
[hidden]="!checkingName"></span>
<div <div
class="selectBox" class="selectBox"
[style.display]=" [style.display]="
@ -38,10 +43,17 @@
</div> </div>
<clr-control-error <clr-control-error
*ngIf=" *ngIf="
noProjectInfo && (projectName.dirty || projectName.touched) (projectName.invalid &&
(projectName.dirty || projectName.touched)) ||
notExist
" "
class="tooltip-content"> class="tooltip-content">
{{ noProjectInfo | translate }} <ng-container *ngIf="projectName.invalid">
{{ 'PROJECT.NAME_TOOLTIP' | translate }}
</ng-container>
<ng-container *ngIf="notExist">
{{ 'REPLICATION.NO_PROJECT_INFO' | translate }}
</ng-container>
</clr-control-error> </clr-control-error>
</div> </div>
</div> </div>

View File

@ -1,6 +1,6 @@
import { Component, OnDestroy, OnInit } from '@angular/core'; import { Component, OnDestroy, OnInit } from '@angular/core';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { debounceTime, switchMap } from 'rxjs/operators'; import { debounceTime, finalize, switchMap } from 'rxjs/operators';
import { import {
AbstractControl, AbstractControl,
FormBuilder, FormBuilder,
@ -17,10 +17,11 @@ import { Project } from 'ng-swagger-gen/models/project';
styleUrls: ['./image-name-input.component.scss'], styleUrls: ['./image-name-input.component.scss'],
}) })
export class ImageNameInputComponent implements OnInit, OnDestroy { export class ImageNameInputComponent implements OnInit, OnDestroy {
noProjectInfo = '';
selectedProjectList: Project[] = []; selectedProjectList: Project[] = [];
proNameChecker: Subject<string> = new Subject<string>(); proNameChecker: Subject<string> = new Subject<string>();
imageNameForm: FormGroup; imageNameForm: FormGroup;
notExist: boolean = false;
checkingName: boolean = false;
public project: string; public project: string;
public repo: string; public repo: string;
public tag: string; public tag: string;
@ -57,13 +58,16 @@ export class ImageNameInputComponent implements OnInit, OnDestroy {
.pipe(debounceTime(200)) .pipe(debounceTime(200))
.pipe( .pipe(
switchMap(name => { switchMap(name => {
this.noProjectInfo = ''; this.notExist = false;
this.checkingName = true;
this.selectedProjectList = []; this.selectedProjectList = [];
return this.proService.listProjects({ return this.proService
name: name, .listProjects({
page: 1, name: name,
pageSize: 10, page: 1,
}); pageSize: 10,
})
.pipe(finalize(() => (this.checkingName = false)));
}) })
) )
.subscribe( .subscribe(
@ -76,18 +80,14 @@ export class ImageNameInputComponent implements OnInit, OnDestroy {
data.name === data.name ===
this.imageNameForm.controls['projectName'].value this.imageNameForm.controls['projectName'].value
); );
if (!exist) { this.notExist = !exist;
this.noProjectInfo = 'REPLICATION.NO_PROJECT_INFO';
} else {
this.noProjectInfo = '';
}
} else { } else {
this.noProjectInfo = 'REPLICATION.NO_PROJECT_INFO'; this.notExist = true;
} }
}, },
(error: any) => { (error: any) => {
this.errorHandler.error(error); this.errorHandler.error(error);
this.noProjectInfo = 'REPLICATION.NO_PROJECT_INFO'; this.notExist = true;
} }
); );
} }
@ -96,8 +96,6 @@ export class ImageNameInputComponent implements OnInit, OnDestroy {
let cont = this.imageNameForm.controls['projectName']; let cont = this.imageNameForm.controls['projectName'];
if (cont && cont.valid) { if (cont && cont.valid) {
this.proNameChecker.next(cont.value); this.proNameChecker.next(cont.value);
} else {
this.noProjectInfo = 'PROJECT.NAME_TOOLTIP';
} }
} }
@ -126,6 +124,6 @@ export class ImageNameInputComponent implements OnInit, OnDestroy {
selectedProjectName(projectName: string) { selectedProjectName(projectName: string) {
this.imageNameForm.controls['projectName'].setValue(projectName); this.imageNameForm.controls['projectName'].setValue(projectName);
this.selectedProjectList = []; this.selectedProjectList = [];
this.noProjectInfo = ''; this.notExist = false;
} }
} }

View File

@ -601,7 +601,7 @@
"JOB_PLACEHOLDER": "We couldn't find any replication jobs!", "JOB_PLACEHOLDER": "We couldn't find any replication jobs!",
"NO_ENDPOINT_INFO": "Please add an endpoint first", "NO_ENDPOINT_INFO": "Please add an endpoint first",
"NO_LABEL_INFO": "Please add a label first", "NO_LABEL_INFO": "Please add a label first",
"NO_PROJECT_INFO": "This project is not exist", "NO_PROJECT_INFO": "This project does not exist",
"SOURCE_RESOURCE_FILTER": "Source resource filter", "SOURCE_RESOURCE_FILTER": "Source resource filter",
"SCHEDULED": "Scheduled", "SCHEDULED": "Scheduled",
"MANUAL": "Manual", "MANUAL": "Manual",

View File

@ -603,7 +603,7 @@
"JOB_PLACEHOLDER": "We couldn't find any replication jobs!", "JOB_PLACEHOLDER": "We couldn't find any replication jobs!",
"NO_ENDPOINT_INFO": "Please add an endpoint first", "NO_ENDPOINT_INFO": "Please add an endpoint first",
"NO_LABEL_INFO": "Please add a label first", "NO_LABEL_INFO": "Please add a label first",
"NO_PROJECT_INFO": "This project is not exist", "NO_PROJECT_INFO": "This project does not exist",
"SOURCE_RESOURCE_FILTER": "Source resource filter", "SOURCE_RESOURCE_FILTER": "Source resource filter",
"SCHEDULED": "Scheduled", "SCHEDULED": "Scheduled",
"MANUAL": "Manual", "MANUAL": "Manual",