mirror of
https://github.com/goharbor/harbor.git
synced 2025-01-15 20:22:01 +01:00
Improve copy-artifact component (#16628)
Signed-off-by: AllForNothing <sshijun@vmware.com>
This commit is contained in:
parent
37132786cf
commit
df54e1e13c
@ -716,7 +716,7 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
|||||||
retag() {
|
retag() {
|
||||||
if (this.selectedRow && this.selectedRow.length && !this.depth) {
|
if (this.selectedRow && this.selectedRow.length && !this.depth) {
|
||||||
this.retagDialogOpened = true;
|
this.retagDialogOpened = true;
|
||||||
this.imageNameInput.imageNameForm.reset();
|
this.imageNameInput.imageNameForm.reset({repoName: this.repoName});
|
||||||
this.retagSrcImage = this.repoName + ":" + this.selectedRow[0].digest;
|
this.retagSrcImage = this.repoName + ":" + this.selectedRow[0].digest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
(keyup)='validateProjectName()'
|
(keyup)='validateProjectName()'
|
||||||
formControlName="projectName" autocomplete="off" />
|
formControlName="projectName" autocomplete="off" />
|
||||||
<clr-icon class="clr-validate-icon" shape="exclamation-circle"></clr-icon>
|
<clr-icon class="clr-validate-icon" shape="exclamation-circle"></clr-icon>
|
||||||
<div class="select-box" [style.display]="selectedProjectList.length ? 'block' : 'none'">
|
<div class="selectBox" [style.display]="selectedProjectList.length ? 'block' : 'none'">
|
||||||
<ul>
|
<ul>
|
||||||
<li *ngFor="let project of selectedProjectList"
|
<li *ngFor="let project of selectedProjectList"
|
||||||
(click)="selectedProjectName(project?.name)">{{project?.name}}</li>
|
(click)="selectedProjectName(project?.name)">{{project?.name}}</li>
|
||||||
|
@ -1,34 +1,28 @@
|
|||||||
|
.selectBox{
|
||||||
.select-box {
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
width: 278px;
|
||||||
height: auto;
|
height: auto;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
border: 1px solid rgba(0, 0, 0, .15);
|
border: 1px solid rgba(0,0,0,.15);
|
||||||
border-right-width: 2px;
|
border-right-width: 2px;
|
||||||
border-bottom-width: 2px;
|
border-bottom-width: 2px;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
|
box-shadow: 0 5px 10px rgba(0,0,0,.2);
|
||||||
z-index:1;
|
z-index: 100;
|
||||||
width:100%;
|
}
|
||||||
|
.selectBox ul li{
|
||||||
ul {
|
|
||||||
li {
|
|
||||||
list-style: none;
|
list-style: none;
|
||||||
padding: 3px 20px;
|
padding: 3px 20px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
}
|
||||||
&:hover {
|
.selectBox ul li:hover{
|
||||||
color: #262626;
|
color: #262626;
|
||||||
background-image: linear-gradient(180deg, #f5f5f5 0, #e8e8e8);
|
background-image: linear-gradient(180deg,#f5f5f5 0,#e8e8e8);
|
||||||
background-repeat: repeat-x;
|
background-repeat: repeat-x;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.clr-input-wrapper {
|
.clr-input-wrapper {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: relative;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.wrap-label {
|
.wrap-label {
|
||||||
@ -42,5 +36,5 @@
|
|||||||
width: 60%;
|
width: 60%;
|
||||||
}
|
}
|
||||||
.w-90 {
|
.w-90 {
|
||||||
width: 90%;
|
width: 278px;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
||||||
import { ImageNameInputComponent } from "./image-name-input.component";
|
import { ImageNameInputComponent } from "./image-name-input.component";
|
||||||
import { ProjectDefaultService, ProjectService } from "../../services";
|
|
||||||
import { Project } from "../../../base/project/project-config/project-policy-config/project";
|
|
||||||
import { of } from "rxjs";
|
import { of } from "rxjs";
|
||||||
import { HttpResponse } from "@angular/common/http";
|
|
||||||
import { SharedTestingModule } from "../../shared.module";
|
import { SharedTestingModule } from "../../shared.module";
|
||||||
|
import { ProjectService } from "ng-swagger-gen/services/project.service";
|
||||||
|
import { Project } from "ng-swagger-gen/models/project";
|
||||||
|
|
||||||
describe("ImageNameInputComponent (inline template)", () => {
|
describe("ImageNameInputComponent (inline template)", () => {
|
||||||
let comp: ImageNameInputComponent;
|
let comp: ImageNameInputComponent;
|
||||||
@ -31,9 +30,6 @@ describe("ImageNameInputComponent (inline template)", () => {
|
|||||||
declarations: [
|
declarations: [
|
||||||
ImageNameInputComponent
|
ImageNameInputComponent
|
||||||
],
|
],
|
||||||
providers: [
|
|
||||||
{ provide: ProjectService, useClass: ProjectDefaultService }
|
|
||||||
]
|
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -43,7 +39,7 @@ describe("ImageNameInputComponent (inline template)", () => {
|
|||||||
|
|
||||||
let projectService: ProjectService;
|
let projectService: ProjectService;
|
||||||
projectService = fixture.debugElement.injector.get(ProjectService);
|
projectService = fixture.debugElement.injector.get(ProjectService);
|
||||||
spy = spyOn(projectService, "listProjects").and.returnValues(of(new HttpResponse({ body: mockProjects })));
|
spy = spyOn(projectService, "listProjects").and.returnValues(of(mockProjects));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should load data", () => {
|
it("should load data", () => {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { Component, OnDestroy, OnInit } from "@angular/core";
|
import { Component, OnDestroy, OnInit } from "@angular/core";
|
||||||
import { Project } from "../../../base/project/project-config/project-policy-config/project";
|
|
||||||
import { Subject } from "rxjs";
|
import { Subject } from "rxjs";
|
||||||
import { debounceTime, switchMap } from "rxjs/operators";
|
import { debounceTime, switchMap } from "rxjs/operators";
|
||||||
import { ProjectService } from "../../services";
|
|
||||||
import { AbstractControl, FormBuilder, FormGroup, Validators } from "@angular/forms";
|
import { AbstractControl, FormBuilder, FormGroup, Validators } from "@angular/forms";
|
||||||
import { ErrorHandler } from "../../units/error-handler";
|
import { ErrorHandler } from "../../units/error-handler";
|
||||||
|
import { ProjectService } from "ng-swagger-gen/services/project.service";
|
||||||
|
import { Project } from "ng-swagger-gen/models/project";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "hbr-image-name-input",
|
selector: "hbr-image-name-input",
|
||||||
@ -46,13 +46,17 @@ export class ImageNameInputComponent implements OnInit, OnDestroy {
|
|||||||
switchMap(name => {
|
switchMap(name => {
|
||||||
this.noProjectInfo = "";
|
this.noProjectInfo = "";
|
||||||
this.selectedProjectList = [];
|
this.selectedProjectList = [];
|
||||||
return this.proService.listProjects(name, undefined);
|
return this.proService.listProjects({
|
||||||
|
name: name,
|
||||||
|
page: 1,
|
||||||
|
pageSize: 10
|
||||||
|
});
|
||||||
})
|
})
|
||||||
).subscribe(response => {
|
).subscribe(response => {
|
||||||
if (response.body) {
|
if (response) {
|
||||||
this.selectedProjectList = response.body.slice(0, 10);
|
this.selectedProjectList = response;
|
||||||
// if input project name exist in the project list
|
// if input project name exist in the project list
|
||||||
let exist = response.body.find((data: any) => data.name === this.imageNameForm.controls["projectName"].value);
|
let exist = response.find((data: Project) => data.name === this.imageNameForm.controls["projectName"].value);
|
||||||
if (!exist) {
|
if (!exist) {
|
||||||
this.noProjectInfo = "REPLICATION.NO_PROJECT_INFO";
|
this.noProjectInfo = "REPLICATION.NO_PROJECT_INFO";
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user