mirror of
https://github.com/goharbor/harbor.git
synced 2024-09-29 22:07:32 +02:00
Add limitation to artifact tags
Signed-off-by: AllForNothing <sshijun@vmware.com>
This commit is contained in:
parent
be4e6a5985
commit
4390b2f259
@ -192,7 +192,6 @@
|
|||||||
</clr-dg-cell>
|
</clr-dg-cell>
|
||||||
<clr-dg-cell class="w-rem-4">
|
<clr-dg-cell class="w-rem-4">
|
||||||
<div *ngIf="artifact.tags" class="truncated width-p-100">
|
<div *ngIf="artifact.tags" class="truncated width-p-100">
|
||||||
|
|
||||||
<clr-tooltip class="width-p-100">
|
<clr-tooltip class="width-p-100">
|
||||||
<div clrTooltipTrigger class="level-border">
|
<div clrTooltipTrigger class="level-border">
|
||||||
<div>
|
<div>
|
||||||
@ -202,7 +201,7 @@
|
|||||||
</span>
|
</span>
|
||||||
<span class="eslip"
|
<span class="eslip"
|
||||||
*ngIf="artifact?.tags?.length>1">...</span>
|
*ngIf="artifact?.tags?.length>1">...</span>
|
||||||
<span *ngIf="artifact?.tags?.length>1" > ({{artifact?.tags?.length}})</span>
|
<span *ngIf="artifact?.tags?.length>1" > ({{artifact?.tagNumber}})</span>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -222,6 +221,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="tag-tbody">
|
<tbody class="tag-tbody">
|
||||||
|
<!--display less than 9 tags(too many tags will make UI stuck)-->
|
||||||
<tr class="tag-tr" *ngFor="let tag of artifact.tags">
|
<tr class="tag-tr" *ngFor="let tag of artifact.tags">
|
||||||
<td class="left tag-body-color">{{tag.name}}</td>
|
<td class="left tag-body-color">{{tag.name}}</td>
|
||||||
<td *ngIf="withNotary" class="left tag-body-color" [ngSwitch]="tag.signed">
|
<td *ngIf="withNotary" class="left tag-body-color" [ngSwitch]="tag.signed">
|
||||||
@ -237,6 +237,7 @@
|
|||||||
<td class="left tag-body-color">{{tag.pull_time === availableTime ? '':(tag.pull_time | date: 'short')}}</td>
|
<td class="left tag-body-color">{{tag.pull_time === availableTime ? '':(tag.pull_time | date: 'short')}}</td>
|
||||||
<td class="left tag-body-color">{{tag.push_time | date: 'short'}}</td>
|
<td class="left tag-body-color">{{tag.push_time | date: 'short'}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr *ngIf="artifact?.tagNumber > 8">...</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</clr-tooltip-content>
|
</clr-tooltip-content>
|
||||||
|
@ -58,14 +58,13 @@ import {
|
|||||||
ArtifactFront as Artifact,
|
ArtifactFront as Artifact,
|
||||||
mutipleFilter,
|
mutipleFilter,
|
||||||
artifactPullCommands,
|
artifactPullCommands,
|
||||||
artifactDefault
|
artifactDefault, ArtifactFront
|
||||||
} from '../../../artifact/artifact';
|
} from '../../../artifact/artifact';
|
||||||
import { Project } from "../../../../project";
|
import { Project } from "../../../../project";
|
||||||
import { ArtifactService as NewArtifactService } from "../../../../../../../ng-swagger-gen/services/artifact.service";
|
import { ArtifactService as NewArtifactService } from "../../../../../../../ng-swagger-gen/services/artifact.service";
|
||||||
import { ADDITIONS } from "../../../artifact/artifact-additions/models";
|
import { ADDITIONS } from "../../../artifact/artifact-additions/models";
|
||||||
import { Platform } from "../../../../../../../ng-swagger-gen/models/platform";
|
import { Platform } from "../../../../../../../ng-swagger-gen/models/platform";
|
||||||
import { IconService } from '../../../../../../../ng-swagger-gen/services/icon.service';
|
import { SafeUrl } from '@angular/platform-browser';
|
||||||
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
|
|
||||||
export interface LabelState {
|
export interface LabelState {
|
||||||
iconsShow: boolean;
|
iconsShow: boolean;
|
||||||
label: Label;
|
label: Label;
|
||||||
@ -91,7 +90,7 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
|||||||
@Input() registryUrl: string;
|
@Input() registryUrl: string;
|
||||||
@Input() withNotary: boolean;
|
@Input() withNotary: boolean;
|
||||||
@Input() withAdmiral: boolean;
|
@Input() withAdmiral: boolean;
|
||||||
artifactList: Artifact[] = [];
|
artifactList: ArtifactFront[] = [];
|
||||||
availableTime = AVAILABLE_TIME;
|
availableTime = AVAILABLE_TIME;
|
||||||
showTagManifestOpened: boolean;
|
showTagManifestOpened: boolean;
|
||||||
retagDialogOpened: boolean;
|
retagDialogOpened: boolean;
|
||||||
@ -342,8 +341,7 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
|||||||
withImmutableStatus: true,
|
withImmutableStatus: true,
|
||||||
withLabel: true,
|
withLabel: true,
|
||||||
withScanOverview: true,
|
withScanOverview: true,
|
||||||
withSignature: true,
|
withTag: false
|
||||||
withTag: true
|
|
||||||
};
|
};
|
||||||
this.newArtifactService.getArtifact(artifactParam).subscribe(
|
this.newArtifactService.getArtifact(artifactParam).subscribe(
|
||||||
res => {
|
res => {
|
||||||
@ -359,8 +357,7 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
|||||||
withImmutableStatus: true,
|
withImmutableStatus: true,
|
||||||
withLabel: true,
|
withLabel: true,
|
||||||
withScanOverview: true,
|
withScanOverview: true,
|
||||||
withSignature: true,
|
withTag: false
|
||||||
withTag: true
|
|
||||||
};
|
};
|
||||||
platFormAttr.push({platform: child.platform});
|
platFormAttr.push({platform: child.platform});
|
||||||
observableLists.push(this.newArtifactService.getArtifact(childParams));
|
observableLists.push(this.newArtifactService.getArtifact(childParams));
|
||||||
@ -374,6 +371,7 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
|||||||
artifact.platform = clone(platFormAttr[index].platform);
|
artifact.platform = clone(platFormAttr[index].platform);
|
||||||
});
|
});
|
||||||
this.getPullCommand(this.artifactList);
|
this.getPullCommand(this.artifactList);
|
||||||
|
this.getArtifactTagsAsync(this.artifactList);
|
||||||
this.getIconsFromBackEnd();
|
this.getIconsFromBackEnd();
|
||||||
}, error => {
|
}, error => {
|
||||||
this.errorHandlerService.error(error);
|
this.errorHandlerService.error(error);
|
||||||
@ -388,7 +386,7 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
|||||||
repositoryName: dbEncodeURIComponent(this.repoName),
|
repositoryName: dbEncodeURIComponent(this.repoName),
|
||||||
withLabel: true,
|
withLabel: true,
|
||||||
withScanOverview: true,
|
withScanOverview: true,
|
||||||
withTag: true
|
withTag: false
|
||||||
};
|
};
|
||||||
Object.assign(listArtifactParams, params);
|
Object.assign(listArtifactParams, params);
|
||||||
this.newArtifactService.listArtifactsResponse(listArtifactParams)
|
this.newArtifactService.listArtifactsResponse(listArtifactParams)
|
||||||
@ -404,6 +402,7 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
|||||||
this.artifactList = doSorting<Artifact>(this.artifactList, state);
|
this.artifactList = doSorting<Artifact>(this.artifactList, state);
|
||||||
|
|
||||||
this.getPullCommand(this.artifactList);
|
this.getPullCommand(this.artifactList);
|
||||||
|
this.getArtifactTagsAsync(this.artifactList);
|
||||||
this.getIconsFromBackEnd();
|
this.getIconsFromBackEnd();
|
||||||
}, error => {
|
}, error => {
|
||||||
// error
|
// error
|
||||||
@ -1012,4 +1011,31 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
|||||||
getIcon(icon: string): SafeUrl {
|
getIcon(icon: string): SafeUrl {
|
||||||
return this.artifactService.getIcon(icon);
|
return this.artifactService.getIcon(icon);
|
||||||
}
|
}
|
||||||
|
// get Tags and display less than 9 tags(too many tags will make UI stuck)
|
||||||
|
getArtifactTagsAsync(artifacts: ArtifactFront[]) {
|
||||||
|
if (artifacts && artifacts.length) {
|
||||||
|
artifacts.forEach(item => {
|
||||||
|
const listTagParams: NewArtifactService.ListTagsParams = {
|
||||||
|
projectName: this.projectName,
|
||||||
|
repositoryName: dbEncodeURIComponent(this.repoName),
|
||||||
|
reference: item.digest,
|
||||||
|
withSignature: true,
|
||||||
|
withImmutableStatus: true,
|
||||||
|
page: 1,
|
||||||
|
pageSize: 8
|
||||||
|
};
|
||||||
|
this.newArtifactService.listTagsResponse(listTagParams).subscribe(
|
||||||
|
res => {
|
||||||
|
if (res.headers) {
|
||||||
|
let xHeader: string = res.headers.get("x-total-count");
|
||||||
|
if (xHeader) {
|
||||||
|
item.tagNumber = Number.parseInt(xHeader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
item.tags = res.body;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,21 +86,21 @@ export class ArtifactTagComponent implements OnInit, OnDestroy {
|
|||||||
.subscribe(systemInfo => this.systemInfo = systemInfo, error => this.errorHandlerService.error(error));
|
.subscribe(systemInfo => this.systemInfo = systemInfo, error => this.errorHandlerService.error(error));
|
||||||
}
|
}
|
||||||
checkTagName(name) {
|
checkTagName(name) {
|
||||||
let listArtifactParams: ArtifactService.ListArtifactsParams = {
|
const listTagParams: ArtifactService.ListTagsParams = {
|
||||||
projectName: this.projectName,
|
projectName: this.projectName,
|
||||||
repositoryName: dbEncodeURIComponent(this.repositoryName),
|
repositoryName: dbEncodeURIComponent(this.repositoryName),
|
||||||
withLabel: true,
|
reference: this.artifactDetails.digest,
|
||||||
withScanOverview: true,
|
withSignature: true,
|
||||||
withTag: true,
|
withImmutableStatus: true,
|
||||||
q: encodeURIComponent(`tags=${name}`)
|
q: encodeURIComponent(`name=${name}`)
|
||||||
};
|
};
|
||||||
return this.artifactService.listArtifacts(listArtifactParams)
|
return this.artifactService.listTags(listTagParams)
|
||||||
.pipe(finalize(() => this.tagNameCheckOnGoing = false));
|
.pipe(finalize(() => this.tagNameCheckOnGoing = false));
|
||||||
}
|
}
|
||||||
invalidCreateTag() {
|
invalidCreateTag() {
|
||||||
if (!this.tagNameCheckSub) {
|
if (!this.tagNameCheckSub) {
|
||||||
this.tagNameCheckSub = this.tagNameChecker
|
this.tagNameCheckSub = this.tagNameChecker
|
||||||
.pipe(debounceTime(200))
|
.pipe(debounceTime(500))
|
||||||
.pipe(distinctUntilChanged())
|
.pipe(distinctUntilChanged())
|
||||||
.pipe(switchMap(name => {
|
.pipe(switchMap(name => {
|
||||||
this.tagNameCheckOnGoing = true;
|
this.tagNameCheckOnGoing = true;
|
||||||
|
@ -6,6 +6,7 @@ export interface ArtifactFront extends Artifact {
|
|||||||
showImage?: string;
|
showImage?: string;
|
||||||
pullCommand?: string;
|
pullCommand?: string;
|
||||||
annotationsArray?: Array<{[key: string]: any}>;
|
annotationsArray?: Array<{[key: string]: any}>;
|
||||||
|
tagNumber?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const mutipleFilter = [
|
export const mutipleFilter = [
|
||||||
|
@ -44,7 +44,7 @@ export class ArtifactDetailRoutingResolverService implements Resolve<Artifact> {
|
|||||||
projectName: project.name,
|
projectName: project.name,
|
||||||
withLabel: true,
|
withLabel: true,
|
||||||
withScanOverview: true,
|
withScanOverview: true,
|
||||||
withSignature: true,
|
withTag: false,
|
||||||
withImmutableStatus: true
|
withImmutableStatus: true
|
||||||
}), of(project)]);
|
}), of(project)]);
|
||||||
}),
|
}),
|
||||||
|
Loading…
Reference in New Issue
Block a user