mirror of
https://github.com/goharbor/harbor
synced 2025-04-22 19:10:40 +00:00
Improve input validator for copy-component (#17310)
Signed-off-by: AllForNothing <sshijun@vmware.com>
This commit is contained in:
parent
893cb0a655
commit
423647ea33
@ -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()">
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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",
|
||||||
|
@ -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",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user