mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-25 18:18:04 +01:00
Merge pull request #11362 from jwangyangls/refact-artifact-tag
[OCI] Refact artifact tag
This commit is contained in:
commit
ceded08507
@ -95,7 +95,7 @@
|
|||||||
<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>
|
||||||
|
|
||||||
<clr-dropdown class="btn btn-link">
|
<clr-dropdown class="btn btn-link" *ngIf="!depth">
|
||||||
<span clrDropdownTrigger id="artifact-list-action" class="btn pl-0">
|
<span clrDropdownTrigger id="artifact-list-action" class="btn pl-0">
|
||||||
{{'BUTTON.ACTIONS' | translate}}
|
{{'BUTTON.ACTIONS' | translate}}
|
||||||
<clr-icon shape="caret down"></clr-icon>
|
<clr-icon shape="caret down"></clr-icon>
|
||||||
|
@ -248,9 +248,9 @@ describe("ArtifactListTabComponent (inline template)", () => {
|
|||||||
error: () => { }
|
error: () => { }
|
||||||
};
|
};
|
||||||
const permissions = [
|
const permissions = [
|
||||||
{ resource: USERSTATICPERMISSION.REPOSITORY_TAG_LABEL.KEY, action: USERSTATICPERMISSION.REPOSITORY_TAG_LABEL.VALUE.CREATE },
|
{ resource: USERSTATICPERMISSION.REPOSITORY_ARTIFACT_LABEL.KEY, action: USERSTATICPERMISSION.REPOSITORY_ARTIFACT_LABEL.VALUE.CREATE },
|
||||||
{ resource: USERSTATICPERMISSION.REPOSITORY.KEY, action: USERSTATICPERMISSION.REPOSITORY.VALUE.PULL },
|
{ resource: USERSTATICPERMISSION.REPOSITORY.KEY, action: USERSTATICPERMISSION.REPOSITORY.VALUE.PULL },
|
||||||
{ resource: USERSTATICPERMISSION.REPOSITORY_TAG.KEY, action: USERSTATICPERMISSION.REPOSITORY_TAG.VALUE.DELETE },
|
{ resource: USERSTATICPERMISSION.ARTIFACT.KEY, action: USERSTATICPERMISSION.ARTIFACT.VALUE.DELETE },
|
||||||
{ resource: USERSTATICPERMISSION.REPOSITORY_TAG_SCAN_JOB.KEY, action: USERSTATICPERMISSION.REPOSITORY_TAG_SCAN_JOB.VALUE.CREATE },
|
{ resource: USERSTATICPERMISSION.REPOSITORY_TAG_SCAN_JOB.KEY, action: USERSTATICPERMISSION.REPOSITORY_TAG_SCAN_JOB.VALUE.CREATE },
|
||||||
];
|
];
|
||||||
const mockRouter = {
|
const mockRouter = {
|
||||||
|
@ -848,9 +848,9 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
getImagePermissionRule(projectId: number): void {
|
getImagePermissionRule(projectId: number): void {
|
||||||
const permissions = [
|
const permissions = [
|
||||||
{ resource: USERSTATICPERMISSION.REPOSITORY_TAG_LABEL.KEY, action: USERSTATICPERMISSION.REPOSITORY_TAG_LABEL.VALUE.CREATE },
|
{ resource: USERSTATICPERMISSION.REPOSITORY_ARTIFACT_LABEL.KEY, action: USERSTATICPERMISSION.REPOSITORY_ARTIFACT_LABEL.VALUE.CREATE },
|
||||||
{ resource: USERSTATICPERMISSION.REPOSITORY.KEY, action: USERSTATICPERMISSION.REPOSITORY.VALUE.PULL },
|
{ resource: USERSTATICPERMISSION.REPOSITORY.KEY, action: USERSTATICPERMISSION.REPOSITORY.VALUE.PULL },
|
||||||
{ resource: USERSTATICPERMISSION.REPOSITORY_TAG.KEY, action: USERSTATICPERMISSION.REPOSITORY_TAG.VALUE.DELETE },
|
{ resource: USERSTATICPERMISSION.ARTIFACT.KEY, action: USERSTATICPERMISSION.ARTIFACT.VALUE.DELETE },
|
||||||
{ resource: USERSTATICPERMISSION.REPOSITORY_TAG_SCAN_JOB.KEY, action: USERSTATICPERMISSION.REPOSITORY_TAG_SCAN_JOB.VALUE.CREATE },
|
{ resource: USERSTATICPERMISSION.REPOSITORY_TAG_SCAN_JOB.KEY, action: USERSTATICPERMISSION.REPOSITORY_TAG_SCAN_JOB.VALUE.CREATE },
|
||||||
];
|
];
|
||||||
this.userPermissionService.hasProjectPermissions(this.projectId, permissions).subscribe((results: Array<boolean>) => {
|
this.userPermissionService.hasProjectPermissions(this.projectId, permissions).subscribe((results: Array<boolean>) => {
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
<ng-container *ngIf="!loading">
|
<ng-container *ngIf="!loading">
|
||||||
<!-- tags -->
|
<!-- tags -->
|
||||||
<artifact-tag [artifactDetails]="artifact" [projectName]="projectName" [projectId]="projectId" [repositoryName]="repositoryName"
|
<artifact-tag [artifactDetails]="artifact" [projectName]="projectName" [projectId]="projectId" [repositoryName]="repositoryName"
|
||||||
(refreshArtifact)="refreshArtifact()"></artifact-tag>
|
></artifact-tag>
|
||||||
|
|
||||||
<!-- Overview -->
|
<!-- Overview -->
|
||||||
<artifact-common-properties [artifactDetails]="artifact"></artifact-common-properties>
|
<artifact-common-properties [artifactDetails]="artifact"></artifact-common-properties>
|
||||||
|
@ -91,9 +91,7 @@ export class ArtifactSummaryComponent implements OnInit {
|
|||||||
reference: this.artifactDigest,
|
reference: this.artifactDigest,
|
||||||
projectName: this.projectName,
|
projectName: this.projectName,
|
||||||
withLabel: true,
|
withLabel: true,
|
||||||
withScanOverview: true,
|
withScanOverview: true
|
||||||
withSignature: true,
|
|
||||||
withImmutableStatus: true
|
|
||||||
}).pipe(finalize(() => this.loading = false))
|
}).pipe(finalize(() => this.loading = false))
|
||||||
.subscribe(response => {
|
.subscribe(response => {
|
||||||
this.artifact = response;
|
this.artifact = response;
|
||||||
@ -105,8 +103,4 @@ export class ArtifactSummaryComponent implements OnInit {
|
|||||||
onBack(): void {
|
onBack(): void {
|
||||||
this.backEvt.emit(this.repositoryName);
|
this.backEvt.emit(this.repositoryName);
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshArtifact() {
|
|
||||||
this.getArtifactDetails();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
<h4>{{'REPOSITORY.TAGS_COUNT' | translate}}</h4>
|
<h4>{{'REPOSITORY.TAGS_COUNT' | translate}}</h4>
|
||||||
<clr-datagrid [clrDgLoading]="loading" [(clrDgSelected)]="selectedRow" [clrDgRowSelection]="true">
|
|
||||||
|
<clr-datagrid [clrDgLoading]="loading" (clrDgRefresh)="getCurrentArtifactTags($event)" [(clrDgSelected)]="selectedRow" [clrDgRowSelection]="true">
|
||||||
<clr-dg-action-bar>
|
<clr-dg-action-bar>
|
||||||
<button type="button" class="btn btn-secondary" (click)="addTag()">
|
<button type="button" [disabled]="!hasCreateTagPermission" 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&& !hasImmutableOnTag() && hasDeleteTagPermission)" (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>
|
||||||
|
<span class="refresh-btn" (click)="refresh()">
|
||||||
|
<clr-icon shape="refresh"></clr-icon>
|
||||||
|
</span>
|
||||||
<form #tagForm="ngForm" [hidden]="!newTagformShow" class="label-form stack-block-label">
|
<form #tagForm="ngForm" [hidden]="!newTagformShow" class="label-form stack-block-label">
|
||||||
<section>
|
<section>
|
||||||
<label>
|
<label>
|
||||||
@ -39,7 +43,7 @@
|
|||||||
<clr-dg-column>{{'TAG.PULL_TIME' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'TAG.PULL_TIME' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'TAG.PUSH_TIME' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'TAG.PUSH_TIME' | translate}}</clr-dg-column>
|
||||||
|
|
||||||
<clr-dg-row *clrDgItems="let tag of artifactDetails?.tags" [clrDgItem]="tag">
|
<clr-dg-row *ngFor="let tag of currentTags" [clrDgItem]="tag">
|
||||||
<clr-dg-cell>
|
<clr-dg-cell>
|
||||||
<div class="cell white-normal" [class.immutable]="tag.immutable">
|
<div class="cell white-normal" [class.immutable]="tag.immutable">
|
||||||
<span href="javascript:void(0)" class="max-width-100" title="{{tag.name}}">{{tag.name}}</span>
|
<span href="javascript:void(0)" class="max-width-100" title="{{tag.name}}">{{tag.name}}</span>
|
||||||
@ -61,9 +65,9 @@
|
|||||||
</clr-dg-row>
|
</clr-dg-row>
|
||||||
|
|
||||||
<clr-dg-footer>
|
<clr-dg-footer>
|
||||||
<span *ngIf="pagination.totalItems">{{pagination.firstItem + 1}} - {{pagination.lastItem + 1}}
|
<span *ngIf="totalCount">{{pagination.firstItem + 1}} - {{pagination.lastItem + 1}}
|
||||||
{{'TAG.OF' | translate}} {{pagination.totalItems}} {{'TAG.ITEMS' | translate}}</span>
|
{{'TAG.OF' | translate}} {{totalCount}} {{'TAG.ITEMS' | translate}}</span>
|
||||||
<clr-dg-pagination #pagination [clrDgPageSize]="10"></clr-dg-pagination>
|
<clr-dg-pagination #pagination [clrDgTotalItems]="totalCount" [(clrDgPage)]="currentPage" [clrDgPageSize]="pageSize"></clr-dg-pagination>
|
||||||
</clr-dg-footer>
|
</clr-dg-footer>
|
||||||
</clr-datagrid>
|
</clr-datagrid>
|
||||||
|
|
||||||
|
@ -25,3 +25,9 @@
|
|||||||
.position-ab {
|
.position-ab {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
.refresh-btn {
|
||||||
|
float: right;
|
||||||
|
margin-top: 15px;
|
||||||
|
margin-right: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
@ -11,6 +11,8 @@ import { ArtifactService } from '../../../../../../ng-swagger-gen/services/artif
|
|||||||
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';
|
import { USERSTATICPERMISSION, UserPermissionService, UserPermissionDefaultService } from '../../../../../lib/services';
|
||||||
|
import { TagService } from '../../../../../../ng-swagger-gen/services/tag.service';
|
||||||
|
import { delay } from 'rxjs/operators';
|
||||||
|
|
||||||
|
|
||||||
describe('ArtifactTagComponent', () => {
|
describe('ArtifactTagComponent', () => {
|
||||||
@ -19,6 +21,10 @@ describe('ArtifactTagComponent', () => {
|
|||||||
const mockErrorHandler = {
|
const mockErrorHandler = {
|
||||||
error: () => {}
|
error: () => {}
|
||||||
};
|
};
|
||||||
|
const mockTagService = {
|
||||||
|
listTagsResponse: () => of({headers: null, body: []}).pipe(delay(0)),
|
||||||
|
listTags: () => of([]),
|
||||||
|
};
|
||||||
const mockArtifactService = {
|
const mockArtifactService = {
|
||||||
createTag: () => of([]),
|
createTag: () => of([]),
|
||||||
deleteTag: () => of(null),
|
deleteTag: () => of(null),
|
||||||
@ -29,6 +35,7 @@ describe('ArtifactTagComponent', () => {
|
|||||||
let userPermissionService;
|
let userPermissionService;
|
||||||
const permissions = [
|
const permissions = [
|
||||||
{ resource: USERSTATICPERMISSION.REPOSITORY_TAG.KEY, action: USERSTATICPERMISSION.REPOSITORY_TAG.VALUE.DELETE },
|
{ resource: USERSTATICPERMISSION.REPOSITORY_TAG.KEY, action: USERSTATICPERMISSION.REPOSITORY_TAG.VALUE.DELETE },
|
||||||
|
{ resource: USERSTATICPERMISSION.REPOSITORY_TAG.KEY, action: USERSTATICPERMISSION.REPOSITORY_TAG.VALUE.CREATE },
|
||||||
];
|
];
|
||||||
let mockHasDeleteImagePermission: boolean = true;
|
let mockHasDeleteImagePermission: boolean = true;
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
@ -47,6 +54,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: TagService, useValue: mockTagService },
|
||||||
{ provide: UserPermissionService, useClass: UserPermissionDefaultService },
|
{ provide: UserPermissionService, useClass: UserPermissionDefaultService },
|
||||||
{ provide: OperationService },
|
{ provide: OperationService },
|
||||||
]
|
]
|
||||||
@ -62,6 +70,7 @@ describe('ArtifactTagComponent', () => {
|
|||||||
.withArgs(component.projectId, permissions)
|
.withArgs(component.projectId, permissions)
|
||||||
.and.returnValue(of([
|
.and.returnValue(of([
|
||||||
mockHasDeleteImagePermission]));
|
mockHasDeleteImagePermission]));
|
||||||
|
component.artifactDetails = {id: 1};
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Component, OnInit, Input, ViewChild, Output, EventEmitter } from '@angular/core';
|
import { Component, OnInit, Input, ViewChild, Output, EventEmitter } from '@angular/core';
|
||||||
import { Observable, of, forkJoin } from 'rxjs';
|
import { Observable, of, forkJoin } from 'rxjs';
|
||||||
import { map, catchError } from 'rxjs/operators';
|
import { map, catchError, finalize } from 'rxjs/operators';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { NgForm } from '@angular/forms';
|
import { NgForm } from '@angular/forms';
|
||||||
import { AVAILABLE_TIME } from "../../artifact-list-page/artifact-list/artifact-list-tab/artifact-list-tab.component";
|
import { AVAILABLE_TIME } from "../../artifact-list-page/artifact-list/artifact-list-tab/artifact-list-tab.component";
|
||||||
@ -16,11 +16,14 @@ import { operateChanges, OperateInfo, OperationState } from "../../../../../lib/
|
|||||||
import { errorHandler } from "../../../../../lib/utils/shared/shared.utils";
|
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 { TagService } from '../../../../../../ng-swagger-gen/services/tag.service';
|
||||||
import { Tag } from '../../../../../../ng-swagger-gen/models/tag';
|
import { Tag } from '../../../../../../ng-swagger-gen/models/tag';
|
||||||
import {
|
import {
|
||||||
|
|
||||||
UserPermissionService, USERSTATICPERMISSION
|
UserPermissionService, USERSTATICPERMISSION
|
||||||
} from "../../../../../lib/services";
|
} from "../../../../../lib/services";
|
||||||
|
import { ClrDatagridStateInterface } from '@clr/angular';
|
||||||
|
import { DEFAULT_PAGE_SIZE, calculatePage } from '../../../../../lib/utils/utils';
|
||||||
|
|
||||||
class InitTag {
|
class InitTag {
|
||||||
name = "";
|
name = "";
|
||||||
}
|
}
|
||||||
@ -35,22 +38,29 @@ export class ArtifactTagComponent implements OnInit {
|
|||||||
@Input() projectName: string;
|
@Input() projectName: string;
|
||||||
@Input() projectId: number;
|
@Input() projectId: number;
|
||||||
@Input() repositoryName: string;
|
@Input() repositoryName: string;
|
||||||
@Output() refreshArtifact = new EventEmitter();
|
|
||||||
newTagName = new InitTag();
|
newTagName = new InitTag();
|
||||||
newTagForm: NgForm;
|
newTagForm: NgForm;
|
||||||
@ViewChild("newTagForm", { static: true }) currentForm: NgForm;
|
@ViewChild("newTagForm", { static: true }) currentForm: NgForm;
|
||||||
selectedRow: Tag[] = [];
|
selectedRow: Tag[] = [];
|
||||||
isTagNameExist = false;
|
isTagNameExist = false;
|
||||||
newTagformShow = false;
|
newTagformShow = false;
|
||||||
loading = false;
|
loading = true;
|
||||||
openTag = false;
|
openTag = false;
|
||||||
availableTime = AVAILABLE_TIME;
|
availableTime = AVAILABLE_TIME;
|
||||||
@ViewChild("confirmationDialog", { static: false })
|
@ViewChild("confirmationDialog", { static: false })
|
||||||
confirmationDialog: ConfirmationDialogComponent;
|
confirmationDialog: ConfirmationDialogComponent;
|
||||||
hasDeleteTagPermission: boolean;
|
hasDeleteTagPermission: boolean;
|
||||||
|
hasCreateTagPermission: boolean;
|
||||||
|
|
||||||
|
totalCount: number = 0;
|
||||||
|
allTags: Tag[] = [];
|
||||||
|
currentTags: Tag[] = [];
|
||||||
|
pageSize: number = DEFAULT_PAGE_SIZE;
|
||||||
|
currentPage = 1;
|
||||||
constructor(
|
constructor(
|
||||||
private operationService: OperationService,
|
private operationService: OperationService,
|
||||||
private artifactService: ArtifactService,
|
private artifactService: ArtifactService,
|
||||||
|
private tagService: TagService,
|
||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
private userPermissionService: UserPermissionService,
|
private userPermissionService: UserPermissionService,
|
||||||
private errorHandlerService: ErrorHandler
|
private errorHandlerService: ErrorHandler
|
||||||
@ -58,13 +68,57 @@ export class ArtifactTagComponent implements OnInit {
|
|||||||
) { }
|
) { }
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.getImagePermissionRule(this.projectId);
|
this.getImagePermissionRule(this.projectId);
|
||||||
|
this.getAllTags();
|
||||||
|
}
|
||||||
|
getCurrentArtifactTags(state: ClrDatagridStateInterface) {
|
||||||
|
if (!state || !state.page) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
let pageNumber: number = calculatePage(state);
|
||||||
|
if (pageNumber <= 0) { pageNumber = 1; }
|
||||||
|
let params: TagService.ListTagsParams = {
|
||||||
|
projectName: this.projectName,
|
||||||
|
repositoryName: this.repositoryName,
|
||||||
|
page: pageNumber,
|
||||||
|
withSignature: true,
|
||||||
|
withImmutableStatus: true,
|
||||||
|
pageSize: this.pageSize,
|
||||||
|
q: encodeURIComponent(`artifact_id=${this.artifactDetails.id}`)
|
||||||
|
};
|
||||||
|
this.tagService.listTagsResponse(params).pipe(finalize(() => {
|
||||||
|
this.loading = false;
|
||||||
|
})).subscribe(res => {
|
||||||
|
if (res.headers) {
|
||||||
|
let xHeader: string = res.headers.get("x-total-count");
|
||||||
|
if (xHeader) {
|
||||||
|
this.totalCount = Number.parseInt(xHeader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.currentTags = res.body;
|
||||||
|
}, error => {
|
||||||
|
this.errorHandlerService.error(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
getAllTags() {
|
||||||
|
let params: TagService.ListTagsParams = {
|
||||||
|
projectName: this.projectName,
|
||||||
|
repositoryName: this.repositoryName
|
||||||
|
};
|
||||||
|
this.tagService.listTags(params).subscribe(res => {
|
||||||
|
this.allTags = res;
|
||||||
|
}, error => {
|
||||||
|
this.errorHandlerService.error(error);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
getImagePermissionRule(projectId: number): void {
|
getImagePermissionRule(projectId: number): void {
|
||||||
const permissions = [
|
const permissions = [
|
||||||
{ resource: USERSTATICPERMISSION.REPOSITORY_TAG.KEY, action: USERSTATICPERMISSION.REPOSITORY_TAG.VALUE.DELETE }
|
{ resource: USERSTATICPERMISSION.REPOSITORY_TAG.KEY, action: USERSTATICPERMISSION.REPOSITORY_TAG.VALUE.DELETE },
|
||||||
|
{ resource: USERSTATICPERMISSION.REPOSITORY_TAG.KEY, action: USERSTATICPERMISSION.REPOSITORY_TAG.VALUE.CREATE },
|
||||||
|
|
||||||
];
|
];
|
||||||
this.userPermissionService.hasProjectPermissions(this.projectId, permissions).subscribe((results: Array<boolean>) => {
|
this.userPermissionService.hasProjectPermissions(this.projectId, permissions).subscribe((results: Array<boolean>) => {
|
||||||
this.hasDeleteTagPermission = results[0];
|
this.hasDeleteTagPermission = results[0];
|
||||||
|
this.hasCreateTagPermission = results[1];
|
||||||
}, error => this.errorHandlerService.error(error));
|
}, error => this.errorHandlerService.error(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,11 +138,16 @@ export class ArtifactTagComponent implements OnInit {
|
|||||||
reference: this.artifactDetails.digest,
|
reference: this.artifactDetails.digest,
|
||||||
tag: this.newTagName
|
tag: this.newTagName
|
||||||
};
|
};
|
||||||
|
this.loading = true;
|
||||||
this.artifactService.createTag(createTagParams).subscribe(res => {
|
this.artifactService.createTag(createTagParams).subscribe(res => {
|
||||||
this.newTagformShow = false;
|
this.newTagformShow = false;
|
||||||
this.newTagName = new InitTag();
|
this.newTagName = new InitTag();
|
||||||
this.refreshArtifact.emit();
|
this.getAllTags();
|
||||||
|
this.currentPage = 1;
|
||||||
|
let st: ClrDatagridStateInterface = { page: {from: 0, to: this.pageSize - 1, size: this.pageSize} };
|
||||||
|
this.getCurrentArtifactTags(st);
|
||||||
}, error => {
|
}, error => {
|
||||||
|
this.loading = false;
|
||||||
this.errorHandlerService.error(error);
|
this.errorHandlerService.error(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -124,12 +183,36 @@ export class ArtifactTagComponent implements OnInit {
|
|||||||
tagList.forEach(tag => {
|
tagList.forEach(tag => {
|
||||||
observableLists.push(this.delOperate(tag));
|
observableLists.push(this.delOperate(tag));
|
||||||
});
|
});
|
||||||
|
this.loading = true;
|
||||||
forkJoin(...observableLists).subscribe((items) => {
|
forkJoin(...observableLists).subscribe((deleteResult) => {
|
||||||
// if delete one success refresh list
|
// if delete one success refresh list
|
||||||
if (items.some(item => !item)) {
|
let deleteSuccessList = [];
|
||||||
this.selectedRow = [];
|
let deleteErrorList = [];
|
||||||
this.refreshArtifact.emit();
|
deleteResult.forEach(result => {
|
||||||
|
if (!result) {
|
||||||
|
// delete success
|
||||||
|
deleteSuccessList.push(result);
|
||||||
|
} else {
|
||||||
|
deleteErrorList.push(result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.selectedRow = [];
|
||||||
|
if (deleteSuccessList.length === deleteResult.length) {
|
||||||
|
// all is success
|
||||||
|
this.currentPage = 1;
|
||||||
|
let st: ClrDatagridStateInterface = { page: {from: 0, to: this.pageSize - 1, size: this.pageSize} };
|
||||||
|
this.getCurrentArtifactTags(st);
|
||||||
|
} else if (deleteErrorList.length === deleteResult.length) {
|
||||||
|
// all is error
|
||||||
|
this.loading = false;
|
||||||
|
this.errorHandlerService.error(deleteResult[deleteResult.length - 1].error);
|
||||||
|
} else {
|
||||||
|
// some artifact delete success but it has error delete things
|
||||||
|
this.errorHandlerService.error(deleteErrorList[deleteErrorList.length - 1].error);
|
||||||
|
// if delete one success refresh list
|
||||||
|
this.currentPage = 1;
|
||||||
|
let st: ClrDatagridStateInterface = { page: {from: 0, to: this.pageSize - 1, size: this.pageSize} };
|
||||||
|
this.getCurrentArtifactTags(st);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -167,8 +250,8 @@ export class ArtifactTagComponent implements OnInit {
|
|||||||
|
|
||||||
existValid(name) {
|
existValid(name) {
|
||||||
this.isTagNameExist = false;
|
this.isTagNameExist = false;
|
||||||
if (this.artifactDetails.tags) {
|
if (this.allTags) {
|
||||||
this.artifactDetails.tags.forEach(tag => {
|
this.allTags.forEach(tag => {
|
||||||
if (tag.name === name) {
|
if (tag.name === name) {
|
||||||
this.isTagNameExist = true;
|
this.isTagNameExist = true;
|
||||||
}
|
}
|
||||||
@ -183,5 +266,10 @@ export class ArtifactTagComponent implements OnInit {
|
|||||||
hasImmutableOnTag(): boolean {
|
hasImmutableOnTag(): boolean {
|
||||||
return this.selectedRow.some((artifact) => artifact.immutable);
|
return this.selectedRow.some((artifact) => artifact.immutable);
|
||||||
}
|
}
|
||||||
|
refresh() {
|
||||||
|
this.loading = true;
|
||||||
|
this.currentPage = 1;
|
||||||
|
let st: ClrDatagridStateInterface = { page: {from: 0, to: this.pageSize - 1, size: this.pageSize} };
|
||||||
|
this.getCurrentArtifactTags(st);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,6 +116,12 @@ body {
|
|||||||
button:focus {
|
button:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
clr-dropdown {
|
||||||
|
div:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.w-100 {
|
.w-100 {
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
|
@ -13,6 +13,7 @@ export const USERSTATICPERMISSION = {
|
|||||||
"CREATE": "create",
|
"CREATE": "create",
|
||||||
"UPDATE": "update",
|
"UPDATE": "update",
|
||||||
"DELETE": "delete",
|
"DELETE": "delete",
|
||||||
|
"READ": "read",
|
||||||
"LIST": "list"
|
"LIST": "list"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -22,6 +23,7 @@ export const USERSTATICPERMISSION = {
|
|||||||
"LIST": "list"
|
"LIST": "list"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// to do remove
|
||||||
"REPLICATION": {
|
"REPLICATION": {
|
||||||
'KEY': 'replication',
|
'KEY': 'replication',
|
||||||
'VALUE': {
|
'VALUE': {
|
||||||
@ -31,6 +33,7 @@ export const USERSTATICPERMISSION = {
|
|||||||
"LIST": "list",
|
"LIST": "list",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// to do remove
|
||||||
"REPLICATION_JOB": {
|
"REPLICATION_JOB": {
|
||||||
'KEY': 'replication-job',
|
'KEY': 'replication-job',
|
||||||
'VALUE': {
|
'VALUE': {
|
||||||
@ -43,6 +46,7 @@ export const USERSTATICPERMISSION = {
|
|||||||
"CREATE": "create",
|
"CREATE": "create",
|
||||||
"UPDATE": "update",
|
"UPDATE": "update",
|
||||||
"DELETE": "delete",
|
"DELETE": "delete",
|
||||||
|
"READ": "read",
|
||||||
"LIST": "list",
|
"LIST": "list",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -67,43 +71,47 @@ export const USERSTATICPERMISSION = {
|
|||||||
"DELETE": "delete",
|
"DELETE": "delete",
|
||||||
"LIST": "list",
|
"LIST": "list",
|
||||||
"PUSH": "push",
|
"PUSH": "push",
|
||||||
|
"READ": "read",
|
||||||
"PULL": "pull",
|
"PULL": "pull",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ARTIFACT": {
|
||||||
|
'KEY': 'artifact',
|
||||||
|
'VALUE': {
|
||||||
|
"CREATE": "create",
|
||||||
|
"DELETE": "delete",
|
||||||
|
"LIST": "list",
|
||||||
|
"READ": "read",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ARTIFACT_ADDITION": {
|
||||||
|
'KEY': 'artifact-addition',
|
||||||
|
'VALUE': {
|
||||||
|
"READ": "read",
|
||||||
|
}
|
||||||
|
},
|
||||||
"REPOSITORY_TAG": {
|
"REPOSITORY_TAG": {
|
||||||
'KEY': 'repository-tag',
|
'KEY': 'tag',
|
||||||
'VALUE': {
|
'VALUE': {
|
||||||
"DELETE": "delete",
|
"DELETE": "delete",
|
||||||
"LIST": "list",
|
"LIST": "list",
|
||||||
|
"CREATE": "create"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"REPOSITORY_TAG_SCAN_JOB": {
|
"REPOSITORY_TAG_SCAN_JOB": {
|
||||||
'KEY': 'repository-tag-scan-job',
|
'KEY': 'scan',
|
||||||
'VALUE': {
|
'VALUE': {
|
||||||
"CREATE": "create",
|
"CREATE": "create",
|
||||||
"READ": "read",
|
"READ": "read",
|
||||||
"LIST": "list",
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"REPOSITORY_TAG_VULNERABILITY": {
|
"REPOSITORY_ARTIFACT_LABEL": {
|
||||||
'KEY': 'repository-tag-vulnerability',
|
'KEY': 'repository-artifact-label',
|
||||||
'VALUE': {
|
|
||||||
"LIST": "list",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"REPOSITORY_TAG_LABEL": {
|
|
||||||
'KEY': 'repository-tag-label',
|
|
||||||
'VALUE': {
|
'VALUE': {
|
||||||
"CREATE": "create",
|
"CREATE": "create",
|
||||||
"DELETE": "delete",
|
"DELETE": "delete",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"REPOSITORY_TAG_MANIFEST": {
|
|
||||||
'KEY': 'repository-tag-manifest',
|
|
||||||
'VALUE': {
|
|
||||||
"READ": "read",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"HELM_CHART": {
|
"HELM_CHART": {
|
||||||
'KEY': 'helm-chart',
|
'KEY': 'helm-chart',
|
||||||
'VALUE': {
|
'VALUE': {
|
||||||
@ -118,6 +126,7 @@ export const USERSTATICPERMISSION = {
|
|||||||
'VALUE': {
|
'VALUE': {
|
||||||
"DELETE": "delete",
|
"DELETE": "delete",
|
||||||
"LIST": "list",
|
"LIST": "list",
|
||||||
|
"CREATE": "create",
|
||||||
"READ": "read",
|
"READ": "read",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -146,8 +155,16 @@ export const USERSTATICPERMISSION = {
|
|||||||
"DELETE": "delete",
|
"DELETE": "delete",
|
||||||
"LIST": "list",
|
"LIST": "list",
|
||||||
"READ": "read",
|
"READ": "read",
|
||||||
"PULL": "pull",
|
"OPERATE": "operate"
|
||||||
"PUSH": "push"
|
}
|
||||||
|
},
|
||||||
|
"IMMUTABLE_TAG": {
|
||||||
|
'KEY': "immutable-tag",
|
||||||
|
'VALUE': {
|
||||||
|
"CREATE": "create",
|
||||||
|
"UPDATE": "update",
|
||||||
|
"DELETE": "delete",
|
||||||
|
"LIST": "list",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"WEBHOOK": {
|
"WEBHOOK": {
|
||||||
@ -155,6 +172,8 @@ export const USERSTATICPERMISSION = {
|
|||||||
"VALUE": {
|
"VALUE": {
|
||||||
"LIST": "list",
|
"LIST": "list",
|
||||||
"READ": "read",
|
"READ": "read",
|
||||||
|
"CREATE": "create",
|
||||||
|
"UPDATE": "update",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"SCANNER": {
|
"SCANNER": {
|
||||||
@ -163,6 +182,15 @@ export const USERSTATICPERMISSION = {
|
|||||||
"READ": "read",
|
"READ": "read",
|
||||||
"CREATE": "create"
|
"CREATE": "create"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"METADATA": {
|
||||||
|
"KEY": "metadata",
|
||||||
|
"VALUE": {
|
||||||
|
"READ": "read",
|
||||||
|
"CREATE": "create",
|
||||||
|
"UPDATE": "update",
|
||||||
|
"DELETE": "delete",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user