mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-22 18:25:56 +01:00
Merge pull request #11254 from jwangyangls/nightly-case-3
[Fix] Fix issue 2.0
This commit is contained in:
commit
96572c3c86
@ -91,7 +91,7 @@
|
|||||||
[(clrDgSelected)]="selectedRow">
|
[(clrDgSelected)]="selectedRow">
|
||||||
<clr-dg-action-bar>
|
<clr-dg-action-bar>
|
||||||
<button [clrLoading]="scanBtnState" type="button" class="btn btn-secondary scan-btn"
|
<button [clrLoading]="scanBtnState" type="button" class="btn btn-secondary scan-btn"
|
||||||
[disabled]="!(canScanNow() && selectedRowHasVul() && selectedRow.length==1 && hasEnabledScanner && hasScanImagePermission )" (click)="scanNow()">
|
[disabled]="!(canScanNow() && selectedRowHasVul() && hasEnabledScanner && hasScanImagePermission )" (click)="scanNow()">
|
||||||
<clr-icon shape="shield-check" size="16"></clr-icon> {{'VULNERABILITY.SCAN_NOW' | translate}}
|
<clr-icon shape="shield-check" size="16"></clr-icon> {{'VULNERABILITY.SCAN_NOW' | translate}}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@ -110,7 +110,7 @@
|
|||||||
(click)="addLabels()">
|
(click)="addLabels()">
|
||||||
{{'REPOSITORY.ADD_LABELS' | translate}}
|
{{'REPOSITORY.ADD_LABELS' | translate}}
|
||||||
</button>
|
</button>
|
||||||
<clr-dropdown-menu>
|
<clr-dropdown-menu [hidden]="!selectedRow.length">
|
||||||
<div class="filter-grid">
|
<div class="filter-grid">
|
||||||
<label
|
<label
|
||||||
class="dropdown-header">{{'REPOSITORY.ADD_LABEL_TO_IMAGE' | translate}}</label>
|
class="dropdown-header">{{'REPOSITORY.ADD_LABEL_TO_IMAGE' | translate}}</label>
|
||||||
@ -208,17 +208,17 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th class="left tag-header-color">
|
<th class="left tag-header-color">
|
||||||
{{'REPOSITORY.TAGS_COUNT' | translate | uppercase}}</th>
|
{{'REPOSITORY.TAGS_COUNT' | translate | uppercase}}</th>
|
||||||
<th class="left tag-header-color">
|
|
||||||
{{'REPOSITORY.PUSH_TIME' | translate | uppercase}}</th>
|
|
||||||
<th class="left tag-header-color">
|
<th class="left tag-header-color">
|
||||||
{{'REPOSITORY.PULL_TIME' | translate | uppercase}}</th>
|
{{'REPOSITORY.PULL_TIME' | translate | uppercase}}</th>
|
||||||
|
<th class="left tag-header-color">
|
||||||
|
{{'REPOSITORY.PUSH_TIME' | translate | uppercase}}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="tag-tbody">
|
<tbody class="tag-tbody">
|
||||||
<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 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>
|
||||||
<td class="left tag-body-color">{{tag.pull_time | date: 'short'}}</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -162,6 +162,10 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
|||||||
openSelectFilterPiece = false;
|
openSelectFilterPiece = false;
|
||||||
// could Pagination filter
|
// could Pagination filter
|
||||||
filters: string[];
|
filters: string[];
|
||||||
|
|
||||||
|
scanFiinishArtifactLength: number = 0;
|
||||||
|
onScanArtifactsLength: number = 0;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private errorHandlerService: ErrorHandler,
|
private errorHandlerService: ErrorHandler,
|
||||||
private userPermissionService: UserPermissionService,
|
private userPermissionService: UserPermissionService,
|
||||||
@ -731,6 +735,7 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
|||||||
forkJoin(...this.deleteArtifactobservableLists).subscribe((deleteResult) => {
|
forkJoin(...this.deleteArtifactobservableLists).subscribe((deleteResult) => {
|
||||||
let deleteSuccessList = [];
|
let deleteSuccessList = [];
|
||||||
let deleteErrorList = [];
|
let deleteErrorList = [];
|
||||||
|
this.deleteArtifactobservableLists = [];
|
||||||
deleteResult.forEach(result => {
|
deleteResult.forEach(result => {
|
||||||
if (!result) {
|
if (!result) {
|
||||||
// delete success
|
// delete success
|
||||||
@ -739,9 +744,9 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
|||||||
deleteErrorList.push(result);
|
deleteErrorList.push(result);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.selectedRow = [];
|
||||||
if (deleteSuccessList.length === deleteResult.length) {
|
if (deleteSuccessList.length === deleteResult.length) {
|
||||||
// all is success
|
// all is success
|
||||||
this.selectedRow = [];
|
|
||||||
let st: ClrDatagridStateInterface = { page: {from: 0, to: this.pageSize - 1, size: this.pageSize} };
|
let st: ClrDatagridStateInterface = { page: {from: 0, to: this.pageSize - 1, size: this.pageSize} };
|
||||||
this.clrLoad(st);
|
this.clrLoad(st);
|
||||||
} else if (deleteErrorList.length === deleteResult.length) {
|
} else if (deleteErrorList.length === deleteResult.length) {
|
||||||
@ -752,7 +757,6 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
|||||||
// some artifact delete success but it has error delete things
|
// some artifact delete success but it has error delete things
|
||||||
this.errorHandlerService.error(deleteErrorList[deleteErrorList.length - 1].error);
|
this.errorHandlerService.error(deleteErrorList[deleteErrorList.length - 1].error);
|
||||||
// if delete one success refresh list
|
// if delete one success refresh list
|
||||||
this.selectedRow = [];
|
|
||||||
let st: ClrDatagridStateInterface = { page: {from: 0, to: this.pageSize - 1, size: this.pageSize} };
|
let st: ClrDatagridStateInterface = { page: {from: 0, to: this.pageSize - 1, size: this.pageSize} };
|
||||||
this.clrLoad(st);
|
this.clrLoad(st);
|
||||||
}
|
}
|
||||||
@ -871,10 +875,16 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
// Trigger scan
|
// Trigger scan
|
||||||
scanNow(): void {
|
scanNow(): void {
|
||||||
if (this.selectedRow && this.selectedRow.length === 1) {
|
if (!this.selectedRow.length) {
|
||||||
this.onSendingScanCommand = true;
|
return;
|
||||||
this.channel.publishScanEvent(this.repoName + "/" + this.selectedRow[0].digest);
|
|
||||||
}
|
}
|
||||||
|
this.scanFiinishArtifactLength = 0;
|
||||||
|
this.onScanArtifactsLength = this.selectedRow.length;
|
||||||
|
this.onSendingScanCommand = true;
|
||||||
|
this.selectedRow.forEach((data: any) => {
|
||||||
|
let digest = data.digest;
|
||||||
|
this.channel.publishScanEvent(this.repoName + "/" + digest);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
selectedRowHasVul(): boolean {
|
selectedRowHasVul(): boolean {
|
||||||
return !!(this.selectedRow
|
return !!(this.selectedRow
|
||||||
@ -886,7 +896,11 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
|||||||
return !!(artifact && artifact.addition_links && artifact.addition_links[ADDITIONS.VULNERABILITIES]);
|
return !!(artifact && artifact.addition_links && artifact.addition_links[ADDITIONS.VULNERABILITIES]);
|
||||||
}
|
}
|
||||||
submitFinish(e: boolean) {
|
submitFinish(e: boolean) {
|
||||||
this.onSendingScanCommand = e;
|
this.scanFiinishArtifactLength += 1;
|
||||||
|
// all selected scan action has start
|
||||||
|
if (this.scanFiinishArtifactLength === this.onScanArtifactsLength) {
|
||||||
|
this.onSendingScanCommand = e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// pull command
|
// pull command
|
||||||
onCpError($event: any): void {
|
onCpError($event: any): void {
|
||||||
|
@ -91,7 +91,10 @@ export class ArtifactVulnerabilitiesComponent implements OnInit, OnDestroy {
|
|||||||
this.hasShowLoading = true;
|
this.hasShowLoading = true;
|
||||||
}
|
}
|
||||||
this.additionsService.getDetailByLink(this.vulnerabilitiesLink.href)
|
this.additionsService.getDetailByLink(this.vulnerabilitiesLink.href)
|
||||||
.pipe(finalize(() => this.loading = false))
|
.pipe(finalize(() => {
|
||||||
|
this.loading = false;
|
||||||
|
this.hasShowLoading = false;
|
||||||
|
}))
|
||||||
.subscribe(
|
.subscribe(
|
||||||
res => {
|
res => {
|
||||||
this.scan_overview = res;
|
this.scan_overview = res;
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
<artifact-common-properties [artifactDetails]="artifact"></artifact-common-properties>
|
<artifact-common-properties [artifactDetails]="artifact"></artifact-common-properties>
|
||||||
|
|
||||||
<!-- tags -->
|
<!-- tags -->
|
||||||
<artifact-tag [artifactDetails]="artifact" [projectName]="projectName" [repositoryName]="repositoryName"
|
<artifact-tag [artifactDetails]="artifact" [projectName]="projectName" [projectId]="projectId" [repositoryName]="repositoryName"
|
||||||
(refreshArtifact)="refreshArtifact()"></artifact-tag>
|
(refreshArtifact)="refreshArtifact()"></artifact-tag>
|
||||||
|
|
||||||
<!-- Additions -->
|
<!-- Additions -->
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<button type="button" class="btn btn-secondary" (click)="addTag()">
|
<button type="button" class="btn btn-secondary" (click)="addTag()">
|
||||||
<clr-icon shape="plus" size="16"></clr-icon> {{'TAG.ADD_TAG' | translate}}
|
<clr-icon shape="plus" size="16"></clr-icon> {{'TAG.ADD_TAG' | translate}}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-secondary" [disabled]="!(selectedRow.length>=1)" (click)="removeTag()">
|
<button type="button" class="btn btn-secondary" [disabled]="!(selectedRow.length>=1&& !hasImmutableOnTag() && hasDeleteTagPermission)" (click)="removeTag()">
|
||||||
<clr-icon shape="trash" size="16"></clr-icon> {{'TAG.REMOVE_TAG' | translate}}
|
<clr-icon shape="trash" size="16"></clr-icon> {{'TAG.REMOVE_TAG' | translate}}
|
||||||
</button>
|
</button>
|
||||||
<form #tagForm="ngForm" [hidden]="!newTagformShow" class="label-form stack-block-label">
|
<form #tagForm="ngForm" [hidden]="!newTagformShow" class="label-form stack-block-label">
|
||||||
@ -46,7 +46,7 @@
|
|||||||
<span *ngIf="tag.immutable" class="label label-info ml-8">{{'REPOSITORY.IMMUTABLE' | translate}}</span>
|
<span *ngIf="tag.immutable" class="label label-info ml-8">{{'REPOSITORY.IMMUTABLE' | translate}}</span>
|
||||||
</div>
|
</div>
|
||||||
</clr-dg-cell>
|
</clr-dg-cell>
|
||||||
<clr-dg-cell [ngSwitch]="tag.signature != null">
|
<clr-dg-cell [ngSwitch]="tag.signed">
|
||||||
<div class="cell">
|
<div class="cell">
|
||||||
<clr-icon shape="check-circle" *ngSwitchCase="true" size="20" class="color-green"></clr-icon>
|
<clr-icon shape="check-circle" *ngSwitchCase="true" size="20" class="color-green"></clr-icon>
|
||||||
<clr-icon shape="times-circle" *ngSwitchCase="false" size="16" class="color-red"></clr-icon>
|
<clr-icon shape="times-circle" *ngSwitchCase="false" size="16" class="color-red"></clr-icon>
|
||||||
|
@ -10,6 +10,7 @@ import { ErrorHandler } from "../../../../../lib/utils/error-handler";
|
|||||||
import { ArtifactService } from '../../../../../../ng-swagger-gen/services/artifact.service';
|
import { ArtifactService } from '../../../../../../ng-swagger-gen/services/artifact.service';
|
||||||
import { OperationService } from "../../../../../lib/components/operation/operation.service";
|
import { OperationService } from "../../../../../lib/components/operation/operation.service";
|
||||||
import { CURRENT_BASE_HREF } from "../../../../../lib/utils/utils";
|
import { CURRENT_BASE_HREF } from "../../../../../lib/utils/utils";
|
||||||
|
import { USERSTATICPERMISSION, UserPermissionService, UserPermissionDefaultService } from '../../../../../lib/services';
|
||||||
|
|
||||||
|
|
||||||
describe('ArtifactTagComponent', () => {
|
describe('ArtifactTagComponent', () => {
|
||||||
@ -25,6 +26,11 @@ describe('ArtifactTagComponent', () => {
|
|||||||
const config: IServiceConfig = {
|
const config: IServiceConfig = {
|
||||||
repositoryBaseEndpoint: CURRENT_BASE_HREF + "/repositories/testing"
|
repositoryBaseEndpoint: CURRENT_BASE_HREF + "/repositories/testing"
|
||||||
};
|
};
|
||||||
|
let userPermissionService;
|
||||||
|
const permissions = [
|
||||||
|
{ resource: USERSTATICPERMISSION.REPOSITORY_TAG.KEY, action: USERSTATICPERMISSION.REPOSITORY_TAG.VALUE.DELETE },
|
||||||
|
];
|
||||||
|
let mockHasDeleteImagePermission: boolean = true;
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [
|
imports: [
|
||||||
@ -41,6 +47,7 @@ describe('ArtifactTagComponent', () => {
|
|||||||
{ provide: SERVICE_CONFIG, useValue: config },
|
{ provide: SERVICE_CONFIG, useValue: config },
|
||||||
{ provide: mockErrorHandler, useValue: ErrorHandler },
|
{ provide: mockErrorHandler, useValue: ErrorHandler },
|
||||||
{ provide: ArtifactService, useValue: mockArtifactService },
|
{ provide: ArtifactService, useValue: mockArtifactService },
|
||||||
|
{ provide: UserPermissionService, useClass: UserPermissionDefaultService },
|
||||||
{ provide: OperationService },
|
{ provide: OperationService },
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
@ -50,6 +57,11 @@ describe('ArtifactTagComponent', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(ArtifactTagComponent);
|
fixture = TestBed.createComponent(ArtifactTagComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
|
userPermissionService = fixture.debugElement.injector.get(UserPermissionService);
|
||||||
|
spyOn(userPermissionService, "hasProjectPermissions")
|
||||||
|
.withArgs(component.projectId, permissions)
|
||||||
|
.and.returnValue(of([
|
||||||
|
mockHasDeleteImagePermission]));
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -17,7 +17,10 @@ import { errorHandler } from "../../../../../lib/utils/shared/shared.utils";
|
|||||||
import { ArtifactFront as Artifact } from "../artifact";
|
import { ArtifactFront as Artifact } from "../artifact";
|
||||||
import { ArtifactService } from '../../../../../../ng-swagger-gen/services/artifact.service';
|
import { ArtifactService } from '../../../../../../ng-swagger-gen/services/artifact.service';
|
||||||
import { Tag } from '../../../../../../ng-swagger-gen/models/tag';
|
import { Tag } from '../../../../../../ng-swagger-gen/models/tag';
|
||||||
|
import {
|
||||||
|
|
||||||
|
UserPermissionService, USERSTATICPERMISSION
|
||||||
|
} from "../../../../../lib/services";
|
||||||
class InitTag {
|
class InitTag {
|
||||||
name = "";
|
name = "";
|
||||||
}
|
}
|
||||||
@ -30,6 +33,7 @@ class InitTag {
|
|||||||
export class ArtifactTagComponent implements OnInit {
|
export class ArtifactTagComponent implements OnInit {
|
||||||
@Input() artifactDetails: Artifact;
|
@Input() artifactDetails: Artifact;
|
||||||
@Input() projectName: string;
|
@Input() projectName: string;
|
||||||
|
@Input() projectId: number;
|
||||||
@Input() repositoryName: string;
|
@Input() repositoryName: string;
|
||||||
@Output() refreshArtifact = new EventEmitter();
|
@Output() refreshArtifact = new EventEmitter();
|
||||||
newTagName = new InitTag();
|
newTagName = new InitTag();
|
||||||
@ -43,15 +47,25 @@ export class ArtifactTagComponent implements OnInit {
|
|||||||
availableTime = AVAILABLE_TIME;
|
availableTime = AVAILABLE_TIME;
|
||||||
@ViewChild("confirmationDialog", { static: false })
|
@ViewChild("confirmationDialog", { static: false })
|
||||||
confirmationDialog: ConfirmationDialogComponent;
|
confirmationDialog: ConfirmationDialogComponent;
|
||||||
|
hasDeleteTagPermission: boolean;
|
||||||
constructor(
|
constructor(
|
||||||
private operationService: OperationService,
|
private operationService: OperationService,
|
||||||
private artifactService: ArtifactService,
|
private artifactService: ArtifactService,
|
||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
|
private userPermissionService: UserPermissionService,
|
||||||
private errorHandlerService: ErrorHandler
|
private errorHandlerService: ErrorHandler
|
||||||
|
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
this.getImagePermissionRule(this.projectId);
|
||||||
|
}
|
||||||
|
getImagePermissionRule(projectId: number): void {
|
||||||
|
const permissions = [
|
||||||
|
{ resource: USERSTATICPERMISSION.REPOSITORY_TAG.KEY, action: USERSTATICPERMISSION.REPOSITORY_TAG.VALUE.DELETE }
|
||||||
|
];
|
||||||
|
this.userPermissionService.hasProjectPermissions(this.projectId, permissions).subscribe((results: Array<boolean>) => {
|
||||||
|
this.hasDeleteTagPermission = results[0];
|
||||||
|
}, error => this.errorHandlerService.error(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
addTag() {
|
addTag() {
|
||||||
@ -166,4 +180,8 @@ export class ArtifactTagComponent implements OnInit {
|
|||||||
this.openTag = !this.openTag;
|
this.openTag = !this.openTag;
|
||||||
this.newTagformShow = false;
|
this.newTagformShow = false;
|
||||||
}
|
}
|
||||||
|
hasImmutableOnTag(): boolean {
|
||||||
|
return this.selectedRow.some((artifact) => artifact.immutable);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -68,8 +68,9 @@ export class ListRepositoryROComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
public gotoLink(projectId: number, repoName: string): void {
|
public gotoLink(projectId: number, repoName: string): void {
|
||||||
this.searchTrigger.closeSearch(true);
|
this.searchTrigger.closeSearch(true);
|
||||||
|
let projectName = repoName.split('/')[0];
|
||||||
let linkUrl = ['harbor', 'tags', projectId, repoName];
|
let repositorieName = projectName ? repoName.split(`${projectName}/`)[1] : repoName;
|
||||||
|
let linkUrl = ['harbor', 'projects', projectId, 'repositories', repositorieName ];
|
||||||
this.router.navigate(linkUrl);
|
this.router.navigate(linkUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,7 +693,7 @@
|
|||||||
"ADD_LABEL_TO_IMAGE": "Add labels to this image",
|
"ADD_LABEL_TO_IMAGE": "Add labels to this image",
|
||||||
"FILTER_BY_LABEL": "Filter images by label",
|
"FILTER_BY_LABEL": "Filter images by label",
|
||||||
"FILTER_ARTIFACT_BY_LABEL": "Filter actifact by label",
|
"FILTER_ARTIFACT_BY_LABEL": "Filter actifact by label",
|
||||||
"ADD_LABELS": "Add labels",
|
"ADD_LABELS": "Add Labels",
|
||||||
"RETAG": "Copy",
|
"RETAG": "Copy",
|
||||||
"ACTION": "ACTION",
|
"ACTION": "ACTION",
|
||||||
"DEPLOY": "DEPLOY",
|
"DEPLOY": "DEPLOY",
|
||||||
|
@ -694,7 +694,7 @@
|
|||||||
"ADD_LABEL_TO_IMAGE": "Add labels to this image",
|
"ADD_LABEL_TO_IMAGE": "Add labels to this image",
|
||||||
"FILTER_BY_LABEL": "Filter images by label",
|
"FILTER_BY_LABEL": "Filter images by label",
|
||||||
"FILTER_ARTIFACT_BY_LABEL": "Filter actifact by label",
|
"FILTER_ARTIFACT_BY_LABEL": "Filter actifact by label",
|
||||||
"ADD_LABELS": "Add labels",
|
"ADD_LABELS": "Add Labels",
|
||||||
"RETAG": "Copy",
|
"RETAG": "Copy",
|
||||||
"ACTION": "ACTION",
|
"ACTION": "ACTION",
|
||||||
"DEPLOY": "DEPLOY",
|
"DEPLOY": "DEPLOY",
|
||||||
|
@ -680,7 +680,7 @@
|
|||||||
"ADD_LABEL_TO_IMAGE": "Add labels to this image",
|
"ADD_LABEL_TO_IMAGE": "Add labels to this image",
|
||||||
"FILTER_BY_LABEL": "Filter images by label",
|
"FILTER_BY_LABEL": "Filter images by label",
|
||||||
"FILTER_ARTIFACT_BY_LABEL": "Filter actifact by label",
|
"FILTER_ARTIFACT_BY_LABEL": "Filter actifact by label",
|
||||||
"ADD_LABELS": "Add labels",
|
"ADD_LABELS": "Add Labels",
|
||||||
"RETAG": "Copy",
|
"RETAG": "Copy",
|
||||||
"ACTION": "ACTION",
|
"ACTION": "ACTION",
|
||||||
"DEPLOY": "DEPLOY",
|
"DEPLOY": "DEPLOY",
|
||||||
|
@ -693,7 +693,7 @@
|
|||||||
"ADD_LABEL_TO_IMAGE": "Adicionar labels a essa imagem",
|
"ADD_LABEL_TO_IMAGE": "Adicionar labels a essa imagem",
|
||||||
"FILTER_BY_LABEL": "Filtrar imagens por label",
|
"FILTER_BY_LABEL": "Filtrar imagens por label",
|
||||||
"FILTER_ARTIFACT_BY_LABEL": "Filter actifact by label",
|
"FILTER_ARTIFACT_BY_LABEL": "Filter actifact by label",
|
||||||
"ADD_LABELS": "Adicionar labels",
|
"ADD_LABELS": "Adicionar Labels",
|
||||||
"RETAG": "Copy",
|
"RETAG": "Copy",
|
||||||
"ACTION": "AÇÃO",
|
"ACTION": "AÇÃO",
|
||||||
"DEPLOY": "DEPLOY",
|
"DEPLOY": "DEPLOY",
|
||||||
|
@ -2,29 +2,33 @@
|
|||||||
<div class="normal-wrapper">
|
<div class="normal-wrapper">
|
||||||
<span [style.width]="buttonMarginLeft" class="font-style">{{ labelCurrent | translate }}</span>
|
<span [style.width]="buttonMarginLeft" class="font-style">{{ labelCurrent | translate }}</span>
|
||||||
<span>{{(originScheduleType ? 'SCHEDULE.'+ originScheduleType.toUpperCase(): "") | translate}}</span>
|
<span>{{(originScheduleType ? 'SCHEDULE.'+ originScheduleType.toUpperCase(): "") | translate}}</span>
|
||||||
<a [hidden]="originScheduleType!==SCHEDULE_TYPE.HOURLY" href="javascript:void(0)" role="tooltip" aria-haspopup="true" class="tooltip tooltip-top-right">
|
<a [hidden]="originScheduleType!==SCHEDULE_TYPE.HOURLY" href="javascript:void(0)" role="tooltip"
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
aria-haspopup="true" class="tooltip tooltip-top-right">
|
||||||
<span class="tooltip-content">{{'CONFIG.TOOLTIP.HOURLY_CRON' | translate}}</span>
|
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
||||||
|
<span class="tooltip-content">{{'CONFIG.TOOLTIP.HOURLY_CRON' | translate}}</span>
|
||||||
</a>
|
</a>
|
||||||
<a [hidden]="originScheduleType!==SCHEDULE_TYPE.WEEKLY" href="javascript:void(0)" role="tooltip" aria-haspopup="true" class="tooltip tooltip-top-right">
|
<a [hidden]="originScheduleType!==SCHEDULE_TYPE.WEEKLY" href="javascript:void(0)" role="tooltip"
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
aria-haspopup="true" class="tooltip tooltip-top-right">
|
||||||
<span class="tooltip-content">{{'CONFIG.TOOLTIP.WEEKLY_CRON' | translate}}</span>
|
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
||||||
|
<span class="tooltip-content">{{'CONFIG.TOOLTIP.WEEKLY_CRON' | translate}}</span>
|
||||||
</a>
|
</a>
|
||||||
<a [hidden]="originScheduleType!==SCHEDULE_TYPE.DAILY" href="javascript:void(0)" role="tooltip" aria-haspopup="true" class="tooltip tooltip-top-right">
|
<a [hidden]="originScheduleType!==SCHEDULE_TYPE.DAILY" href="javascript:void(0)" role="tooltip" aria-haspopup="true"
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
class="tooltip tooltip-top-right">
|
||||||
<span class="tooltip-content">{{'CONFIG.TOOLTIP.DAILY_CRON' | translate}}</span>
|
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
||||||
|
<span class="tooltip-content">{{'CONFIG.TOOLTIP.DAILY_CRON' | translate}}</span>
|
||||||
</a>
|
</a>
|
||||||
<span [hidden]="originScheduleType!==SCHEDULE_TYPE.CUSTOM">{{ "SCHEDULE.CRON" | translate }} :</span>
|
<span [hidden]="originScheduleType!==SCHEDULE_TYPE.CUSTOM">{{ "SCHEDULE.CRON" | translate }} :</span>
|
||||||
<span [hidden]="originScheduleType!==SCHEDULE_TYPE.CUSTOM">{{ oriCron }}</span>
|
<span [hidden]="originScheduleType!==SCHEDULE_TYPE.CUSTOM">{{ oriCron }}</span>
|
||||||
</div>
|
</div>
|
||||||
<button [style.margin-left]="buttonMarginLeft" [disabled]="disabled" class="btn btn-primary " (click)="editSchedule()" id="editSchedule">
|
<button [style.margin-left]="buttonMarginLeft" [disabled]="disabled" class="btn btn-primary " (click)="editSchedule()"
|
||||||
|
id="editSchedule">
|
||||||
{{ "BUTTON.EDIT" | translate }}
|
{{ "BUTTON.EDIT" | translate }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-wrapper flex-layout" *ngIf="isEditMode">
|
<div class="setting-wrapper flex-layout" *ngIf="isEditMode">
|
||||||
<span [style.width]="buttonMarginLeft" class="font-style">{{ labelEdit | translate }}</span>
|
<span [style.width]="buttonMarginLeft" class="font-style">{{ labelEdit | translate }}</span>
|
||||||
<div class="select select-schedule clr-select-wrapper">
|
<div class="select select-schedule clr-select-wrapper">
|
||||||
<select name="selectPolicy" id="selectPolicy" [(ngModel)]="scheduleType">
|
<select name="selectPolicy" id="selectPolicy" [(ngModel)]="scheduleType">
|
||||||
<option [value]="SCHEDULE_TYPE.NONE">{{'SCHEDULE.NONE' | translate}}</option>
|
<option [value]="SCHEDULE_TYPE.NONE">{{'SCHEDULE.NONE' | translate}}</option>
|
||||||
<option [value]="SCHEDULE_TYPE.HOURLY">{{'SCHEDULE.HOURLY' | translate}}</option>
|
<option [value]="SCHEDULE_TYPE.HOURLY">{{'SCHEDULE.HOURLY' | translate}}</option>
|
||||||
<option [value]="SCHEDULE_TYPE.DAILY">{{'SCHEDULE.DAILY' | translate}}</option>
|
<option [value]="SCHEDULE_TYPE.DAILY">{{'SCHEDULE.DAILY' | translate}}</option>
|
||||||
@ -34,27 +38,26 @@
|
|||||||
</div>
|
</div>
|
||||||
<span class="required" [hidden]="scheduleType!==SCHEDULE_TYPE.CUSTOM">{{ "SCHEDULE.CRON" | translate }}</span>
|
<span class="required" [hidden]="scheduleType!==SCHEDULE_TYPE.CUSTOM">{{ "SCHEDULE.CRON" | translate }}</span>
|
||||||
<div [hidden]="scheduleType!==SCHEDULE_TYPE.CUSTOM" class="cron-input">
|
<div [hidden]="scheduleType!==SCHEDULE_TYPE.CUSTOM" class="cron-input">
|
||||||
<label for="targetCron" aria-haspopup="true" role="tooltip" [class.invalid]="dateInvalid" class="tooltip tooltip-validation tooltip-md tooltip-top-left cron-label">
|
<label for="targetCron" aria-haspopup="true" role="tooltip" [class.clr-error]="dateInvalid"
|
||||||
<input type="text" (blur)="blurInvalid()" (input)="inputInvalid()" name=targetCron id="targetCron" #cronStringInput="ngModel" required class="clr-input form-control"
|
class="tooltip tooltip-validation tooltip-md tooltip-top-left cron-label">
|
||||||
[(ngModel)]="cronString">
|
<input type="text" (blur)="blurInvalid()" (input)="inputInvalid()" name="targetCron" id="targetCron"
|
||||||
<span class="tooltip-content" *ngIf="dateInvalid">
|
#cronStringInput="ngModel" required class="clr-input form-control" [(ngModel)]="cronString">
|
||||||
{{'TOOLTIP.CRON_REQUIRED' | translate }}
|
<clr-control-error *ngIf="dateInvalid">{{'TOOLTIP.CRON_REQUIRED' | translate}}</clr-control-error>
|
||||||
</span>
|
|
||||||
</label>
|
</label>
|
||||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true" class="tooltip tooltip-lg tooltip-right top-7 cron-tooltip">
|
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true"
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
class="tooltip tooltip-lg tooltip-right top-7 cron-tooltip">
|
||||||
<div class="tooltip-content table-box">
|
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
||||||
<cron-tooltip></cron-tooltip>
|
<div class="tooltip-content table-box">
|
||||||
</div>
|
<cron-tooltip></cron-tooltip>
|
||||||
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="confirm-button">
|
<div class="confirm-button">
|
||||||
<button [style.margin-left]="buttonMarginLeft" class="btn btn-primary "
|
<button [style.margin-left]="buttonMarginLeft" class="btn btn-primary " (click)="save()" id="config-save">
|
||||||
(click)="save()" id="config-save">
|
{{ "BUTTON.SAVE" | translate }}
|
||||||
{{ "BUTTON.SAVE" | translate }}
|
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-primary " (click)="isEditMode=false">
|
<button class="btn btn-primary " (click)="isEditMode=false">
|
||||||
{{ "BUTTON.CANCEL" | translate }}
|
{{ "BUTTON.CANCEL" | translate }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -47,6 +47,7 @@
|
|||||||
.cron-tooltip {
|
.cron-tooltip {
|
||||||
color: gray;
|
color: gray;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
|
position: absolute;
|
||||||
.table-box {
|
.table-box {
|
||||||
width: 20rem;
|
width: 20rem;
|
||||||
}
|
}
|
||||||
|
@ -248,7 +248,7 @@ Add Labels To Tag
|
|||||||
Retry Element Click xpath=//clr-dg-row[contains(.,'${tagName}')]//label
|
Retry Element Click xpath=//clr-dg-row[contains(.,'${tagName}')]//label
|
||||||
Capture Page Screenshot add_${labelName}.png
|
Capture Page Screenshot add_${labelName}.png
|
||||||
Retry Element Click xpath=//clr-dg-action-bar//clr-dropdown//span
|
Retry Element Click xpath=//clr-dg-action-bar//clr-dropdown//span
|
||||||
Retry Element Click xpath=//clr-dropdown-menu//clr-dropdown//button[contains(.,'Add labels')]
|
Retry Element Click xpath=//clr-dropdown-menu//clr-dropdown//button[contains(.,'Add Labels')]
|
||||||
Retry Element Click xpath=//clr-dropdown//div//label[contains(.,'${labelName}')]
|
Retry Element Click xpath=//clr-dropdown//div//label[contains(.,'${labelName}')]
|
||||||
Retry Wait Until Page Contains Element xpath=//clr-dg-row//label[contains(.,'${labelName}')]
|
Retry Wait Until Page Contains Element xpath=//clr-dg-row//label[contains(.,'${labelName}')]
|
||||||
|
|
||||||
|
@ -76,6 +76,7 @@ Switch To Scanners Page
|
|||||||
|
|
||||||
Should Display The Default Clair Scanner
|
Should Display The Default Clair Scanner
|
||||||
Retry Wait Until Page Contains Element //clr-datagrid//clr-dg-row//clr-dg-cell[contains(.,'Clair')]//span[contains(.,'Default')]
|
Retry Wait Until Page Contains Element //clr-datagrid//clr-dg-row//clr-dg-cell[contains(.,'Clair')]//span[contains(.,'Default')]
|
||||||
|
|
||||||
Clair Is Immutable Scanner
|
Clair Is Immutable Scanner
|
||||||
Retry Element Click //clr-dg-row[contains(.,'Clair')]//clr-radio-wrapper/label
|
Retry Element Click //clr-dg-row[contains(.,'Clair')]//clr-radio-wrapper/label
|
||||||
Retry Double Keywords When Error Retry Element Click ${scanner_action_xpath} Retry Wait Until Page Contains Element ${delete_scanner_action_xpath}
|
Retry Double Keywords When Error Retry Element Click ${scanner_action_xpath} Retry Wait Until Page Contains Element ${delete_scanner_action_xpath}
|
||||||
|
Loading…
Reference in New Issue
Block a user