mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-19 07:07:42 +01:00
Fix bugs with label 'target 2.0.1'
Signed-off-by: AllForNothing <sshijun@vmware.com>
This commit is contained in:
parent
f5d482854b
commit
8bf77d01f4
@ -20,8 +20,7 @@ export class ScannerMetadataComponent implements OnInit {
|
||||
loading: boolean = false;
|
||||
scannerMetadata: ScannerMetadata;
|
||||
constructor(private configScannerService: ConfigScannerService,
|
||||
private errorHandler: ErrorHandler,
|
||||
private translate: TranslateService) {
|
||||
private errorHandler: ErrorHandler) {
|
||||
}
|
||||
ngOnInit(): void {
|
||||
this.loading = true;
|
||||
@ -35,7 +34,7 @@ export class ScannerMetadataComponent implements OnInit {
|
||||
}
|
||||
parseDate(item: any): string {
|
||||
if (this.hasValue(item) && this.hasDateValue(item)) {
|
||||
return new DatePipe(this.translate.currentLang).transform(item.value, 'short');
|
||||
return new DatePipe('en-us').transform(item.value, 'short');
|
||||
}
|
||||
if (this.hasValue(item)) {
|
||||
return item.value;
|
||||
|
@ -8,4 +8,4 @@
|
||||
</div>
|
||||
</clr-alert>
|
||||
</div>
|
||||
<div *ngIf="globalMessageOpened" class="mask-layer"></div>
|
||||
<div *ngIf="globalMessageOpened && needAuth" class="mask-layer"></div>
|
||||
|
@ -1,13 +1,12 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { Component, Input, OnInit, OnDestroy, ElementRef } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { Subscription } from "rxjs";
|
||||
import { ElementRef } from '@angular/core';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||
import { ClarityModule } from "@clr/angular";
|
||||
import { ClarityModule } from '@clr/angular';
|
||||
import { Message } from './message';
|
||||
import { MessageService } from './message.service';
|
||||
import { MessageComponent } from './message.component';
|
||||
import { AlertType } from '../shared/shared.const';
|
||||
|
||||
describe('MessageComponent', () => {
|
||||
let component: MessageComponent;
|
||||
@ -39,4 +38,22 @@ describe('MessageComponent', () => {
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should open mask layer when unauthorized', async () => {
|
||||
component.globalMessageOpened = true;
|
||||
component.globalMessage = Message.newMessage(401, "unauthorized", AlertType.DANGER);
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
const ele: HTMLDivElement = fixture.nativeElement.querySelector(".mask-layer");
|
||||
expect(ele).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should not open mask layer when it's not unauthorized", async () => {
|
||||
component.globalMessageOpened = true;
|
||||
component.globalMessage = Message.newMessage(403, "forbidden", AlertType.WARNING);
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
const ele: HTMLDivElement = fixture.nativeElement.querySelector(".mask-layer");
|
||||
expect(ele).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
@ -320,7 +320,12 @@ const harborRoutes: Routes = [
|
||||
}
|
||||
},
|
||||
component: ScannerComponent
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
redirectTo: 'repositories',
|
||||
pathMatch: 'full'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div class="breadcrumb">
|
||||
<a (click)="gotoProjectList()"> {{ 'SIDE_NAV.PROJECTS'| translate}} </a>
|
||||
<
|
||||
<a (click)="gotoChartList()">{{ 'HELM_CHART.HELMCHARTS'| translate}}</a>
|
||||
<a (click)="gotoChartList()">{{ projectName }}</a>
|
||||
<
|
||||
<a (click)="gotoChartVersion()">{{ 'HELM_CHART.CHARTVERSIONS'| translate}}</a>
|
||||
</div>
|
||||
|
@ -13,6 +13,7 @@ export class HelmChartDetailComponent implements OnInit {
|
||||
|
||||
projectId: number | string;
|
||||
project: Project;
|
||||
projectName: string;
|
||||
chartName: string;
|
||||
chartVersion: string;
|
||||
currentUser: SessionUser;
|
||||
@ -36,6 +37,7 @@ export class HelmChartDetailComponent implements OnInit {
|
||||
if (resolverData) {
|
||||
this.project = <Project>(resolverData["projectResolver"]);
|
||||
this.roleName = this.project.role_name;
|
||||
this.projectName = this.project.name;
|
||||
this.hasProjectAdminRole = this.project.has_project_admin_role;
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
<div *ngIf="readme" class="md-div" [innerHTML]="readme | markdown"></div>
|
||||
<div *ngIf="!readme">{{'HELM_CHART.NO_README' | translate}}</div>
|
||||
</div>
|
||||
<div class="col-md-4 summary-container">
|
||||
<div class="col-md-4 summary-container mt-1">
|
||||
<div class="col-md-12 content-group">
|
||||
<div>
|
||||
<label>{{'HELM_CHART.OVERVIEW' | translate }}</label>
|
||||
@ -55,7 +55,7 @@
|
||||
<tr>
|
||||
<td class="left cmd-title">{{'HELM_CHART.ADD_REPO' | translate }}</td>
|
||||
<td class="left cmd-content">
|
||||
<input class="cmd-content" type="text" [(ngModel)]="addCMD" #addCMDInput readonly />
|
||||
<input class="cmd-content clr-input" type="text" [(ngModel)]="addCMD" #addCMDInput readonly />
|
||||
</td>
|
||||
<td class="left">
|
||||
<span>
|
||||
@ -67,7 +67,7 @@
|
||||
<tr>
|
||||
<td class="left cmd-title">{{'HELM_CHART.INSTALL_CHART' | translate }}</td>
|
||||
<td class="left">
|
||||
<input class="cmd-content" type="text" [(ngModel)]="installCMD" #installCMDInput readonly />
|
||||
<input class="cmd-content clr-input" type="text" [(ngModel)]="installCMD" #installCMDInput readonly />
|
||||
</td>
|
||||
<td class="left">
|
||||
<span>
|
||||
@ -79,7 +79,7 @@
|
||||
<tr *ngIf="prov_ready">
|
||||
<td class="left cmd-title">{{'HELM_CHART.VERIFY_CHART' | translate }}</td>
|
||||
<td class="left">
|
||||
<input class="cmd-content" type="text" [(ngModel)]="verifyCMD" #verifyCMDInput readonly />
|
||||
<input class="cmd-content clr-input" type="text" [(ngModel)]="verifyCMD" #verifyCMDInput readonly />
|
||||
</td>
|
||||
<td class="left">
|
||||
<span>
|
||||
|
@ -2,12 +2,11 @@
|
||||
margin-top: 20px;
|
||||
padding: 0 0 0 15px;
|
||||
.md-container {
|
||||
border: solid 1px #ddd;
|
||||
border: solid 1px;
|
||||
}
|
||||
.summary-container {
|
||||
padding: 0;
|
||||
table {
|
||||
background-color: #f2f2f2;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
.content-group {
|
||||
@ -36,45 +35,3 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
%code-block {
|
||||
background: #ddd;
|
||||
border-radius: 2px;
|
||||
padding: 2px 4px;
|
||||
}
|
||||
|
||||
.md-div {
|
||||
::ng-deep {
|
||||
code:not([class*="language-"]) {
|
||||
@extend %code-block;
|
||||
color: #657b83;
|
||||
}
|
||||
pre:not([class*="language-"]) {
|
||||
background: #fdf6e3;
|
||||
code:not([class*="language-"]) {
|
||||
@extend %code-block;
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
table {
|
||||
display: block;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
padding: 0;
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 16px;
|
||||
td,
|
||||
th {
|
||||
padding: 6px 13px;
|
||||
border: 1px solid #ddd;
|
||||
@include align-text-mixin(left, right, center);
|
||||
}
|
||||
tr {
|
||||
&:nth-child(2n) {
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div class="breadcrumb">
|
||||
<a href="javascript:void(0)" (click)="gotoProjectList()"> {{ 'SIDE_NAV.PROJECTS'| translate}} </a>
|
||||
<
|
||||
<a href="javascript:void(0)" (click)="gotoChartList()">{{ 'HELM_CHART.HELMCHARTS'| translate}}</a>
|
||||
<a href="javascript:void(0)" (click)="gotoChartList()">{{ projectName }}</a>
|
||||
</div>
|
||||
<hbr-helm-chart-version
|
||||
[projectId]='projectId'
|
||||
|
@ -96,11 +96,7 @@ export class ListProjectComponent implements OnDestroy {
|
||||
}
|
||||
|
||||
get withChartMuseum(): boolean {
|
||||
if (this.appConfigService.getConfig().with_chartmuseum) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return this.appConfigService.getConfig().with_chartmuseum;
|
||||
}
|
||||
|
||||
public get isSystemAdmin(): boolean {
|
||||
@ -129,7 +125,7 @@ export class ListProjectComponent implements OnDestroy {
|
||||
goToLink(proId: number): void {
|
||||
this.searchTrigger.closeSearch(true);
|
||||
|
||||
let linkUrl = ["harbor", "projects", proId, "summary"];
|
||||
let linkUrl = ["harbor", "projects", proId];
|
||||
this.router.navigate(linkUrl);
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div class="breadcrumb" *ngIf="!withAdmiral">
|
||||
<a (click)="goProBack()">{{'SIDE_NAV.PROJECTS'| translate}}</a>
|
||||
<span class="back-icon"><</span>
|
||||
<a (click)="watchGoBackEvt(projectId)">{{'REPOSITORY.REPOSITORIES'| translate}}</a>
|
||||
<a (click)="watchGoBackEvt(projectId)">{{projectName}}</a>
|
||||
<span *ngIf="depth"><<a (click)="backInitRepo()">{{repoName}}</a></span>
|
||||
<span *ngIf="referArtifactNameArray?.length>=1" >
|
||||
<span *ngFor="let digest of referArtifactNameArray;let i = index">
|
||||
|
@ -28,6 +28,7 @@ import { Project } from "../../project";
|
||||
export class ArtifactListPageComponent implements OnInit {
|
||||
|
||||
projectId: number;
|
||||
projectName: string;
|
||||
projectMemberRoleId: number;
|
||||
repoName: string;
|
||||
referArtifactNameArray: string[] = [];
|
||||
@ -60,6 +61,7 @@ export class ArtifactListPageComponent implements OnInit {
|
||||
}
|
||||
let resolverData = this.route.snapshot.data;
|
||||
if (resolverData) {
|
||||
this.projectName = (<Project>resolverData['projectResolver']).name;
|
||||
this.hasProjectAdminRole = (<Project>resolverData['projectResolver']).has_project_admin_role;
|
||||
this.isGuest = (<Project>resolverData['projectResolver']).current_user_role_id === 3;
|
||||
this.projectMemberRoleId = (<Project>resolverData['projectResolver']).current_user_role_id;
|
||||
|
@ -264,7 +264,7 @@
|
||||
<span *ngIf="!hasVul(artifact)">
|
||||
{{'ARTIFACT.SCAN_UNSUPPORTED' | translate}}
|
||||
</span>
|
||||
<hbr-vulnerability-bar *ngIf="hasVul(artifact)" [scanner]="handleScanOverview(artifact.scan_overview)?.scanner"
|
||||
<hbr-vulnerability-bar (scanFinished)="scanFinished($event)" *ngIf="hasVul(artifact)" [scanner]="handleScanOverview(artifact.scan_overview)?.scanner"
|
||||
(submitFinish)="submitFinish($event)" [projectName]="projectName" [repoName]="repoName"
|
||||
[artifactDigest]="artifact.digest" [summary]="handleScanOverview(artifact.scan_overview)">
|
||||
</hbr-vulnerability-bar>
|
||||
|
@ -981,4 +981,15 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
||||
get isFilterReadonly() {
|
||||
return this.filterByType === 'labels' ? 'readonly' : null;
|
||||
}
|
||||
// when finished, remove it from selectedRow
|
||||
scanFinished(artifact: Artifact) {
|
||||
if (this.selectedRow && this.selectedRow.length) {
|
||||
for ( let i = 0; i < this.selectedRow.length; i++) {
|
||||
if (artifact.digest === this.selectedRow[i].digest) {
|
||||
this.selectedRow.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,10 +10,10 @@
|
||||
<clr-datagrid [clrDgLoading]="loading">
|
||||
<clr-dg-action-bar>
|
||||
<div class="clr-row center">
|
||||
<div class="clr-col-1">
|
||||
<div class="ml-05">
|
||||
<button (click)="scanNow()" type="button" class="btn btn-secondary" [clrLoading]="scanBtnState" [disabled]="!(hasEnabledScanner && hasScanningPermission && !onSendingScanCommand)"><clr-icon shape="shield-check" size="16"></clr-icon> {{'VULNERABILITY.SCAN_NOW' | translate}}</button>
|
||||
</div>
|
||||
<div class="clr-col">
|
||||
<div class="ml-1">
|
||||
<div [hidden]="!shouldShowBar()">
|
||||
<hbr-vulnerability-bar [summary]="handleScanOverview(artifact?.scan_overview)" [scanner]="scanner"
|
||||
(submitFinish)="submitFinish($event)" [projectName]="projectName" [repoName]="repoName"
|
||||
|
@ -46,3 +46,6 @@
|
||||
.no-border {
|
||||
border: none;
|
||||
}
|
||||
.ml-05 {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ export class ArtifactCommonPropertiesComponent implements OnInit, OnChanges {
|
||||
@Input() artifactDetails: Artifact;
|
||||
commonProperties: { [key: string]: any } = {};
|
||||
|
||||
constructor(private translate: TranslateService) {
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
@ -44,7 +44,7 @@ export class ArtifactCommonPropertiesComponent implements OnInit, OnChanges {
|
||||
}
|
||||
}
|
||||
if (name === Types.CREATED) {
|
||||
this.commonProperties[name] = new DatePipe(this.translate.currentLang)
|
||||
this.commonProperties[name] = new DatePipe('en-us')
|
||||
.transform(this.commonProperties[name], 'short');
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<div class="arrow-block" *ngIf="!withAdmiral">
|
||||
<a class="pl-0" (click)="goBackPro()">{{'SIDE_NAV.PROJECTS'| translate}}</a>
|
||||
<span class="back-icon"><</span>
|
||||
<a (click)="goBackRep()">{{'REPOSITORY.REPOSITORIES'| translate}}</a>
|
||||
<a (click)="goBackRep()">{{projectName}}</a>
|
||||
<span class="back-icon"><</span>
|
||||
<a (click)="goBack()">{{repositoryName}}</a>
|
||||
|
||||
|
@ -30,12 +30,14 @@
|
||||
<clr-dg-column [clrDgField]="'name'">{{'REPOSITORY.NAME' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'REPOSITORY.ARTIFACTS_COUNT' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgSortBy]="'pull_count'">{{'REPOSITORY.PULL_COUNT' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgSortBy]="'update_time'">{{'REPOSITORY.LAST_MODIFIED' | translate}}</clr-dg-column>
|
||||
<clr-dg-placeholder>{{'REPOSITORY.PLACEHOLDER' | translate }}</clr-dg-placeholder>
|
||||
<clr-dg-row *ngFor="let r of repositories" [clrDgItem]="r">
|
||||
<clr-dg-cell><a href="javascript:void(0)" (click)="goIntoRepo(r)"><span *ngIf="withAdmiral" class="list-img"><img [src]="getImgLink(r)"/></span>{{r.name}}</a></clr-dg-cell>
|
||||
<!-- to do -->
|
||||
<clr-dg-cell>{{r.artifact_count}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{r.pull_count}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{r.update_time | date:'short'}}</clr-dg-cell>
|
||||
</clr-dg-row>
|
||||
<clr-dg-footer>
|
||||
<span *ngIf="totalCount">{{pagination.firstItem + 1}} - {{pagination.lastItem + 1}} {{'REPOSITORY.OF' | translate}}</span>
|
||||
@ -72,12 +74,16 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{{'REPOSITORY.ARTIFACTS_COUNT' | translate}}</label>
|
||||
<div>{{item.tags_count}}</div>
|
||||
<div>{{item.artifact_count}}</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{{'REPOSITORY.PULL_COUNT' | translate}}</label>
|
||||
<div>{{item.pull_count}}</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{{'REPOSITORY.LAST_MODIFIED' | translate}}</label>
|
||||
<div>{{item.update_time | date: 'short'}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<clr-dropdown [clrCloseMenuOnItemClick]="false">
|
||||
|
@ -76,7 +76,7 @@
|
||||
}
|
||||
|
||||
.form-group > label {
|
||||
width: 100px;
|
||||
width: 142px;
|
||||
}
|
||||
|
||||
.card-media-block > img {
|
||||
|
@ -43,6 +43,8 @@ export class ResultBarChartComponent implements OnInit, OnDestroy {
|
||||
timerHandler: any;
|
||||
@Output()
|
||||
submitFinish: EventEmitter<boolean> = new EventEmitter<boolean>();
|
||||
@Output()
|
||||
scanFinished: EventEmitter<Artifact> = new EventEmitter<Artifact>();
|
||||
|
||||
constructor(
|
||||
private artifactService: ArtifactService,
|
||||
@ -165,6 +167,7 @@ export class ResultBarChartComponent implements OnInit, OnDestroy {
|
||||
this.stateCheckTimer.unsubscribe();
|
||||
this.stateCheckTimer = null;
|
||||
}
|
||||
this.scanFinished.emit(artifact);
|
||||
}
|
||||
this.channel.ArtifactDetail$.next(artifact);
|
||||
}, error => {
|
||||
|
@ -26,8 +26,8 @@
|
||||
</div>
|
||||
<div class="clr-row">
|
||||
<div class="clr-col-4"></div>
|
||||
<div class="clr-col-8">
|
||||
<span>{{'TAG_RETENTION.REP_SEPARATOR' | translate}}</span>
|
||||
<div class="clr-col-8 margin-top-5px">
|
||||
<span class="tootip">{{'TAG_RETENTION.REP_SEPARATOR' | translate}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -57,7 +57,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="height-85">
|
||||
<div class="height-95">
|
||||
<div class="clr-row">
|
||||
<div class="clr-col-4">
|
||||
<label>{{'TAG_RETENTION.TAGS' | translate}}</label>
|
||||
@ -84,7 +84,7 @@
|
||||
</div>
|
||||
<div class="clr-row">
|
||||
<div class="clr-col-4"></div>
|
||||
<div class="clr-col-8">
|
||||
<div class="clr-col-8 margin-top-5px">
|
||||
<span class="tootip">{{'TAG_RETENTION.TAG_SEPARATOR' | translate}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -11,8 +11,8 @@
|
||||
.height-72 {
|
||||
height: 72px;
|
||||
}
|
||||
.height-85 {
|
||||
height: 85px;
|
||||
.height-95 {
|
||||
height: 95px;
|
||||
}
|
||||
|
||||
.display-none {
|
||||
@ -33,3 +33,6 @@
|
||||
.font-size-13 {
|
||||
font-size: 13px;
|
||||
}
|
||||
.margin-top-5px {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
@ -703,7 +703,8 @@
|
||||
"DEPLOY": "DEPLOY",
|
||||
"ADDITIONAL_INFO": "Add Additional Info",
|
||||
"REPO_NAME": "Repository",
|
||||
"MARKDOWN": "Styling with Markdown is supported"
|
||||
"MARKDOWN": "Styling with Markdown is supported",
|
||||
"LAST_MODIFIED": "Last Modified Time"
|
||||
},
|
||||
"HELM_CHART": {
|
||||
"HELMCHARTS": "Charts",
|
||||
|
@ -704,7 +704,8 @@
|
||||
"DEPLOY": "DEPLOY",
|
||||
"ADDITIONAL_INFO": "Add Additional Info",
|
||||
"REPO_NAME": "Repository",
|
||||
"MARKDOWN": "Styling with Markdown is supported"
|
||||
"MARKDOWN": "Styling with Markdown is supported",
|
||||
"LAST_MODIFIED": "Last Modified Time"
|
||||
},
|
||||
"HELM_CHART": {
|
||||
"HELMCHARTS": "Charts",
|
||||
|
@ -690,7 +690,8 @@
|
||||
"DEPLOY": "DEPLOY",
|
||||
"ADDITIONAL_INFO": "Add Additional Info",
|
||||
"REPO_NAME": "Repository",
|
||||
"MARKDOWN": "Styling with Markdown is supported"
|
||||
"MARKDOWN": "Styling with Markdown is supported",
|
||||
"LAST_MODIFIED": "Last Modified Time"
|
||||
},
|
||||
"HELM_CHART": {
|
||||
"HELMCHARTS": "Charts",
|
||||
|
@ -702,7 +702,8 @@
|
||||
"ACTION": "AÇÃO",
|
||||
"DEPLOY": "DEPLOY",
|
||||
"ADDITIONAL_INFO": "Adicionar informação adicional",
|
||||
"MARKDOWN": "Styling with Markdown is supported"
|
||||
"MARKDOWN": "Styling with Markdown is supported",
|
||||
"LAST_MODIFIED": "Last Modified Time"
|
||||
},
|
||||
"HELM_CHART": {
|
||||
"HELMCHARTS": "Charts",
|
||||
|
@ -703,7 +703,8 @@
|
||||
"DEPLOY": "YÜKLE",
|
||||
"ADDITIONAL_INFO": "Ek Bilgi Ekle",
|
||||
"REPO_NAME": "Depo",
|
||||
"MARKDOWN": "Markdown ile stil desteklenir"
|
||||
"MARKDOWN": "Markdown ile stil desteklenir",
|
||||
"LAST_MODIFIED": "Last Modified Time"
|
||||
},
|
||||
"HELM_CHART": {
|
||||
"HELMCHARTS": "Tablolar",
|
||||
|
@ -704,7 +704,8 @@
|
||||
"DEPLOY": "部署",
|
||||
"ADDITIONAL_INFO": "添加信息",
|
||||
"REPO_NAME": "镜像仓库",
|
||||
"MARKDOWN": "支持使用Markdown进行样式设置"
|
||||
"MARKDOWN": "支持使用Markdown进行样式设置",
|
||||
"LAST_MODIFIED": "最新变更时间"
|
||||
},
|
||||
"HELM_CHART": {
|
||||
"HELMCHARTS": "Charts",
|
||||
|
@ -1,11 +1,11 @@
|
||||
{
|
||||
"APP_TITLE":{
|
||||
"VMW_HARBOR":"VMW_HARBOR",
|
||||
"HARBOR":"HARBOR",
|
||||
"VMW_HARBOR":"Harbor",
|
||||
"HARBOR":"Harbor",
|
||||
"VIC":"vSphere Integrated Containers",
|
||||
"MGMT":"管理",
|
||||
"REG":"註冊表",
|
||||
"HARBOR_SWAGGER":"HARBOR_SWAGGER",
|
||||
"HARBOR_SWAGGER":"Harbor Swagger",
|
||||
"THEME_DARK_TEXT": "深色主題",
|
||||
"THEME_LIGHT_TEXT": "淺色主題"
|
||||
},
|
||||
@ -270,7 +270,7 @@
|
||||
"NEW_USER": "添加用戶成員",
|
||||
"NEW_MEMBER": "新建成員",
|
||||
"MEMBER": "成員",
|
||||
"NAME": "姓名",
|
||||
"NAME": "名稱",
|
||||
"EMAIL": "郵箱",
|
||||
"ROLE": "角色",
|
||||
"SYS_ADMIN": "系統管理員",
|
||||
@ -317,7 +317,7 @@
|
||||
"REMOVE": "移除成員"
|
||||
},
|
||||
"ROBOT_ACCOUNT":{
|
||||
"NAME": "姓名",
|
||||
"NAME": "名稱",
|
||||
"PERMISSIONS": "權限",
|
||||
"TOKEN": "令牌",
|
||||
"NEW_ROBOT_ACCOUNT": "添加機器人帳戶",
|
||||
@ -700,7 +700,8 @@
|
||||
"DEPLOY": "部署",
|
||||
"ADDITIONAL_INFO": "添加信息",
|
||||
"REPO_NAME": "鏡像倉庫",
|
||||
"MARKDOWN": "支持使用Markdown進行樣式設置"
|
||||
"MARKDOWN": "支持使用Markdown進行樣式設置",
|
||||
"LAST_MODIFIED": "Last Modified Time"
|
||||
},
|
||||
"HELM_CHART":{
|
||||
"HELMCHARTS":"圖表",
|
||||
|
@ -145,7 +145,7 @@ export class VulnerabilityConfigComponent implements OnInit, OnDestroy {
|
||||
if (metadata && metadata.properties) {
|
||||
for (let key in metadata.properties) {
|
||||
if (key === DATABASE_UPDATED_PROPERTY && metadata.properties[key]) {
|
||||
this.updatedTimeStr = new DatePipe(this.translate.currentLang).transform(metadata.properties[key], 'short');
|
||||
this.updatedTimeStr = new DatePipe('en-us').transform(metadata.properties[key], 'short');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import { of } from "rxjs";
|
||||
import { HttpClient } from "@angular/common/http";
|
||||
import { HttpClientTestingModule } from "@angular/common/http/testing";
|
||||
import { CURRENT_BASE_HREF } from "../../utils/utils";
|
||||
import { AppConfigService } from '../../../app/services/app-config.service';
|
||||
|
||||
describe("CreateEditEndpointComponent (inline template)", () => {
|
||||
let mockData: Endpoint = {
|
||||
@ -263,6 +264,14 @@ describe("CreateEditEndpointComponent (inline template)", () => {
|
||||
|
||||
let spy: jasmine.Spy;
|
||||
let spyAdapter: jasmine.Spy;
|
||||
const mockAppConfigService = {
|
||||
getConfig: () => {
|
||||
return {
|
||||
project_creation_restriction: "",
|
||||
with_chartmuseum: ""
|
||||
};
|
||||
}
|
||||
};
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [SharedModule, NoopAnimationsModule],
|
||||
@ -276,6 +285,7 @@ describe("CreateEditEndpointComponent (inline template)", () => {
|
||||
{ provide: SERVICE_CONFIG, useValue: config },
|
||||
{ provide: EndpointService, useClass: EndpointDefaultService },
|
||||
{ provide: HttpClient, useValue: fakedHttp },
|
||||
{ provide: AppConfigService, useValue: mockAppConfigService }
|
||||
]
|
||||
});
|
||||
}));
|
||||
|
@ -32,10 +32,12 @@ import { Endpoint, PingEndpoint } from "../../services/interface";
|
||||
import { clone, compareValue, CURRENT_BASE_HREF, isEmptyObject } from "../../utils/utils";
|
||||
import { HttpClient } from "@angular/common/http";
|
||||
import { catchError } from "rxjs/operators";
|
||||
import { AppConfigService } from '../../../app/services/app-config.service';
|
||||
|
||||
const FAKE_PASSWORD = "rjGcfuRu";
|
||||
const FAKE_JSON_KEY = "No Change";
|
||||
const METADATA_URL = CURRENT_BASE_HREF + "/replication/adapterinfos";
|
||||
const HELM_HUB = "helm-hub";
|
||||
@Component({
|
||||
selector: "hbr-create-edit-endpoint",
|
||||
templateUrl: "./create-edit-endpoint.component.html",
|
||||
@ -78,21 +80,31 @@ export class CreateEditEndpointComponent
|
||||
private errorHandler: ErrorHandler,
|
||||
private translateService: TranslateService,
|
||||
private ref: ChangeDetectorRef,
|
||||
private http: HttpClient
|
||||
private http: HttpClient,
|
||||
private appConfigService: AppConfigService,
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.getAdapters();
|
||||
this.getAdapterInfo();
|
||||
}
|
||||
getAdapters() {
|
||||
this.endpointService.getAdapters().subscribe(
|
||||
adapters => {
|
||||
this.adapterList = adapters || [];
|
||||
if (!this.appConfigService.getConfig().with_chartmuseum) { // disable helm-hub
|
||||
for (let i = 0; i < this.adapterList.length; i++) {
|
||||
if (this.adapterList[i] === HELM_HUB) {
|
||||
this.adapterList.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
error => {
|
||||
this.errorHandler.error(error);
|
||||
}
|
||||
);
|
||||
this.getAdapterInfo();
|
||||
}
|
||||
|
||||
getAdapterInfo() {
|
||||
this.http.get(METADATA_URL)
|
||||
.pipe(catchError(error => observableThrowError(error)))
|
||||
|
@ -22,6 +22,7 @@ import { click, CURRENT_BASE_HREF } from "../../utils/utils";
|
||||
import { of } from "rxjs";
|
||||
import { HttpClientTestingModule } from "@angular/common/http/testing";
|
||||
import { HttpClient } from "@angular/common/http";
|
||||
import { AppConfigService } from '../../../app/services/app-config.service';
|
||||
|
||||
describe("EndpointComponent (inline template)", () => {
|
||||
let adapterInfoMockData = {
|
||||
@ -313,6 +314,14 @@ describe("EndpointComponent (inline template)", () => {
|
||||
let config: IServiceConfig = {
|
||||
systemInfoEndpoint: CURRENT_BASE_HREF + "/endpoints/testing"
|
||||
};
|
||||
const mockAppConfigService = {
|
||||
getConfig: () => {
|
||||
return {
|
||||
project_creation_restriction: "",
|
||||
with_chartmuseum: ""
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
let endpointService: EndpointService;
|
||||
let spy: jasmine.Spy;
|
||||
@ -335,6 +344,7 @@ describe("EndpointComponent (inline template)", () => {
|
||||
{ provide: EndpointService, useClass: EndpointDefaultService },
|
||||
{ provide: OperationService },
|
||||
{ provide: HttpClient, useValue: fakedHttp },
|
||||
{ provide: AppConfigService, useValue: mockAppConfigService }
|
||||
]
|
||||
});
|
||||
}));
|
||||
|
@ -108,7 +108,7 @@
|
||||
<clr-dg-cell>{{t.src_resource}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{t.dst_resource}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{t.operation}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{t.status}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{getStatusStr(t.status)}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{t.start_time | date: 'short'}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{t.end_time && t.end_time != '0001-01-01T00:00:00Z' ? (t.end_time | date: 'short') : "-"}}</clr-dg-cell>
|
||||
<clr-dg-cell>
|
||||
|
@ -11,6 +11,9 @@ import { RequestQueryParams } from "../../../services/RequestQueryParams";
|
||||
import { REFRESH_TIME_DIFFERENCE } from '../../../entities/shared.const';
|
||||
|
||||
const executionStatus = 'InProgress';
|
||||
const STATUS_MAP = {
|
||||
"Succeed": "Succeeded"
|
||||
};
|
||||
@Component({
|
||||
selector: 'replication-tasks',
|
||||
templateUrl: './replication-tasks.component.html',
|
||||
@ -203,11 +206,14 @@ export class ReplicationTasksComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
openFilter(isOpen: boolean): void {
|
||||
if (isOpen) {
|
||||
this.isOpenFilterTag = true;
|
||||
} else {
|
||||
this.isOpenFilterTag = false;
|
||||
this.isOpenFilterTag = isOpen;
|
||||
}
|
||||
|
||||
getStatusStr(status: string): string {
|
||||
if (STATUS_MAP && STATUS_MAP[status]) {
|
||||
return STATUS_MAP[status];
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -65,7 +65,7 @@
|
||||
<a href="javascript:void(0)" (click)="goToLink(j.id)">{{j.id}}</a>
|
||||
</clr-dg-cell>
|
||||
<clr-dg-cell>
|
||||
{{j.status}}
|
||||
{{getStatusStr(j.status)}}
|
||||
<clr-tooltip>
|
||||
<clr-icon *ngIf="j.status_text" clrTooltipTrigger shape="info-circle" size="20"></clr-icon>
|
||||
<clr-tooltip-content [clrPosition]="'left'" clrSize="md" *clrIfOpen>
|
||||
|
@ -82,6 +82,10 @@ export class SearchOption {
|
||||
pageSize: number = DEFAULT_PAGE_SIZE;
|
||||
}
|
||||
|
||||
const STATUS_MAP = {
|
||||
"Succeed": "Succeeded"
|
||||
};
|
||||
|
||||
@Component({
|
||||
selector: "hbr-replication",
|
||||
templateUrl: "./replication.component.html",
|
||||
@ -518,4 +522,10 @@ export class ReplicationComponent implements OnInit, OnDestroy {
|
||||
return '-';
|
||||
}
|
||||
}
|
||||
getStatusStr(status: string): string {
|
||||
if (STATUS_MAP && STATUS_MAP[status]) {
|
||||
return STATUS_MAP[status];
|
||||
}
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user