Fix tag select bug in tag component

Signed-off-by: AllForNothing <sshijun@vmware.com>
This commit is contained in:
AllForNothing 2019-11-12 10:25:03 +08:00
parent 407417ce7b
commit 7f1201dec9
6 changed files with 36 additions and 32 deletions

View File

@ -55,10 +55,10 @@
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12"> <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-datagrid [clrDgLoading]="loading" class="datagrid-top" [class.embeded-datagrid]="isEmbedded" [(clrDgSelected)]="selectedRow">
<clr-dg-action-bar> <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>&nbsp;{{'VULNERABILITY.SCAN_NOW' | 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>&nbsp;{{'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>&nbsp;{{'REPOSITORY.COPY_DIGEST_ID' | 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>&nbsp;{{'REPOSITORY.COPY_DIGEST_ID' | translate}}</button>
<clr-dropdown *ngIf="!withAdmiral"> <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-menu clrPosition="bottom-left" *clrIfOpen>
<clr-dropdown> <clr-dropdown>
<div class="filter-grid"> <div class="filter-grid">
@ -75,8 +75,8 @@
</clr-dropdown> </clr-dropdown>
</clr-dropdown-menu> </clr-dropdown-menu>
</clr-dropdown> </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>&nbsp;{{'REPOSITORY.RETAG' | 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>&nbsp;{{'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>&nbsp;{{'REPOSITORY.DELETE' | 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>&nbsp;{{'REPOSITORY.DELETE' | translate}}</button>
</clr-dg-action-bar> </clr-dg-action-bar>
<clr-dg-column class="flex-max-width" [clrDgField]="'name'">{{'REPOSITORY.TAG' | translate}}</clr-dg-column> <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> <clr-dg-column [clrDgField]="'size'">{{'REPOSITORY.SIZE' | translate}}</clr-dg-column>
@ -109,7 +109,7 @@
</clr-dg-cell> </clr-dg-cell>
<clr-dg-cell> <clr-dg-cell>
<div class="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> </div>
</clr-dg-cell> </clr-dg-cell>
<clr-dg-cell *ngIf="withNotary" [ngSwitch]="t.signature !== null"> <clr-dg-cell *ngIf="withNotary" [ngSwitch]="t.signature !== null">

View File

@ -153,6 +153,7 @@ export class TagComponent implements OnInit, AfterViewInit {
hasScanImagePermission: boolean; hasScanImagePermission: boolean;
hasEnabledScanner: boolean; hasEnabledScanner: boolean;
scanBtnState: ClrLoadingState = ClrLoadingState.DEFAULT; scanBtnState: ClrLoadingState = ClrLoadingState.DEFAULT;
onSendingScanCommand: boolean;
constructor( constructor(
private errorHandler: ErrorHandler, private errorHandler: ErrorHandler,
private tagService: TagService, private tagService: TagService,
@ -318,11 +319,11 @@ export class TagComponent implements OnInit, AfterViewInit {
} }
} }
addLabels(tag: Tag[]): void { addLabels(): void {
this.labelListOpen = true; this.labelListOpen = true;
this.selectedTag = tag; this.selectedTag = this.selectedRow;
this.stickName = ''; this.stickName = '';
this.labelSelectedChange(tag); this.labelSelectedChange(this.selectedRow);
} }
stickLabel(labelInfo: LabelState): void { stickLabel(labelInfo: LabelState): void {
@ -558,10 +559,10 @@ export class TagComponent implements OnInit, AfterViewInit {
} }
} }
retag(tags: Tag[]) { retag() {
if (tags && tags.length) { if (this.selectedRow && this.selectedRow.length) {
this.retagDialogOpened = true; this.retagDialogOpened = true;
this.retagSrcImage = this.repoName + ":" + tags[0].digest; this.retagSrcImage = this.repoName + ":" + this.selectedRow[0].digest;
} else { } else {
this.errorHandler.error("One tag should be selected before retag."); this.errorHandler.error("One tag should be selected before retag.");
} }
@ -588,10 +589,10 @@ export class TagComponent implements OnInit, AfterViewInit {
}); });
} }
deleteTags(tags: Tag[]) { deleteTags() {
if (tags && tags.length) { if (this.selectedRow && this.selectedRow.length) {
let tagNames: string[] = []; let tagNames: string[] = [];
tags.forEach(tag => { this.selectedRow.forEach(tag => {
tagNames.push(tag.name); tagNames.push(tag.name);
}); });
@ -604,7 +605,7 @@ export class TagComponent implements OnInit, AfterViewInit {
titleKey, titleKey,
summaryKey, summaryKey,
content, content,
tags, this.selectedRow,
ConfirmationTargets.TAG, ConfirmationTargets.TAG,
buttons); buttons);
this.confirmationDialog.open(message); this.confirmationDialog.open(message);
@ -670,10 +671,10 @@ export class TagComponent implements OnInit, AfterViewInit {
} }
} }
showDigestId(tag: Tag[]) { showDigestId() {
if (tag && (tag.length === 1)) { if (this.selectedRow && (this.selectedRow.length === 1)) {
this.manifestInfoTitle = "REPOSITORY.COPY_DIGEST_ID"; this.manifestInfoTitle = "REPOSITORY.COPY_DIGEST_ID";
this.digestId = tag[0].digest; this.digestId = this.selectedRow[0].digest;
this.showTagManifestOpened = true; this.showTagManifestOpened = true;
this.copyFailed = false; this.copyFailed = false;
} }
@ -716,9 +717,10 @@ export class TagComponent implements OnInit, AfterViewInit {
return VULNERABILITY_SCAN_STATUS.NOT_SCANNED; return VULNERABILITY_SCAN_STATUS.NOT_SCANNED;
} }
// Whether show the 'scan now' menu // Whether show the 'scan now' menu
canScanNow(t: Tag[]): boolean { canScanNow(): boolean {
if (!this.hasScanImagePermission) { return false; } 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; return st !== VULNERABILITY_SCAN_STATUS.RUNNING;
} }
getImagePermissionRule(projectId: number): void { getImagePermissionRule(projectId: number): void {
@ -742,15 +744,18 @@ export class TagComponent implements OnInit, AfterViewInit {
}, error => this.errorHandler.error(error)); }, error => this.errorHandler.error(error));
} }
// Trigger scan // Trigger scan
scanNow(t: Tag[]): void { scanNow(): void {
if (t && t.length) { if (this.selectedRow && this.selectedRow.length) {
t.forEach((data: any) => { this.selectedRow.forEach((data: any) => {
let tagId = data.name; let tagId = data.name;
this.onSendingScanCommand = true;
this.channel.publishScanEvent(this.repoName + "/" + tagId); this.channel.publishScanEvent(this.repoName + "/" + tagId);
}); });
} }
} }
submitFinish(e: boolean) {
this.onSendingScanCommand = e;
}
// pull command // pull command
onCpError($event: any): void { onCpError($event: any): void {
this.copyInput.setPullCommendShow(); this.copyInput.setPullCommendShow();

View File

@ -3,7 +3,7 @@ import {
Input, Input,
OnInit, OnInit,
OnDestroy, OnDestroy,
ChangeDetectorRef, ChangeDetectorRef, Output, EventEmitter,
} from '@angular/core'; } from '@angular/core';
import { Subscription , timer} from "rxjs"; import { Subscription , timer} from "rxjs";
@ -17,6 +17,7 @@ import {
import { ErrorHandler } from '../error-handler/index'; import { ErrorHandler } from '../error-handler/index';
import { ChannelService } from '../channel/index'; import { ChannelService } from '../channel/index';
import { JobLogService } from "../service/index"; import { JobLogService } from "../service/index";
import { finalize } from "rxjs/operators";
const STATE_CHECK_INTERVAL: number = 3000; // 3s const STATE_CHECK_INTERVAL: number = 3000; // 3s
const RETRY_TIMES: number = 3; const RETRY_TIMES: number = 3;
@ -35,6 +36,8 @@ export class ResultBarChartComponent implements OnInit, OnDestroy {
stateCheckTimer: Subscription; stateCheckTimer: Subscription;
scanSubscription: Subscription; scanSubscription: Subscription;
timerHandler: any; timerHandler: any;
@Output()
submitFinish: EventEmitter<boolean> = new EventEmitter<boolean>();
constructor( constructor(
private tagService: TagService, private tagService: TagService,
@ -114,6 +117,7 @@ export class ResultBarChartComponent implements OnInit, OnDestroy {
this.onSubmitting = true; this.onSubmitting = true;
this.scanningService.startVulnerabilityScanning(this.repoName, this.tagId) this.scanningService.startVulnerabilityScanning(this.repoName, this.tagId)
.pipe(finalize(() => this.submitFinish.emit(false)))
.subscribe(() => { .subscribe(() => {
this.onSubmitting = false; this.onSubmitting = false;

View File

@ -26,7 +26,7 @@
<span class="margin-left-10 font-weight-800 color-green font-size-12">{{fixableCount}}</span> <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> <span class="margin-left-5 color-green font-size-12">{{'SCANNER.FIXABLE' | translate}}</span>
</div> </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> </div>
<clr-tooltip-content class="w-800" [clrPosition]="'right'" [clrSize]="'lg'" *clrIfOpen> <clr-tooltip-content class="w-800" [clrPosition]="'right'" [clrSize]="'lg'" *clrIfOpen>
<div class="bar-tooltip-font-larger"> <div class="bar-tooltip-font-larger">

View File

@ -288,8 +288,6 @@ hr {
color: green; color: green;
} }
.tip-block { .tip-block {
height: $thirty-pixel;
line-height: $thirty-pixel;
position: relative; position: relative;
} }
.font-size-14 { .font-size-14 {

View File

@ -1,6 +1,5 @@
.bar-wrapper { .bar-wrapper {
width: 210px; width: 210px;
height: 15px;
} }
.bar-state { .bar-state {
text-align: center !important; text-align: center !important;
@ -10,7 +9,6 @@
} }
.bar-state-chart { .bar-state-chart {
margin-top: 2px;
.loop-height { .loop-height {
height: 2px; height: 2px;
} }
@ -18,7 +16,6 @@
.bar-state-error { .bar-state-error {
position: relative; position: relative;
top: -4px;
} }
.error-text { .error-text {