mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-18 22:57:38 +01:00
Merge pull request #9839 from AllForNothing/unexpected
Fix tag select bug in tag component
This commit is contained in:
commit
9367b3f240
@ -55,10 +55,10 @@
|
||||
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
||||
<clr-datagrid [clrDgLoading]="loading" class="datagrid-top" [class.embeded-datagrid]="isEmbedded" [(clrDgSelected)]="selectedRow">
|
||||
<clr-dg-action-bar>
|
||||
<button [clrLoading]="scanBtnState" type="button" class="btn btn-sm btn-secondary" [disabled]="!(canScanNow(selectedRow) && selectedRow.length==1 && hasEnabledScanner)" (click)="scanNow(selectedRow)"><clr-icon shape="shield-check" size="16"></clr-icon> {{'VULNERABILITY.SCAN_NOW' | translate}}</button>
|
||||
<button type="button" class="btn btn-sm btn-secondary" [disabled]="!(selectedRow.length==1)" (click)="showDigestId(selectedRow)"><clr-icon shape="copy" size="16"></clr-icon> {{'REPOSITORY.COPY_DIGEST_ID' | translate}}</button>
|
||||
<button [clrLoading]="scanBtnState" type="button" class="btn btn-sm btn-secondary" [disabled]="!(canScanNow() && selectedRow.length==1 && hasEnabledScanner)" (click)="scanNow()"><clr-icon shape="shield-check" size="16"></clr-icon> {{'VULNERABILITY.SCAN_NOW' | translate}}</button>
|
||||
<button type="button" class="btn btn-sm btn-secondary" [disabled]="!(selectedRow.length==1)" (click)="showDigestId()"><clr-icon shape="copy" size="16"></clr-icon> {{'REPOSITORY.COPY_DIGEST_ID' | translate}}</button>
|
||||
<clr-dropdown *ngIf="!withAdmiral">
|
||||
<button type="button" class="btn btn-sm btn-secondary" clrDropdownTrigger [disabled]="!(selectedRow.length==1)||!hasAddLabelImagePermission" (click)="addLabels(selectedRow)"><clr-icon shape="plus" size="16"></clr-icon>{{'REPOSITORY.ADD_LABELS' | translate}}</button>
|
||||
<button type="button" class="btn btn-sm btn-secondary" clrDropdownTrigger [disabled]="!(selectedRow.length==1)||!hasAddLabelImagePermission" (click)="addLabels()"><clr-icon shape="plus" size="16"></clr-icon>{{'REPOSITORY.ADD_LABELS' | translate}}</button>
|
||||
<clr-dropdown-menu clrPosition="bottom-left" *clrIfOpen>
|
||||
<clr-dropdown>
|
||||
<div class="filter-grid">
|
||||
@ -75,8 +75,8 @@
|
||||
</clr-dropdown>
|
||||
</clr-dropdown-menu>
|
||||
</clr-dropdown>
|
||||
<button type="button" class="btn btn-sm btn-secondary" *ngIf="!withAdmiral" [disabled]="!(selectedRow.length===1)|| !hasRetagImagePermission" (click)="retag(selectedRow)"><clr-icon shape="copy" size="16"></clr-icon> {{'REPOSITORY.RETAG' | translate}}</button>
|
||||
<button type="button" class="btn btn-sm btn-secondary" *ngIf="hasDeleteImagePermission" (click)="deleteTags(selectedRow)" [disabled]="!hasDeleteImagePermission||!selectedRow.length"><clr-icon shape="times" size="16"></clr-icon> {{'REPOSITORY.DELETE' | translate}}</button>
|
||||
<button type="button" class="btn btn-sm btn-secondary" *ngIf="!withAdmiral" [disabled]="!(selectedRow.length===1)|| !hasRetagImagePermission" (click)="retag()"><clr-icon shape="copy" size="16"></clr-icon> {{'REPOSITORY.RETAG' | translate}}</button>
|
||||
<button type="button" class="btn btn-sm btn-secondary" *ngIf="hasDeleteImagePermission" (click)="deleteTags()" [disabled]="!hasDeleteImagePermission||!selectedRow.length"><clr-icon shape="times" size="16"></clr-icon> {{'REPOSITORY.DELETE' | translate}}</button>
|
||||
</clr-dg-action-bar>
|
||||
<clr-dg-column class="flex-max-width" [clrDgField]="'name'">{{'REPOSITORY.TAG' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgField]="'size'">{{'REPOSITORY.SIZE' | translate}}</clr-dg-column>
|
||||
@ -109,7 +109,7 @@
|
||||
</clr-dg-cell>
|
||||
<clr-dg-cell>
|
||||
<div class="cell">
|
||||
<hbr-vulnerability-bar [repoName]="repoName" [tagId]="t.name" [summary]="handleScanOverview(t.scan_overview)"></hbr-vulnerability-bar>
|
||||
<hbr-vulnerability-bar (submitFinish)="submitFinish($event)" [repoName]="repoName" [tagId]="t.name" [summary]="handleScanOverview(t.scan_overview)"></hbr-vulnerability-bar>
|
||||
</div>
|
||||
</clr-dg-cell>
|
||||
<clr-dg-cell *ngIf="withNotary" [ngSwitch]="t.signature !== null">
|
||||
|
@ -153,6 +153,7 @@ export class TagComponent implements OnInit, AfterViewInit {
|
||||
hasScanImagePermission: boolean;
|
||||
hasEnabledScanner: boolean;
|
||||
scanBtnState: ClrLoadingState = ClrLoadingState.DEFAULT;
|
||||
onSendingScanCommand: boolean;
|
||||
constructor(
|
||||
private errorHandler: ErrorHandler,
|
||||
private tagService: TagService,
|
||||
@ -318,11 +319,11 @@ export class TagComponent implements OnInit, AfterViewInit {
|
||||
}
|
||||
}
|
||||
|
||||
addLabels(tag: Tag[]): void {
|
||||
addLabels(): void {
|
||||
this.labelListOpen = true;
|
||||
this.selectedTag = tag;
|
||||
this.selectedTag = this.selectedRow;
|
||||
this.stickName = '';
|
||||
this.labelSelectedChange(tag);
|
||||
this.labelSelectedChange(this.selectedRow);
|
||||
}
|
||||
|
||||
stickLabel(labelInfo: LabelState): void {
|
||||
@ -558,10 +559,10 @@ export class TagComponent implements OnInit, AfterViewInit {
|
||||
}
|
||||
}
|
||||
|
||||
retag(tags: Tag[]) {
|
||||
if (tags && tags.length) {
|
||||
retag() {
|
||||
if (this.selectedRow && this.selectedRow.length) {
|
||||
this.retagDialogOpened = true;
|
||||
this.retagSrcImage = this.repoName + ":" + tags[0].digest;
|
||||
this.retagSrcImage = this.repoName + ":" + this.selectedRow[0].digest;
|
||||
} else {
|
||||
this.errorHandler.error("One tag should be selected before retag.");
|
||||
}
|
||||
@ -588,10 +589,10 @@ export class TagComponent implements OnInit, AfterViewInit {
|
||||
});
|
||||
}
|
||||
|
||||
deleteTags(tags: Tag[]) {
|
||||
if (tags && tags.length) {
|
||||
deleteTags() {
|
||||
if (this.selectedRow && this.selectedRow.length) {
|
||||
let tagNames: string[] = [];
|
||||
tags.forEach(tag => {
|
||||
this.selectedRow.forEach(tag => {
|
||||
tagNames.push(tag.name);
|
||||
});
|
||||
|
||||
@ -604,7 +605,7 @@ export class TagComponent implements OnInit, AfterViewInit {
|
||||
titleKey,
|
||||
summaryKey,
|
||||
content,
|
||||
tags,
|
||||
this.selectedRow,
|
||||
ConfirmationTargets.TAG,
|
||||
buttons);
|
||||
this.confirmationDialog.open(message);
|
||||
@ -670,10 +671,10 @@ export class TagComponent implements OnInit, AfterViewInit {
|
||||
}
|
||||
}
|
||||
|
||||
showDigestId(tag: Tag[]) {
|
||||
if (tag && (tag.length === 1)) {
|
||||
showDigestId() {
|
||||
if (this.selectedRow && (this.selectedRow.length === 1)) {
|
||||
this.manifestInfoTitle = "REPOSITORY.COPY_DIGEST_ID";
|
||||
this.digestId = tag[0].digest;
|
||||
this.digestId = this.selectedRow[0].digest;
|
||||
this.showTagManifestOpened = true;
|
||||
this.copyFailed = false;
|
||||
}
|
||||
@ -716,9 +717,10 @@ export class TagComponent implements OnInit, AfterViewInit {
|
||||
return VULNERABILITY_SCAN_STATUS.NOT_SCANNED;
|
||||
}
|
||||
// Whether show the 'scan now' menu
|
||||
canScanNow(t: Tag[]): boolean {
|
||||
canScanNow(): boolean {
|
||||
if (!this.hasScanImagePermission) { return false; }
|
||||
let st: string = this.scanStatus(t[0]);
|
||||
if (this.onSendingScanCommand) { return false; }
|
||||
let st: string = this.scanStatus(this.selectedRow[0]);
|
||||
return st !== VULNERABILITY_SCAN_STATUS.RUNNING;
|
||||
}
|
||||
getImagePermissionRule(projectId: number): void {
|
||||
@ -742,15 +744,18 @@ export class TagComponent implements OnInit, AfterViewInit {
|
||||
}, error => this.errorHandler.error(error));
|
||||
}
|
||||
// Trigger scan
|
||||
scanNow(t: Tag[]): void {
|
||||
if (t && t.length) {
|
||||
t.forEach((data: any) => {
|
||||
scanNow(): void {
|
||||
if (this.selectedRow && this.selectedRow.length) {
|
||||
this.selectedRow.forEach((data: any) => {
|
||||
let tagId = data.name;
|
||||
this.onSendingScanCommand = true;
|
||||
this.channel.publishScanEvent(this.repoName + "/" + tagId);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
submitFinish(e: boolean) {
|
||||
this.onSendingScanCommand = e;
|
||||
}
|
||||
// pull command
|
||||
onCpError($event: any): void {
|
||||
this.copyInput.setPullCommendShow();
|
||||
|
@ -3,7 +3,7 @@ import {
|
||||
Input,
|
||||
OnInit,
|
||||
OnDestroy,
|
||||
ChangeDetectorRef,
|
||||
ChangeDetectorRef, Output, EventEmitter,
|
||||
} from '@angular/core';
|
||||
import { Subscription , timer} from "rxjs";
|
||||
|
||||
@ -17,6 +17,7 @@ import {
|
||||
import { ErrorHandler } from '../error-handler/index';
|
||||
import { ChannelService } from '../channel/index';
|
||||
import { JobLogService } from "../service/index";
|
||||
import { finalize } from "rxjs/operators";
|
||||
|
||||
const STATE_CHECK_INTERVAL: number = 3000; // 3s
|
||||
const RETRY_TIMES: number = 3;
|
||||
@ -35,6 +36,8 @@ export class ResultBarChartComponent implements OnInit, OnDestroy {
|
||||
stateCheckTimer: Subscription;
|
||||
scanSubscription: Subscription;
|
||||
timerHandler: any;
|
||||
@Output()
|
||||
submitFinish: EventEmitter<boolean> = new EventEmitter<boolean>();
|
||||
|
||||
constructor(
|
||||
private tagService: TagService,
|
||||
@ -114,6 +117,7 @@ export class ResultBarChartComponent implements OnInit, OnDestroy {
|
||||
this.onSubmitting = true;
|
||||
|
||||
this.scanningService.startVulnerabilityScanning(this.repoName, this.tagId)
|
||||
.pipe(finalize(() => this.submitFinish.emit(false)))
|
||||
.subscribe(() => {
|
||||
this.onSubmitting = false;
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
<span class="margin-left-10 font-weight-800 color-green font-size-12">{{fixableCount}}</span>
|
||||
<span class="margin-left-5 color-green font-size-12">{{'SCANNER.FIXABLE' | translate}}</span>
|
||||
</div>
|
||||
<div *ngIf="isNone" class="margin-left-5 tip-wrapper bar-block-none shadow-none width-150">{{'VULNERABILITY.NO_VULNERABILITY' | translate }}</div>
|
||||
<div *ngIf="isNone" class="pl-1 margin-left-5 tip-wrapper bar-block-none shadow-none width-150">{{'VULNERABILITY.NO_VULNERABILITY' | translate }}</div>
|
||||
</div>
|
||||
<clr-tooltip-content class="w-800" [clrPosition]="'right'" [clrSize]="'lg'" *clrIfOpen>
|
||||
<div class="bar-tooltip-font-larger">
|
||||
|
@ -288,8 +288,6 @@ hr {
|
||||
color: green;
|
||||
}
|
||||
.tip-block {
|
||||
height: $thirty-pixel;
|
||||
line-height: $thirty-pixel;
|
||||
position: relative;
|
||||
}
|
||||
.font-size-14 {
|
||||
|
@ -1,6 +1,5 @@
|
||||
.bar-wrapper {
|
||||
width: 210px;
|
||||
height: 15px;
|
||||
}
|
||||
.bar-state {
|
||||
text-align: center !important;
|
||||
@ -10,7 +9,6 @@
|
||||
}
|
||||
|
||||
.bar-state-chart {
|
||||
margin-top: 2px;
|
||||
.loop-height {
|
||||
height: 2px;
|
||||
}
|
||||
@ -18,7 +16,6 @@
|
||||
|
||||
.bar-state-error {
|
||||
position: relative;
|
||||
top: -4px;
|
||||
}
|
||||
|
||||
.error-text {
|
||||
|
Loading…
Reference in New Issue
Block a user