diff --git a/src/portal/src/app/project/p2p-provider/add-p2p-policy/add-p2p-policy.component.ts b/src/portal/src/app/project/p2p-provider/add-p2p-policy/add-p2p-policy.component.ts index fdc1da6f5..459902aa1 100644 --- a/src/portal/src/app/project/p2p-provider/add-p2p-policy/add-p2p-policy.component.ts +++ b/src/portal/src/app/project/p2p-provider/add-p2p-policy/add-p2p-policy.component.ts @@ -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) { diff --git a/src/portal/src/app/project/repository/artifact-list-page/artifact-list/artifact-list-tab/artifact-list-tab.component.html b/src/portal/src/app/project/repository/artifact-list-page/artifact-list/artifact-list-tab/artifact-list-tab.component.html index 50f913b68..65f6ea3bb 100644 --- a/src/portal/src/app/project/repository/artifact-list-page/artifact-list/artifact-list-tab/artifact-list-tab.component.html +++ b/src/portal/src/app/project/repository/artifact-list-page/artifact-list/artifact-list-tab/artifact-list-tab.component.html @@ -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> diff --git a/src/portal/src/app/project/repository/artifact-list-page/artifact-list/artifact-list-tab/artifact-list-tab.component.spec.ts b/src/portal/src/app/project/repository/artifact-list-page/artifact-list/artifact-list-tab/artifact-list-tab.component.spec.ts index ffc715434..738d11ff2 100644 --- a/src/portal/src/app/project/repository/artifact-list-page/artifact-list/artifact-list-tab/artifact-list-tab.component.spec.ts +++ b/src/portal/src/app/project/repository/artifact-list-page/artifact-list/artifact-list-tab/artifact-list-tab.component.spec.ts @@ -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({ diff --git a/src/portal/src/app/project/repository/artifact-list-page/artifact-list/artifact-list-tab/artifact-list-tab.component.ts b/src/portal/src/app/project/repository/artifact-list-page/artifact-list/artifact-list-tab/artifact-list-tab.component.ts index cd99941f1..8431a59a6 100644 --- a/src/portal/src/app/project/repository/artifact-list-page/artifact-list/artifact-list-tab/artifact-list-tab.component.ts +++ b/src/portal/src/app/project/repository/artifact-list-page/artifact-list/artifact-list-tab/artifact-list-tab.component.ts @@ -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); + } } diff --git a/src/portal/src/app/project/repository/artifact/artifact-summary.component.html b/src/portal/src/app/project/repository/artifact/artifact-summary.component.html index cda500849..b2b106c3d 100644 --- a/src/portal/src/app/project/repository/artifact/artifact-summary.component.html +++ b/src/portal/src/app/project/repository/artifact/artifact-summary.component.html @@ -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> diff --git a/src/portal/src/app/project/repository/artifact/artifact-summary.component.spec.ts b/src/portal/src/app/project/repository/artifact/artifact-summary.component.spec.ts index 7bed83c73..a899ca72b 100644 --- a/src/portal/src/app/project/repository/artifact/artifact-summary.component.spec.ts +++ b/src/portal/src/app/project/repository/artifact/artifact-summary.component.spec.ts @@ -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 ] }) diff --git a/src/portal/src/app/project/repository/artifact/artifact-summary.component.ts b/src/portal/src/app/project/repository/artifact/artifact-summary.component.ts index 809354c2d..5d1a75bf3 100644 --- a/src/portal/src/app/project/repository/artifact/artifact-summary.component.ts +++ b/src/portal/src/app/project/repository/artifact/artifact-summary.component.ts @@ -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]); + } + } } diff --git a/src/portal/src/app/project/repository/artifact/artifact.service.spec.ts b/src/portal/src/app/project/repository/artifact/artifact.service.spec.ts index 4c6f904a4..6707f6b0f 100644 --- a/src/portal/src/app/project/repository/artifact/artifact.service.spec.ts +++ b/src/portal/src/app/project/repository/artifact/artifact.service.spec.ts @@ -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 + ] }); }); diff --git a/src/portal/src/app/project/repository/artifact/artifact.service.ts b/src/portal/src/app/project/repository/artifact/artifact.service.ts index 52ea04179..10257bf0e 100644 --- a/src/portal/src/app/project/repository/artifact/artifact.service.ts +++ b/src/portal/src/app/project/repository/artifact/artifact.service.ts @@ -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}`)); + }); + } + }); + } + } } diff --git a/src/portal/src/app/project/repository/artifact/artifact.ts b/src/portal/src/app/project/repository/artifact/artifact.ts index 37551b2f9..adc888cac 100644 --- a/src/portal/src/app/project/repository/artifact/artifact.ts +++ b/src/portal/src/app/project/repository/artifact/artifact.ts @@ -5,6 +5,7 @@ export interface ArtifactFront extends Artifact { platform?: Platform; showImage?: string; pullCommand?: string; + annotationsArray?: Array<{[key: string]: any}>; } export const mutipleFilter = [