mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-23 09:08:26 +01:00
Modify harbor-shell UI
Signed-off-by: sshijun <sshijun@vmware.com>
This commit is contained in:
parent
5f62b5778b
commit
b4fa143aa4
@ -20,8 +20,8 @@
|
||||
<clr-control-helper class="config-subtext"> {{ 'PROJECT_CONFIG.CONTENT_TRUST_POLCIY' | translate }}
|
||||
</clr-control-helper>
|
||||
</clr-checkbox-container>
|
||||
<clr-checkbox-container id="prevent-vulenrability-image" *ngIf="withNotary">
|
||||
<label><span *ngIf="!withNotary">{{ 'PROJECT_CONFIG.SECURITY' | translate }}</span></label>
|
||||
<clr-checkbox-container id="prevent-vulenrability-image">
|
||||
<label><span>{{ 'PROJECT_CONFIG.SECURITY' | translate }}</span></label>
|
||||
<clr-checkbox-wrapper>
|
||||
<input type="checkbox" clrCheckbox [(ngModel)]="projectPolicy.PreventVulImg"
|
||||
name="prevent-vulenrability-image-input" [disabled]="!hasChangeConfigRole" />
|
||||
|
@ -70,6 +70,7 @@ export class ProjectPolicyConfigComponent implements OnInit {
|
||||
projectPolicy = new ProjectPolicy();
|
||||
hasChangeConfigRole: boolean;
|
||||
severityOptions = [
|
||||
{severity: 'critical', severityLevel: 'VULNERABILITY.SEVERITY.CRITICAL'},
|
||||
{severity: 'high', severityLevel: 'VULNERABILITY.SEVERITY.HIGH'},
|
||||
{severity: 'medium', severityLevel: 'VULNERABILITY.SEVERITY.MEDIUM'},
|
||||
{severity: 'low', severityLevel: 'VULNERABILITY.SEVERITY.LOW'},
|
||||
|
@ -35,12 +35,12 @@
|
||||
</span>
|
||||
</clr-dg-cell>
|
||||
<clr-dg-cell [ngSwitch]="res.severity">
|
||||
<span *ngSwitchCase="'Critical'" class="label label-critical">{{severityText(res.severity) | translate}}</span>
|
||||
<span *ngSwitchCase="'High'" class="label label-danger">{{severityText(res.severity) | translate}}</span>
|
||||
<span *ngSwitchCase="'Medium'" class="label label-medium">{{severityText(res.severity) | translate}}</span>
|
||||
<span *ngSwitchCase="'Low'" class="label label-low">{{severityText(res.severity) | translate}}</span>
|
||||
<span *ngSwitchCase="'Negligible'" class="label label-negligible">{{severityText(res.severity) | translate}}</span>
|
||||
<span *ngSwitchCase="'Unknown'" class="label label-unknown">{{severityText(res.severity) | translate}}</span>
|
||||
<span *ngSwitchCase="'Critical'" class="label label-critical no-border">{{severityText(res.severity) | translate}}</span>
|
||||
<span *ngSwitchCase="'High'" class="label label-danger no-border">{{severityText(res.severity) | translate}}</span>
|
||||
<span *ngSwitchCase="'Medium'" class="label label-medium no-border">{{severityText(res.severity) | translate}}</span>
|
||||
<span *ngSwitchCase="'Low'" class="label label-low no-border">{{severityText(res.severity) | translate}}</span>
|
||||
<span *ngSwitchCase="'Negligible'" class="label label-negligible no-border">{{severityText(res.severity) | translate}}</span>
|
||||
<span *ngSwitchCase="'Unknown'" class="label label-unknown no-border">{{severityText(res.severity) | translate}}</span>
|
||||
<span *ngSwitchDefault>{{severityText(res.severity) | translate}}</span>
|
||||
</clr-dg-cell>
|
||||
<clr-dg-cell>{{res.package}}</clr-dg-cell>
|
||||
|
@ -164,3 +164,6 @@ hr{
|
||||
.margin-top-m15{
|
||||
margin-top: -15px;
|
||||
}
|
||||
.no-border {
|
||||
border: none;
|
||||
}
|
||||
|
@ -39,6 +39,10 @@ import { VulnerabilityPageComponent } from './vulnerability-page/vulnerability-p
|
||||
import { GcPageComponent } from './gc-page/gc-page.component';
|
||||
import { OidcOnboardModule } from './oidc-onboard/oidc-onboard.module';
|
||||
import { LicenseModule } from './license/license.module';
|
||||
import { InterrogationServicesComponent } from "./interrogation-services/interrogation-services.component";
|
||||
import { LabelsComponent } from './labels/labels.component';
|
||||
import { ProjectQuotasComponent } from './project-quotas/project-quotas.component';
|
||||
|
||||
registerLocaleData(zh, 'zh-cn');
|
||||
registerLocaleData(es, 'es-es');
|
||||
registerLocaleData(localeFr, 'fr-fr');
|
||||
@ -61,7 +65,10 @@ export function getCurrentLanguage(translateService: TranslateService) {
|
||||
AppComponent,
|
||||
ProjectConfigComponent,
|
||||
VulnerabilityPageComponent,
|
||||
GcPageComponent
|
||||
GcPageComponent,
|
||||
InterrogationServicesComponent,
|
||||
LabelsComponent,
|
||||
ProjectQuotasComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
@ -41,26 +41,28 @@
|
||||
<clr-icon shape="cloud-traffic" clrVerticalNavIcon></clr-icon>
|
||||
{{'SIDE_NAV.SYSTEM_MGMT.REPLICATION' | translate}}
|
||||
</a>
|
||||
</clr-vertical-nav-group-children>
|
||||
</clr-vertical-nav-group>
|
||||
<clr-vertical-nav-group *ngIf="isSystemAdmin && hasAdminRole" routerLinkActive="active">
|
||||
<clr-icon shape="event" clrVerticalNavIcon></clr-icon>
|
||||
{{'SIDE_NAV.TASKS' | translate}}
|
||||
<a routerLink="#" hidden aria-hidden="true"></a>
|
||||
<clr-vertical-nav-group-children *clrIfExpanded="true">
|
||||
<a clrVerticalNavLink routerLink="/harbor/vulnerability"
|
||||
routerLinkActive="active">
|
||||
{{'SIDE_NAV.SYSTEM_MGMT.VULNERABILITY' | translate}}
|
||||
<a *ngIf="!withAdmiral" clrVerticalNavLink routerLink="/harbor/labels" routerLinkActive="active">
|
||||
<clr-icon shape="tag" clrVerticalNavIcon></clr-icon>
|
||||
{{'CONFIG.LABEL' | translate }}
|
||||
</a>
|
||||
<a clrVerticalNavLink routerLink="/harbor/project-quotas" routerLinkActive="active">
|
||||
<clr-icon shape="volume" clrVerticalNavIcon></clr-icon>
|
||||
{{'CONFIG.PROJECT_QUOTAS' | translate }}
|
||||
</a>
|
||||
<a clrVerticalNavLink routerLink="/harbor/interrogation-services" routerLinkActive="active">
|
||||
<clr-icon shape="shield" clrVerticalNavIcon></clr-icon>
|
||||
{{'SIDE_NAV.SYSTEM_MGMT.INTERROGATION_SERVICES' | translate}}
|
||||
</a>
|
||||
<a clrVerticalNavLink *ngIf="hasAdminRole" routerLink="/harbor/gc" routerLinkActive="active">
|
||||
<clr-icon shape="trash" clrVerticalNavIcon></clr-icon>
|
||||
{{'SIDE_NAV.SYSTEM_MGMT.GARBAGE_COLLECTION' | translate}}
|
||||
</a>
|
||||
<a clrVerticalNavLink routerLinkActive="active" routerLink="/harbor/configs">
|
||||
<clr-icon shape="cog" clrVerticalNavIcon></clr-icon>
|
||||
{{'SIDE_NAV.SYSTEM_MGMT.CONFIG' | translate}}
|
||||
</a>
|
||||
</clr-vertical-nav-group-children>
|
||||
</clr-vertical-nav-group>
|
||||
<a *ngIf="isSystemAdmin" clrVerticalNavLink routerLinkActive="active" routerLink="/harbor/configs">
|
||||
<clr-icon shape="cog" clrVerticalNavIcon></clr-icon>
|
||||
{{'SIDE_NAV.SYSTEM_MGMT.CONFIG' | translate}}
|
||||
</a>
|
||||
</div>
|
||||
<div class="vertical-nav-footer">
|
||||
<a clrVerticalNavLink target="_blank" routerLink="/devcenter">
|
||||
|
@ -115,7 +115,9 @@ export class HarborShellComponent implements OnInit, OnDestroy {
|
||||
return this.session.getCurrentUser() &&
|
||||
this.session.getCurrentUser().has_admin_role;
|
||||
}
|
||||
|
||||
public get withAdmiral(): boolean {
|
||||
return this.appConfigService.getConfig().with_admiral;
|
||||
}
|
||||
// Open modal dialog
|
||||
openModal(event: ModalEvent): void {
|
||||
switch (event.modalName) {
|
||||
|
@ -1,7 +1,6 @@
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
||||
<h2 class="custom-h2 config-title">{{'CONFIG.TITLE' | translate }}</h2>
|
||||
<span class="spinner spinner-inline" [hidden]="inProgress === false"></span>
|
||||
<h2 class="custom-h2 config-title">{{'CONFIG.TITLE' | translate }}<span class="spinner spinner-inline ml-1 v-mid" [hidden]="inProgress === false"></span></h2>
|
||||
<clr-tabs>
|
||||
<clr-tab>
|
||||
<button id="config-auth" clrTabLink>{{'CONFIG.AUTH' | translate}}</button>
|
||||
@ -21,29 +20,6 @@
|
||||
<system-settings [(systemSettings)]="allConfig" [hasAdminRole]="hasAdminRole" (reloadSystemConfig)="handleAppConfig($event)" (readOnlyChange)="handleReadyOnlyChange($event)" [hasCAFile]="hasCAFile"></system-settings>
|
||||
</clr-tab-content>
|
||||
</clr-tab>
|
||||
<clr-tab *ngIf="!withAdmiral">
|
||||
<button id="config-label" clrTabLink>{{'CONFIG.LABEL' | translate }}</button>
|
||||
<ng-template [(clrIfActive)]="labelActive">
|
||||
<clr-tab-content id="system_label" *ngIf="!withAdmiral">
|
||||
<hbr-label [scope]="'g'"
|
||||
[hasCreateLabelPermission]="true"
|
||||
[hasUpdateLabelPermission]="true"
|
||||
[hasDeleteLabelPermission]="true"></hbr-label>
|
||||
</clr-tab-content>
|
||||
</ng-template>
|
||||
</clr-tab>
|
||||
<clr-tab>
|
||||
<button id="config-quotas" clrTabLink>{{'CONFIG.PROJECT_QUOTAS' | translate }}</button>
|
||||
<clr-tab-content id="project_quotas" *clrIfActive>
|
||||
<project-quotas [(allConfig)]="allConfig" (refreshAllconfig)="refreshAllconfig()"></project-quotas>
|
||||
</clr-tab-content>
|
||||
</clr-tab>
|
||||
<clr-tab>
|
||||
<button id="config-scanners" clrTabLink>{{'SCANNER.SCANNERS' | translate}}</button>
|
||||
<clr-tab-content id="scanners" *clrIfActive>
|
||||
<config-scanner></config-scanner>
|
||||
</clr-tab-content>
|
||||
</clr-tab>
|
||||
</clr-tabs>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -30,3 +30,6 @@ clr-icon:hover {
|
||||
.clr-form-control-disabled {
|
||||
opacity: 1;
|
||||
}
|
||||
.v-mid {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
@ -59,12 +59,12 @@
|
||||
{{'SCANNER.NO_SCANNER' | translate}}
|
||||
</clr-dg-placeholder>
|
||||
<clr-dg-row *clrDgItems="let scanner of scanners" [clrDgItem]="scanner">
|
||||
<clr-dg-cell>
|
||||
<clr-dg-cell class="position-relative">
|
||||
<span>{{scanner.name}}</span>
|
||||
<span *ngIf="scanner.is_default" class="label label-info ml-1 label-in-cell">{{'SCANNER.DEFAULT' | translate}}</span>
|
||||
</clr-dg-cell>
|
||||
<clr-dg-cell>{{scanner.url}}</clr-dg-cell>
|
||||
<clr-dg-cell>
|
||||
<clr-dg-cell class="position-relative">
|
||||
<span *ngIf="scanner.loadingMetadata;else elseBlockLoading" class="spinner spinner-inline ml-2"></span>
|
||||
<ng-template #elseBlockLoading>
|
||||
<span *ngIf="scanner.metadata;else elseBlock" class="label label-success label-in-cell">{{'SCANNER.HEALTHY' | translate}}</span>
|
||||
|
@ -1,7 +1,6 @@
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
||||
<h2 class="custom-h2 gc-title">{{'CONFIG.GC' | translate }}</h2>
|
||||
<span class="spinner spinner-inline" [hidden]="!inProgress"></span>
|
||||
<h2 class="custom-h2 gc-title">{{'CONFIG.GC' | translate }}<span class="spinner spinner-inline ml-1 v-mid" [hidden]="!inProgress"></span></h2>
|
||||
<clr-tabs>
|
||||
<clr-tab *ngIf="hasAdminRole">
|
||||
<button id="config-gc" clrTabLink>{{'CONFIG.GC' | translate }}</button>
|
||||
|
@ -1,3 +1,6 @@
|
||||
.gc-title {
|
||||
display: inline-block;
|
||||
}
|
||||
.v-mid {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
@ -62,8 +62,13 @@ import { LicenseComponent } from './license/license.component';
|
||||
import { SummaryComponent } from './project/summary/summary.component';
|
||||
import { TagRetentionComponent } from './project/tag-retention/tag-retention.component';
|
||||
import { ImmutableTagComponent } from './project/immutable-tag/immutable-tag.component';
|
||||
import { USERSTATICPERMISSION } from '@harbor/ui';
|
||||
import { USERSTATICPERMISSION, VulnerabilityConfigComponent } from '@harbor/ui';
|
||||
import { ScannerComponent } from "./project/scanner/scanner.component";
|
||||
import { InterrogationServicesComponent } from "./interrogation-services/interrogation-services.component";
|
||||
import { ConfigurationScannerComponent } from "./config/scanner/config-scanner.component";
|
||||
import { LabelsComponent } from "./labels/labels.component";
|
||||
import { ProjectQuotasComponent } from "./project-quotas/project-quotas.component";
|
||||
|
||||
|
||||
const harborRoutes: Routes = [
|
||||
{ path: '', redirectTo: 'harbor', pathMatch: 'full' },
|
||||
@ -122,6 +127,37 @@ const harborRoutes: Routes = [
|
||||
canActivate: [SystemAdminGuard],
|
||||
canActivateChild: [SystemAdminGuard]
|
||||
},
|
||||
{
|
||||
path: 'interrogation-services',
|
||||
component: InterrogationServicesComponent,
|
||||
canActivate: [SystemAdminGuard],
|
||||
canActivateChild: [SystemAdminGuard],
|
||||
children: [
|
||||
{
|
||||
path: 'scanners',
|
||||
component: ConfigurationScannerComponent
|
||||
},
|
||||
{
|
||||
path: 'vulnerability',
|
||||
component: VulnerabilityConfigComponent
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
redirectTo: 'scanners',
|
||||
pathMatch: 'full'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'labels',
|
||||
component: LabelsComponent,
|
||||
canActivate: [SystemAdminGuard],
|
||||
},
|
||||
{
|
||||
path: 'project-quotas',
|
||||
component: ProjectQuotasComponent,
|
||||
canActivate: [SystemAdminGuard],
|
||||
},
|
||||
{
|
||||
path: 'replications/:id/:tasks',
|
||||
component: ReplicationTasksPageComponent,
|
||||
|
@ -0,0 +1,14 @@
|
||||
<h2 class="custom-h2" sub-header-title>{{'SIDE_NAV.SYSTEM_MGMT.INTERROGATION_SERVICES' | translate}}</h2>
|
||||
<nav class="subnav sub-nav-bg-color mt-1">
|
||||
<ul class="nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" routerLink="scanners" routerLinkActive="active">{{'SCANNER.SCANNERS' | translate }}</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" routerLink="vulnerability" routerLinkActive="active">{{'CONFIG.VULNERABILITY' | translate }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<router-outlet></router-outlet>
|
||||
|
||||
|
@ -0,0 +1,26 @@
|
||||
.sub-header-title {
|
||||
margin-top: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.sub-nav-bg-color {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.subnav {
|
||||
.nav {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.role-label {
|
||||
color: #CCCCCC;
|
||||
font-size: 14px;
|
||||
font-style: italic;
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
.backStyle{
|
||||
color: #007cbb;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { InterrogationServicesComponent } from './interrogation-services.component';
|
||||
import { SharedModule } from "../shared/shared.module";
|
||||
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
||||
import { ClarityModule } from "@clr/angular";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
|
||||
|
||||
describe('InterrogationServicesComponent', () => {
|
||||
let component: InterrogationServicesComponent;
|
||||
let fixture: ComponentFixture<InterrogationServicesComponent>;
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
SharedModule,
|
||||
BrowserAnimationsModule,
|
||||
ClarityModule,
|
||||
],
|
||||
declarations: [ InterrogationServicesComponent ],
|
||||
providers: [TranslateService],
|
||||
schemas: [
|
||||
CUSTOM_ELEMENTS_SCHEMA
|
||||
],
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(InterrogationServicesComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-interrogation-services',
|
||||
templateUrl: './interrogation-services.component.html',
|
||||
styleUrls: ['./interrogation-services.component.scss']
|
||||
})
|
||||
export class InterrogationServicesComponent implements OnInit {
|
||||
|
||||
constructor(
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
}
|
5
src/portal/src/app/labels/labels.component.html
Normal file
5
src/portal/src/app/labels/labels.component.html
Normal file
@ -0,0 +1,5 @@
|
||||
<h2 class="custom-h2" sub-header-title>{{'CONFIG.LABEL' | translate }}</h2>
|
||||
<hbr-label [scope]="'g'"
|
||||
[hasCreateLabelPermission]="true"
|
||||
[hasUpdateLabelPermission]="true"
|
||||
[hasDeleteLabelPermission]="true"></hbr-label>
|
39
src/portal/src/app/labels/labels.component.spec.ts
Normal file
39
src/portal/src/app/labels/labels.component.spec.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { LabelsComponent } from './labels.component';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
import { ClarityModule } from "@clr/angular";
|
||||
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
||||
import { SharedModule } from "../shared/shared.module";
|
||||
|
||||
describe('LabelsComponent', () => {
|
||||
let component: LabelsComponent;
|
||||
let fixture: ComponentFixture<LabelsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
SharedModule,
|
||||
BrowserAnimationsModule,
|
||||
ClarityModule,
|
||||
],
|
||||
declarations: [ LabelsComponent ],
|
||||
providers: [TranslateService],
|
||||
schemas: [
|
||||
CUSTOM_ELEMENTS_SCHEMA
|
||||
],
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(LabelsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
14
src/portal/src/app/labels/labels.component.ts
Normal file
14
src/portal/src/app/labels/labels.component.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-labels',
|
||||
templateUrl: './labels.component.html',
|
||||
})
|
||||
export class LabelsComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
<h2 class="custom-h2" sub-header-title>{{'CONFIG.PROJECT_QUOTAS' | translate }}<span class="spinner spinner-inline ml-1 v-mid" [hidden]="!loading"></span></h2>
|
||||
<project-quotas *ngIf="!loading" [allConfig]="allConfig" (refreshAllconfig)="refreshAllconfig()"></project-quotas>
|
@ -0,0 +1,3 @@
|
||||
.v-mid {
|
||||
vertical-align: middle;
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ProjectQuotasComponent } from './project-quotas.component';
|
||||
import { TranslateModule } from "@ngx-translate/core";
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
|
||||
import { MessageHandlerService } from "../shared/message-handler/message-handler.service";
|
||||
import { SessionService } from "../shared/session.service";
|
||||
import { SessionUser } from "../shared/session-user";
|
||||
import { ConfigurationService } from "../config/config.service";
|
||||
import { Configuration } from "@harbor/ui";
|
||||
import { of } from "rxjs";
|
||||
|
||||
describe('ProjectQuotasComponent', () => {
|
||||
let component: ProjectQuotasComponent;
|
||||
let fixture: ComponentFixture<ProjectQuotasComponent>;
|
||||
const mockedUser: SessionUser = {
|
||||
user_id: 1,
|
||||
username: 'admin',
|
||||
email: 'harbor@vmware.com',
|
||||
realname: 'admin',
|
||||
has_admin_role: true,
|
||||
comment: 'no comment'
|
||||
};
|
||||
let mockedConfig: Configuration = new Configuration();
|
||||
mockedConfig.count_per_project.value = 10;
|
||||
const fakedSessionService = {
|
||||
getCurrentUser() {
|
||||
return mockedUser;
|
||||
}
|
||||
};
|
||||
const fakedConfigurationService = {
|
||||
getConfiguration() {
|
||||
return of(mockedConfig);
|
||||
}
|
||||
};
|
||||
const fakedMessageHandlerService = {
|
||||
handleError() {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
TranslateModule.forRoot()
|
||||
],
|
||||
declarations: [ ProjectQuotasComponent ],
|
||||
providers: [
|
||||
MessageHandlerService,
|
||||
{provide: MessageHandlerService, useValue: fakedMessageHandlerService},
|
||||
{provide: SessionService, useValue: fakedSessionService},
|
||||
{provide: ConfigurationService, useValue: fakedConfigurationService}
|
||||
],
|
||||
schemas: [
|
||||
CUSTOM_ELEMENTS_SCHEMA
|
||||
],
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ProjectQuotasComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should get config', () => {
|
||||
expect(component.allConfig.count_per_project.value).toEqual(10);
|
||||
});
|
||||
});
|
@ -0,0 +1,40 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Configuration } from "@harbor/ui";
|
||||
import { SessionService } from "../shared/session.service";
|
||||
import { ConfigurationService } from "../config/config.service";
|
||||
import { MessageHandlerService } from "../shared/message-handler/message-handler.service";
|
||||
import { finalize } from "rxjs/operators";
|
||||
|
||||
@Component({
|
||||
selector: 'app-project-quotas',
|
||||
templateUrl: './project-quotas.component.html',
|
||||
styleUrls: ['./project-quotas.component.scss']
|
||||
})
|
||||
export class ProjectQuotasComponent implements OnInit {
|
||||
allConfig: Configuration = new Configuration();
|
||||
loading: boolean = false;
|
||||
constructor(private session: SessionService,
|
||||
private configService: ConfigurationService,
|
||||
private msgHandler: MessageHandlerService) { }
|
||||
|
||||
ngOnInit() {
|
||||
let currentUser = this.session.getCurrentUser();
|
||||
if (currentUser && currentUser.has_admin_role) {
|
||||
this.retrieveConfig();
|
||||
}
|
||||
}
|
||||
|
||||
refreshAllconfig() {
|
||||
this.retrieveConfig();
|
||||
}
|
||||
retrieveConfig(): void {
|
||||
this.loading = true;
|
||||
this.configService.getConfiguration()
|
||||
.pipe(finalize(() => this.loading = false))
|
||||
.subscribe((configurations: Configuration) => {
|
||||
this.allConfig = configurations;
|
||||
}, error => {
|
||||
this.msgHandler.handleError(error);
|
||||
});
|
||||
}
|
||||
}
|
@ -74,7 +74,7 @@
|
||||
<clr-dg-row *clrDgItems="let scanner of scanners" [clrDgItem]="scanner">
|
||||
<clr-dg-cell>{{scanner.name}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{scanner.url}}</clr-dg-cell>
|
||||
<clr-dg-cell>
|
||||
<clr-dg-cell class="position-relative">
|
||||
<span *ngIf="scanner.is_default" class="label label-info label-in-cell">{{scanner.is_default}}</span>
|
||||
<span *ngIf="!scanner.is_default">{{scanner.is_default}}</span>
|
||||
</clr-dg-cell>
|
||||
|
@ -288,3 +288,7 @@
|
||||
.float-lg-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.position-relative {
|
||||
position: relative;
|
||||
}
|
||||
|
@ -166,7 +166,8 @@
|
||||
"REPLICATION": "Replications",
|
||||
"CONFIG": "Configuration",
|
||||
"VULNERABILITY": "Vulnerability",
|
||||
"GARBAGE_COLLECTION": "Garbage Collection"
|
||||
"GARBAGE_COLLECTION": "Garbage Collection",
|
||||
"INTERROGATION_SERVICES": "Interrogation Services"
|
||||
},
|
||||
"LOGS": "Logs",
|
||||
"TASKS": "Tasks",
|
||||
|
@ -166,7 +166,8 @@
|
||||
"REPLICATION": "Replicacións",
|
||||
"CONFIG": "Configuración",
|
||||
"VULNERABILITY": "Vulnerability",
|
||||
"GARBAGE_COLLECTION": "Garbage Collection"
|
||||
"GARBAGE_COLLECTION": "Garbage Collection",
|
||||
"INTERROGATION_SERVICES": "Interrogation Services"
|
||||
},
|
||||
"LOGS": "Logs",
|
||||
"TASKS": "Tasks",
|
||||
|
@ -160,7 +160,8 @@
|
||||
"REPLICATION": "Réplication",
|
||||
"CONFIG": "Configuration",
|
||||
"VULNERABILITY": "Vulnerability",
|
||||
"GARBAGE_COLLECTION": "Garbage Collection"
|
||||
"GARBAGE_COLLECTION": "Garbage Collection",
|
||||
"INTERROGATION_SERVICES": "Interrogation Services"
|
||||
},
|
||||
"LOGS": "Logs",
|
||||
"TASKS": "Tasks",
|
||||
|
@ -164,7 +164,8 @@
|
||||
"REPLICATION": "Replicações",
|
||||
"CONFIG": "Configuração",
|
||||
"VULNERABILITY": "Vulnerability",
|
||||
"GARBAGE_COLLECTION": "Garbage Collection"
|
||||
"GARBAGE_COLLECTION": "Garbage Collection",
|
||||
"INTERROGATION_SERVICES": "Interrogation Services"
|
||||
},
|
||||
"LOGS": "Logs",
|
||||
"TASKS": "Tasks",
|
||||
|
@ -166,7 +166,8 @@
|
||||
"REPLICATION": "Kopyalama",
|
||||
"CONFIG": "Yapılandırma",
|
||||
"VULNERABILITY": "Güvenlik Açığı",
|
||||
"GARBAGE_COLLECTION": "Çöp toplama"
|
||||
"GARBAGE_COLLECTION": "Çöp toplama",
|
||||
"INTERROGATION_SERVICES": "Interrogation Services"
|
||||
},
|
||||
"LOGS": "Kayıtlar",
|
||||
"TASKS": "Görevler",
|
||||
|
@ -165,7 +165,8 @@
|
||||
"REPLICATION": "同步管理",
|
||||
"CONFIG": "配置管理",
|
||||
"VULNERABILITY": "漏洞",
|
||||
"GARBAGE_COLLECTION": "垃圾清理"
|
||||
"GARBAGE_COLLECTION": "垃圾清理",
|
||||
"INTERROGATION_SERVICES": "审查服务"
|
||||
},
|
||||
"LOGS": "日志",
|
||||
"TASKS": "任务",
|
||||
|
@ -154,9 +154,7 @@ Switch To System Settings
|
||||
|
||||
Switch To Project Quotas
|
||||
Sleep 1
|
||||
Retry Element Click xpath=${configuration_xpath}
|
||||
Retry Element Click xpath=${configuration_system_tabsheet_id}
|
||||
Retry Element Click xpath=${configuration_project_quotas_tabsheet_id}
|
||||
Retry Element Click xpath=//clr-main-container//clr-vertical-nav//a[contains(.,'Project Quotas')]
|
||||
Sleep 1
|
||||
|
||||
Modify Token Expiration
|
||||
@ -243,8 +241,7 @@ Disable Read Only
|
||||
## System labels
|
||||
Switch To System Labels
|
||||
Sleep 1
|
||||
Retry Element Click xpath=${configuration_xpath}
|
||||
Retry Element Click xpath=//*[@id='config-label']
|
||||
Retry Element Click xpath=//clr-main-container//clr-vertical-nav//a[contains(.,'Labels')]
|
||||
|
||||
## System labels
|
||||
Switch To Configuration System Setting
|
||||
@ -254,8 +251,7 @@ Switch To Configuration System Setting
|
||||
|
||||
Switch To Configuration Project Quotas
|
||||
Sleep 1
|
||||
Retry Element Click xpath=${configuration_xpath}
|
||||
Retry Element Click xpath=${configuration_project_quotas}
|
||||
Retry Element Click xpath=//clr-main-container//clr-vertical-nav//a[contains(.,'Project Quotas')]
|
||||
|
||||
Create New Labels
|
||||
[Arguments] ${labelname}
|
||||
|
@ -18,7 +18,8 @@ Trigger Scan Now
|
||||
Sleep 10
|
||||
|
||||
Switch To Vulnerability Page
|
||||
Retry Element Click xpath=${vulnerability_page}
|
||||
Retry Element Click xpath=//clr-main-container//clr-vertical-nav//a[contains(.,'Interrogation')]
|
||||
Retry Element Click xpath=//app-interrogation-services//a[contains(.,'Vulnerability')]
|
||||
Retry Wait Element ${scan_now_button}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user