Enhancements to configuration sharable component

This commit is contained in:
Steven Zou 2017-07-05 16:10:47 +08:00
parent f50a125d61
commit c3dd5e6d12
9 changed files with 147 additions and 42 deletions

View File

@ -100,7 +100,7 @@ export class Configuration {
this.verify_remote_cert = new BoolValueItem(false, true);
this.scan_all_policy = new ComplexValueItem({
type: "daily",
parameters: {
parameter: {
daily_time: 0
}
}, true);

View File

@ -1,7 +1,12 @@
export const REGISTRY_CONFIG_HTML: string = `
<div>
<replication-config [(replicationConfig)]="config"></replication-config>
<system-settings [(systemSettings)]="config"></system-settings>
<vulnerability-config [(vulnerabilityConfig)]="config"></vulnerability-config>
<replication-config #replicationConfig [(replicationConfig)]="config"></replication-config>
<system-settings #systemSettings [(systemSettings)]="config"></system-settings>
<vulnerability-config #vulnerabilityConfig [(vulnerabilityConfig)]="config"></vulnerability-config>
<div>
<button type="button" class="btn btn-primary" (click)="save()" [disabled]="shouldDisable">{{'BUTTON.SAVE' | translate}}</button>
<button type="button" class="btn btn-outline" (click)="cancel()" [disabled]="shouldDisable">{{'BUTTON.CANCEL' | translate}}</button>
</div>
<confirmation-dialog #cfgConfirmationDialog (confirmAction)="confirmCancel($event)"></confirmation-dialog>
</div>
`;

View File

@ -8,6 +8,7 @@ import { ReplicationConfigComponent } from './replication/replication-config.com
import { SystemSettingsComponent } from './system/system-settings.component';
import { VulnerabilityConfigComponent } from './vulnerability/vulnerability-config.component';
import { RegistryConfigComponent } from './registry-config.component';
import { ConfirmationDialogComponent } from '../confirmation-dialog/confirmation-dialog.component';
import {
ConfigurationService,
@ -29,7 +30,7 @@ describe('RegistryConfigComponent (inline template)', () => {
mockConfig.verify_remote_cert.value = true;
mockConfig.scan_all_policy.value = {
type: "daily",
parameters: {
parameter: {
daily_time: 0
}
};
@ -46,7 +47,8 @@ describe('RegistryConfigComponent (inline template)', () => {
ReplicationConfigComponent,
SystemSettingsComponent,
VulnerabilityConfigComponent,
RegistryConfigComponent
RegistryConfigComponent,
ConfirmationDialogComponent
],
providers: [
ErrorHandler,

View File

@ -1,10 +1,22 @@
import { Component, OnInit, EventEmitter, Output } from '@angular/core';
import { Component, OnInit, EventEmitter, Output, ViewChild } from '@angular/core';
import { Configuration, ComplexValueItem } from './config';
import { REGISTRY_CONFIG_HTML } from './registry-config.component.html';
import { ConfigurationService } from '../service/index';
import { toPromise } from '../utils';
import { ErrorHandler } from '../error-handler';
import {
ReplicationConfigComponent,
SystemSettingsComponent,
VulnerabilityConfigComponent
} from './index';
import { ConfirmationState, ConfirmationTargets, ConfirmationButtons } from '../shared/shared.const';
import { ConfirmationDialogComponent } from '../confirmation-dialog/confirmation-dialog.component';
import { ConfirmationMessage } from '../confirmation-dialog/confirmation-message';
import { ConfirmationAcknowledgement } from '../confirmation-dialog/confirmation-state-message';
import { TranslateService } from '@ngx-translate/core';
@Component({
selector: 'hbr-registry-config',
@ -13,27 +25,56 @@ import { ErrorHandler } from '../error-handler';
export class RegistryConfigComponent implements OnInit {
config: Configuration = new Configuration();
configCopy: Configuration;
onGoing: boolean = false;
@Output() configChanged: EventEmitter<any> = new EventEmitter<any>();
@ViewChild("replicationConfig") replicationCfg: ReplicationConfigComponent;
@ViewChild("systemSettings") systemSettings: SystemSettingsComponent;
@ViewChild("vulnerabilityConfig") vulnerabilityCfg: VulnerabilityConfigComponent;
@ViewChild("cfgConfirmationDialog") confirmationDlg: ConfirmationDialogComponent;
constructor(
private configService: ConfigurationService,
private errorHandler: ErrorHandler
private errorHandler: ErrorHandler,
private translate: TranslateService
) { }
get shouldDisable(): boolean {
return !this.isValid() || !this.hasChanges() || this.onGoing;
}
ngOnInit(): void {
//Initialize
this.load();
}
isValid(): boolean {
return this.replicationCfg &&
this.replicationCfg.isValid &&
this.systemSettings &&
this.systemSettings.isValid &&
this.vulnerabilityCfg &&
this.vulnerabilityCfg.isValid;
}
hasChanges(): boolean {
return !this._isEmptyObject(this.getChanges());
}
//Load configurations
load(): void {
this.onGoing = true;
toPromise<Configuration>(this.configService.getConfigurations())
.then((config: Configuration) => {
this.configCopy = Object.assign({}, config);
this.onGoing = false;
this.configCopy = this._clone(config);
this.config = config;
})
.catch(error => this.errorHandler.error(error));
.catch(error => {
this.onGoing = false;
this.errorHandler.error(error);
});
}
//Save configuration changes
@ -45,26 +86,48 @@ export class RegistryConfigComponent implements OnInit {
return;
}
//Fix policy parameters issue
let scanningAllPolicy = changes["scan_all_policy"];
if (scanningAllPolicy &&
scanningAllPolicy.type !== "daily" &&
scanningAllPolicy.parameters) {
delete (scanningAllPolicy.parameters);
}
this.onGoing = true;
toPromise<any>(this.configService.saveConfigurations(changes))
.then(() => {
this.configChanged.emit(changes);
this.onGoing = false;
this.translate.get("CONFIG.SAVE_SUCCESS").subscribe((res: string) => {
this.errorHandler.info(res);
});
//Reload to fetch all the updates
this.load();
})
.catch(error => this.errorHandler.error(error));
.catch(error => {
this.onGoing = false;
this.errorHandler.error(error);
});
}
//Cancel the changes if have
cancel(): void {
let msg = new ConfirmationMessage(
"CONFIG.CONFIRM_TITLE",
"CONFIG.CONFIRM_SUMMARY",
"",
{},
ConfirmationTargets.CONFIG
);
this.confirmationDlg.open(msg);
}
//Confirm cancel
confirmCancel(ack: ConfirmationAcknowledgement): void {
if (ack && ack.source === ConfirmationTargets.CONFIG &&
ack.state === ConfirmationState.CONFIRMED) {
this.reset();
}
}
reset(): void {
//Reset to the values of copy
let changes: { [key: string]: any | any[] } = this.getChanges();
for (let prop in changes) {
this.config[prop] = Object.assign({}, this.configCopy[prop]);
this.config[prop] = this._clone(this.configCopy[prop]);
}
}
@ -107,4 +170,10 @@ export class RegistryConfigComponent implements OnInit {
_isEmptyObject(obj: any): boolean {
return !obj || JSON.stringify(obj) === "{}";
}
//Deeper clone all
_clone(srcObj: any): any {
if (!srcObj) return null;
return JSON.parse(JSON.stringify(srcObj));
}
}

View File

@ -5,7 +5,7 @@ export const VULNERABILITY_CONFIG_HTML: string = `
<div class="form-group">
<label for="scanAllPolicy">{{ 'CONFIG.SCANNING.SCAN_ALL' | translate }}</label>
<div class="select">
<select id="scanAllPolicy" name="scanAllPolicy" [disabled]="!editable" [(ngModel)]="vulnerabilityConfig.scan_all_policy.value.type">
<select id="scanAllPolicy" name="scanAllPolicy" [disabled]="!editable" [(ngModel)]="scanningType">
<option value="none">{{ 'CONFIG.SCANNING.NONE_POLICY' | translate }}</option>
<option value="daily">{{ 'CONFIG.SCANNING.DAILY_POLICY' | translate }}</option>
<option value="on_refresh">{{ 'CONFIG.SCANNING.REFRESH_POLICY' | translate }}</option>

View File

@ -30,13 +30,13 @@ export class VulnerabilityConfigComponent {
this.config = cfg;
if (this.config.scan_all_policy &&
this.config.scan_all_policy.value) {
if (this.config.scan_all_policy.value.type === "daily"){
if(!this.config.scan_all_policy.value.parameters){
this.config.scan_all_policy.value.parameters = {
daily_time: 0
};
}
if (this.config.scan_all_policy.value.type === "daily") {
if (!this.config.scan_all_policy.value.parameter) {
this.config.scan_all_policy.value.parameter = {
daily_time: 0
};
}
}
}
this.configChange.emit(this.config);
}
@ -51,8 +51,8 @@ export class VulnerabilityConfigComponent {
}
let timeOffset: number = 0;//seconds
if (this.config.scan_all_policy.value.parameters) {
let daily_time = this.config.scan_all_policy.value.parameters.daily_time;
if (this.config.scan_all_policy.value.parameter) {
let daily_time = this.config.scan_all_policy.value.parameter.daily_time;
if (daily_time && typeof daily_time === "number") {
timeOffset = +daily_time;
}
@ -99,8 +99,9 @@ export class VulnerabilityConfigComponent {
return;
}
if (!this.config.scan_all_policy.value.parameters) {
this.config.scan_all_policy.value.parameters = {
//Double confirm inner parameter existing.
if (!this.config.scan_all_policy.value.parameter) {
this.config.scan_all_policy.value.parameter = {
daily_time: 0
};
}
@ -124,7 +125,41 @@ export class VulnerabilityConfigComponent {
utcTimes -= ONE_DAY_SECONDS;
}
this.config.scan_all_policy.value.parameters.daily_time = utcTimes;
this.config.scan_all_policy.value.parameter.daily_time = utcTimes;
}
//Scanning type
get scanningType(): string {
if (this.config &&
this.config.scan_all_policy &&
this.config.scan_all_policy.value) {
return this.config.scan_all_policy.value.type;
} else {
//default
return "none";
}
}
set scanningType(v: string) {
if (this.config &&
this.config.scan_all_policy &&
this.config.scan_all_policy.value) {
let type: string = (v && v.trim() !== "") ? v : "none";
this.config.scan_all_policy.value.type = type;
if (type !== "daily") {
//No parameter
if (this.config.scan_all_policy.value.parameter) {
delete (this.config.scan_all_policy.value.parameter);
}
} else {
//Has parameter
if (!this.config.scan_all_policy.value.parameter) {
this.config.scan_all_policy.value.parameter = {
daily_time: 0
};
}
}
}
}
@ViewChild("systemConfigFrom") systemSettingsForm: NgForm;

View File

@ -31,7 +31,7 @@
"clarity-icons": "^0.9.8",
"clarity-ui": "^0.9.8",
"core-js": "^2.4.1",
"harbor-ui": "^0.2.40",
"harbor-ui": "^0.2.52",
"intl": "^1.2.5",
"mutationobserver-shim": "^0.3.2",
"ngx-cookie": "^1.0.0",

View File

@ -16,7 +16,7 @@
<button id="config-system" class="btn btn-link nav-link" aria-controls="system_settings" [class.active]='isCurrentTabLink("config-system")' type="button" (click)='tabLinkClick("config-system")'>{{'CONFIG.SYSTEM' | translate }}</button>
</li>
<li role="presentation" class="nav-item">
<button id="config-vulnerability" class="btn btn-link nav-link" aria-controls="vulnerability" [class.active]='isCurrentTabLink("config-vulnerability")' type="button" (click)='tabLinkClick("config-vulnerability")'>Vulnerability</button>
<button id="config-vulnerability" class="btn btn-link nav-link" aria-controls="vulnerability" [class.active]='isCurrentTabLink("config-vulnerability")' type="button" (click)='tabLinkClick("config-vulnerability")'>{{'VULNERABILITY.SINGULAR' | translate}}</button>
</li>
</ul>
<section id="authentication" role="tabpanel" aria-labelledby="config-auth" [hidden]='!isCurrentTabContent("authentication")'>
@ -41,7 +41,6 @@
<button type="button" class="btn btn-outline" (click)="testLDAPServer()" *ngIf="showLdapServerBtn" [disabled]="!isLDAPConfigValid()">{{'BUTTON.TEST_LDAP' | translate}}</button>
<span id="forTestingMail" class="spinner spinner-inline" [hidden]="hideMailTestingSpinner"></span>
<span id="forTestingLDAP" class="spinner spinner-inline" [hidden]="hideLDAPTestingSpinner"></span>
<button type="button" class="btn btn-primary" (click)="consoleTest()">CONSOLE</button>
</div>
</div>
</div>

View File

@ -71,11 +71,6 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
private appConfigService: AppConfigService,
private session: SessionService) { }
consoleTest(): void {
console.log(this.allConfig, this.originalCopy);
console.log("-------------");
console.log(this.getChanges());
}
isCurrentTabLink(tabId: string): boolean {
return this.currentTabId === tabId;
}