mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-22 18:25:56 +01:00
Merge pull request #12701 from AllForNothing/artifact-icon
get artifact icon from backend API
This commit is contained in:
commit
9671ff1f10
@ -151,11 +151,6 @@ export class AddP2pPolicyComponent implements OnInit, OnDestroy {
|
||||
this.tags = null;
|
||||
this.labels = null;
|
||||
this.cron = null;
|
||||
this.currentForm.reset({
|
||||
triggerType: "manual",
|
||||
severity: PROJECT_SEVERITY_LEVEL_MAP[this.projectSeverity],
|
||||
onlySignedImages: this.enableContentTrust
|
||||
});
|
||||
if (this.providers && this.providers.length) {
|
||||
this.providers.forEach(item => {
|
||||
if (item.default) {
|
||||
@ -163,6 +158,12 @@ export class AddP2pPolicyComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
});
|
||||
}
|
||||
this.currentForm.reset({
|
||||
triggerType: "manual",
|
||||
severity: PROJECT_SEVERITY_LEVEL_MAP[this.projectSeverity],
|
||||
onlySignedImages: this.enableContentTrust,
|
||||
provider: this.policy.provider_id
|
||||
});
|
||||
}
|
||||
|
||||
setCron(event: any) {
|
||||
|
@ -40,7 +40,7 @@
|
||||
<div class="execution-select">
|
||||
<div class="select filter-tag" [hidden]="!openSelectFilterPiece">
|
||||
<clr-select-container>
|
||||
<select clrSelect [(ngModel)]="filterByType" (change)="selectFilterType($event)" >
|
||||
<select clrSelect [(ngModel)]="filterByType" (change)="selectFilterType()" >
|
||||
<option *ngFor="let filter of mutipleFilter" value="{{filter.filterBy}}">{{ filter.filterByShowText | translate}}</option>
|
||||
</select>
|
||||
</clr-select-container>
|
||||
@ -161,25 +161,16 @@
|
||||
<clr-dg-row *ngFor="let artifact of artifactList" [clrDgItem]="artifact" >
|
||||
<clr-dg-cell class="truncated flex-max-width">
|
||||
<div class="cell white-normal">
|
||||
<img *ngIf="artifact?.type !== 'IMAGE';else elseBlock" class="artifact-icon" [title]="artifact.type"
|
||||
[src]="artifact.type | selectArtifactIcon" />
|
||||
<ng-template #elseBlock>
|
||||
<clr-tooltip>
|
||||
<div clrTooltipTrigger class="level-border">
|
||||
<img class="artifact-icon" [title]="artifact.type"
|
||||
[src]="artifact.type | selectArtifactIcon" />
|
||||
</div>
|
||||
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||
<span>Docker and the Docker logo are trademarks or registered trademarks of Docker, Inc. in the United States and/or other countries.</span>
|
||||
</clr-tooltip-content>
|
||||
</clr-tooltip>
|
||||
</ng-template>
|
||||
<div class="artifact-icon clr-display-inline-block" *ngIf="artifact.icon">
|
||||
<img *ngIf="getIcon(artifact.icon)" class="artifact-icon" [title]="artifact.type"
|
||||
[src]="getIcon(artifact.icon)" (error)="showDefaultIcon($event)" />
|
||||
</div>
|
||||
<a href="javascript:void(0)" class="max-width-100 margin-left-5" (click)="goIntoArtifactSummaryPage(artifact)"
|
||||
title="{{artifact.digest}}">
|
||||
{{ artifact.digest | slice:0:15}}</a>
|
||||
<clr-tooltip *ngIf="artifact?.references && artifact?.references?.length">
|
||||
<div clrTooltipTrigger class="level-border">
|
||||
<div class="inner truncated ">
|
||||
<div class="inner truncated">
|
||||
<a href="javascript:void(0)" (click)="goIntoIndexArtifact(artifact)">
|
||||
<clr-icon class="icon-folder" shape="folder"></clr-icon>
|
||||
</a>
|
||||
@ -256,7 +247,7 @@
|
||||
</clr-dg-cell>
|
||||
<clr-dg-cell>
|
||||
<div class="cell">
|
||||
{{artifact.size?sizeTransform(artifact.size): ""}}
|
||||
{{artifact.size?sizeTransform(artifact.size+''): ""}}
|
||||
</div>
|
||||
</clr-dg-cell>
|
||||
<clr-dg-cell>
|
||||
|
@ -282,8 +282,13 @@ describe("ArtifactListTabComponent (inline template)", () => {
|
||||
).pipe(delay(0));
|
||||
}
|
||||
},
|
||||
deleteArtifact: () => of (null)
|
||||
|
||||
deleteArtifact: () => of (null),
|
||||
getIconsFromBackEnd() {
|
||||
return undefined;
|
||||
},
|
||||
getIcon() {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
|
@ -54,11 +54,18 @@ import {
|
||||
} from "../../../../../../lib/entities/shared.const";
|
||||
import { operateChanges, OperateInfo, OperationState } from "../../../../../../lib/components/operation/operate";
|
||||
import { errorHandler } from "../../../../../../lib/utils/shared/shared.utils";
|
||||
import { ArtifactFront as Artifact, mutipleFilter, artifactPullCommands } from "../../../artifact/artifact";
|
||||
import {
|
||||
ArtifactFront as Artifact,
|
||||
mutipleFilter,
|
||||
artifactPullCommands,
|
||||
artifactDefault
|
||||
} from '../../../artifact/artifact';
|
||||
import { Project } from "../../../../project";
|
||||
import { ArtifactService as NewArtifactService } from "../../../../../../../ng-swagger-gen/services/artifact.service";
|
||||
import { ADDITIONS } from "../../../artifact/artifact-additions/models";
|
||||
import { Platform } from "../../../../../../../ng-swagger-gen/models/platform";
|
||||
import { IconService } from '../../../../../../../ng-swagger-gen/services/icon.service';
|
||||
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
|
||||
export interface LabelState {
|
||||
iconsShow: boolean;
|
||||
label: Label;
|
||||
@ -161,7 +168,6 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
||||
|
||||
scanFiinishArtifactLength: number = 0;
|
||||
onScanArtifactsLength: number = 0;
|
||||
|
||||
constructor(
|
||||
private errorHandlerService: ErrorHandler,
|
||||
private userPermissionService: UserPermissionService,
|
||||
@ -374,6 +380,7 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
||||
artifact.platform = clone(platFormAttr[index].platform);
|
||||
});
|
||||
this.getPullCommand(this.artifactList);
|
||||
this.getIconsFromBackEnd();
|
||||
}, error => {
|
||||
this.errorHandlerService.error(error);
|
||||
});
|
||||
@ -403,6 +410,7 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
||||
this.artifactList = doSorting<Artifact>(this.artifactList, state);
|
||||
|
||||
this.getPullCommand(this.artifactList);
|
||||
this.getIconsFromBackEnd();
|
||||
}, error => {
|
||||
// error
|
||||
this.errorHandlerService.error(error);
|
||||
@ -992,4 +1000,17 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
}
|
||||
getIconsFromBackEnd() {
|
||||
if (this.artifactList && this.artifactList.length) {
|
||||
this.artifactService.getIconsFromBackEnd(this.artifactList);
|
||||
}
|
||||
}
|
||||
showDefaultIcon(event: any) {
|
||||
if (event && event.target) {
|
||||
event.target.src = artifactDefault;
|
||||
}
|
||||
}
|
||||
getIcon(icon: string): SafeUrl {
|
||||
return this.artifactService.getIcon(icon);
|
||||
}
|
||||
}
|
||||
|
@ -15,19 +15,10 @@
|
||||
</div>
|
||||
<div class="title-block">
|
||||
<h2 class="custom-h2 center-align-items">
|
||||
<img *ngIf="artifact?.type !== 'IMAGE';else elseBlock" class="artifact-icon" [title]="artifact.type"
|
||||
[src]="artifact.type | selectArtifactIcon" />
|
||||
<ng-template #elseBlock>
|
||||
<clr-tooltip>
|
||||
<div clrTooltipTrigger class="level-border">
|
||||
<img class="artifact-icon" [title]="artifact.type"
|
||||
[src]="artifact.type | selectArtifactIcon" />
|
||||
</div>
|
||||
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||
<span>Docker and the Docker logo are trademarks or registered trademarks of Docker, Inc. in the United States and/or other countries.</span>
|
||||
</clr-tooltip-content>
|
||||
</clr-tooltip>
|
||||
</ng-template>
|
||||
<div class="artifact-icon clr-display-inline-block" *ngIf="artifact.icon">
|
||||
<img *ngIf="getIcon(artifact.icon)" class="artifact-icon" [title]="artifact.type"
|
||||
[src]="getIcon(artifact.icon)" (error)="showDefaultIcon($event)" />
|
||||
</div>
|
||||
<span class="margin-left-10px">{{artifact?.digest | slice:0:15}}</span>
|
||||
<clr-icon size="25" *ngIf="artifact?.references && artifact?.references?.length" class="icon-folder margin-left-10px" shape="folder"></clr-icon>
|
||||
</h2>
|
||||
|
@ -12,6 +12,7 @@ import { ActivatedRoute, Router } from "@angular/router";
|
||||
import { AppConfigService } from "../../../services/app-config.service";
|
||||
import { Project } from "../../project";
|
||||
import { AllPipesModule } from "../../../all-pipes/all-pipes.module";
|
||||
import { ArtifactDefaultService } from './artifact.service';
|
||||
|
||||
describe('ArtifactSummaryComponent', () => {
|
||||
|
||||
@ -26,9 +27,12 @@ describe('ArtifactSummaryComponent', () => {
|
||||
}
|
||||
};
|
||||
|
||||
const fakedArtifactService = {
|
||||
getArtifact() {
|
||||
return of(mockedArtifact);
|
||||
const fakedArtifactDefaultService = {
|
||||
getIconsFromBackEnd() {
|
||||
return undefined;
|
||||
},
|
||||
getIcon() {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
let component: ArtifactSummaryComponent;
|
||||
@ -86,7 +90,7 @@ describe('ArtifactSummaryComponent', () => {
|
||||
{ provide: Router, useValue: mockRouter },
|
||||
{ provide: ActivatedRoute, useValue: mockActivatedRoute },
|
||||
{ provide: ProjectService, useValue: fakedProjectService },
|
||||
{ provide: ArtifactService, useValue: fakedArtifactService },
|
||||
{ provide: ArtifactDefaultService, useValue: fakedArtifactDefaultService },
|
||||
ErrorHandler
|
||||
]
|
||||
})
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { Component, Output, EventEmitter, OnInit } from "@angular/core";
|
||||
import { Artifact } from "../../../../../ng-swagger-gen/models/artifact";
|
||||
import { ArtifactService } from "../../../../../ng-swagger-gen/services/artifact.service";
|
||||
import { ErrorHandler } from "../../../../lib/utils/error-handler";
|
||||
import { Label } from "../../../../../ng-swagger-gen/models/label";
|
||||
import { ProjectService } from "../../../../lib/services";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
import { AppConfigService } from "../../../services/app-config.service";
|
||||
import { Project } from "../../project";
|
||||
import { finalize } from "rxjs/operators";
|
||||
import { dbEncodeURIComponent } from "../../../../lib/utils/utils";
|
||||
import { artifactDefault } from './artifact';
|
||||
import { SafeUrl } from '@angular/platform-browser';
|
||||
import { ArtifactDefaultService } from './artifact.service';
|
||||
|
||||
@Component({
|
||||
selector: "artifact-summary",
|
||||
@ -34,11 +34,11 @@ export class ArtifactSummaryComponent implements OnInit {
|
||||
|
||||
constructor(
|
||||
private projectService: ProjectService,
|
||||
private artifactService: ArtifactService,
|
||||
private errorHandler: ErrorHandler,
|
||||
private route: ActivatedRoute,
|
||||
private appConfigService: AppConfigService,
|
||||
private router: Router
|
||||
private router: Router,
|
||||
private frontEndArtifactService: ArtifactDefaultService,
|
||||
) {
|
||||
}
|
||||
|
||||
@ -81,27 +81,24 @@ export class ArtifactSummaryComponent implements OnInit {
|
||||
const pro: Project = <Project>(resolverData['artifactResolver'][1]);
|
||||
this.projectName = pro.name;
|
||||
this.artifact = <Artifact>(resolverData['artifactResolver'][0]);
|
||||
this.getIconFromBackEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getArtifactDetails(): void {
|
||||
this.loading = true;
|
||||
this.artifactService.getArtifact({
|
||||
repositoryName: dbEncodeURIComponent(this.repositoryName),
|
||||
reference: this.artifactDigest,
|
||||
projectName: this.projectName,
|
||||
withLabel: true,
|
||||
withScanOverview: true
|
||||
}).pipe(finalize(() => this.loading = false))
|
||||
.subscribe(response => {
|
||||
this.artifact = response;
|
||||
}, error => {
|
||||
this.errorHandler.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
onBack(): void {
|
||||
this.backEvt.emit(this.repositoryName);
|
||||
}
|
||||
showDefaultIcon(event: any) {
|
||||
if (event && event.target) {
|
||||
event.target.src = artifactDefault;
|
||||
}
|
||||
}
|
||||
getIcon(icon: string): SafeUrl {
|
||||
return this.frontEndArtifactService.getIcon(icon);
|
||||
}
|
||||
getIconFromBackEnd() {
|
||||
if (this.artifact && this.artifact.icon) {
|
||||
this.frontEndArtifactService.getIconsFromBackEnd([this.artifact]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ import { IServiceConfig, SERVICE_CONFIG } from "../../../../lib/entities/service
|
||||
import { SharedModule } from "../../../../lib/utils/shared/shared.module";
|
||||
import { ArtifactDefaultService, ArtifactService } from "../artifact/artifact.service";
|
||||
import { CURRENT_BASE_HREF } from "../../../../lib/utils/utils";
|
||||
import { IconService } from '../../../../../ng-swagger-gen/services/icon.service';
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
|
||||
describe('ArtifactService', () => {
|
||||
|
||||
@ -16,7 +18,10 @@ describe('ArtifactService', () => {
|
||||
{
|
||||
provide: ArtifactService,
|
||||
useClass: ArtifactDefaultService
|
||||
}]
|
||||
},
|
||||
IconService,
|
||||
DomSanitizer
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
import { Injectable, Inject } from "@angular/core";
|
||||
import { Subject } from "rxjs";
|
||||
import { IServiceConfig, SERVICE_CONFIG } from "../../../../lib/entities/service.config";
|
||||
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
|
||||
import { Artifact } from '../../../../../ng-swagger-gen/models/artifact';
|
||||
import { IconService } from '../../../../../ng-swagger-gen/services/icon.service';
|
||||
|
||||
|
||||
/**
|
||||
* Define the service methods to handle the repository tag related things.
|
||||
@ -13,15 +16,39 @@ export abstract class ArtifactService {
|
||||
reference: string[];
|
||||
triggerUploadArtifact = new Subject<string>();
|
||||
TriggerArtifactChan$ = this.triggerUploadArtifact.asObservable();
|
||||
abstract getIcon(digest: string): SafeUrl;
|
||||
abstract setIcon(digest: string, url: SafeUrl);
|
||||
abstract getIconsFromBackEnd(artifactList: Artifact[]);
|
||||
}
|
||||
@Injectable()
|
||||
export class ArtifactDefaultService extends ArtifactService {
|
||||
|
||||
triggerUploadArtifact = new Subject<string>();
|
||||
TriggerArtifactChan$ = this.triggerUploadArtifact.asObservable();
|
||||
|
||||
constructor() {
|
||||
private _iconMap: {[key: string]: SafeUrl} = {};
|
||||
constructor(private iconService: IconService,
|
||||
private domSanitizer: DomSanitizer) {
|
||||
super();
|
||||
}
|
||||
|
||||
getIcon(icon: string): SafeUrl {
|
||||
return this._iconMap[icon];
|
||||
}
|
||||
setIcon(icon: string, url: SafeUrl) {
|
||||
if (!this._iconMap[icon]) {
|
||||
this._iconMap[icon] = url;
|
||||
}
|
||||
}
|
||||
getIconsFromBackEnd(artifactList: Artifact[]) {
|
||||
if (artifactList && artifactList.length) {
|
||||
artifactList.forEach(item => {
|
||||
if (item.icon && !this.getIcon(item.icon)) {
|
||||
this.iconService.getIcon({digest: item.icon})
|
||||
.subscribe(res => {
|
||||
this.setIcon(item.icon, this.domSanitizer
|
||||
.bypassSecurityTrustUrl(`data:${res['content-type']};charset=utf-8;base64,${res.content}`));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ export interface ArtifactFront extends Artifact {
|
||||
platform?: Platform;
|
||||
showImage?: string;
|
||||
pullCommand?: string;
|
||||
annotationsArray?: Array<{[key: string]: any}>;
|
||||
}
|
||||
|
||||
export const mutipleFilter = [
|
||||
|
Loading…
Reference in New Issue
Block a user