diff --git a/src/replication/core/controller.go b/src/replication/core/controller.go index 3db5671d2..b2ad7540f 100644 --- a/src/replication/core/controller.go +++ b/src/replication/core/controller.go @@ -208,7 +208,7 @@ func (ctl *DefaultController) Replicate(policyID int64, metadata ...map[string]i // prepare candidates for replication candidates := getCandidates(&policy, ctl.sourcer, metadata...) if len(candidates) == 0 { - log.Debugf("replicaton candidates are null, no further action needed") + log.Debugf("replication candidates are null, no further action needed") } targets := []*common_models.RepTarget{} diff --git a/src/ui_ng/lib/index.ts b/src/ui_ng/lib/index.ts index f3c80e03c..cba184354 100644 --- a/src/ui_ng/lib/index.ts +++ b/src/ui_ng/lib/index.ts @@ -1 +1 @@ -export * from './src/index'; \ No newline at end of file +export * from './src/index'; diff --git a/src/ui_ng/lib/package.json b/src/ui_ng/lib/package.json index 338448728..8ceeee1e9 100644 --- a/src/ui_ng/lib/package.json +++ b/src/ui_ng/lib/package.json @@ -1,6 +1,6 @@ { "name": "harbor-ui", - "version": "0.7.18-dev.6", + "version": "0.7.18-dev.8", "description": "Harbor shared UI components based on Clarity and Angular4", "author": "VMware", "module": "index.js", diff --git a/src/ui_ng/lib/src/channel/channel.service.ts b/src/ui_ng/lib/src/channel/channel.service.ts index 69788ce5d..e9035fad8 100644 --- a/src/ui_ng/lib/src/channel/channel.service.ts +++ b/src/ui_ng/lib/src/channel/channel.service.ts @@ -13,16 +13,17 @@ // limitations under the License. import { Injectable } from '@angular/core'; import { Subject } from 'rxjs/Subject'; +// tslint:disable-next-line:no-unused-variable import { Observable } from "rxjs/Observable"; @Injectable() export class ChannelService { - //Declare for publishing scan event + // Declare for publishing scan event scanCommandSource = new Subject(); scanCommand$ = this.scanCommandSource.asObservable(); publishScanEvent(tagId: string): void { this.scanCommandSource.next(tagId); } -} \ No newline at end of file +} diff --git a/src/ui_ng/lib/src/channel/index.ts b/src/ui_ng/lib/src/channel/index.ts index 53dcbeb6f..6d663c216 100644 --- a/src/ui_ng/lib/src/channel/index.ts +++ b/src/ui_ng/lib/src/channel/index.ts @@ -1 +1 @@ -export * from './channel.service'; \ No newline at end of file +export * from './channel.service'; diff --git a/src/ui_ng/lib/src/config/config.ts b/src/ui_ng/lib/src/config/config.ts index 624967756..07631722a 100644 --- a/src/ui_ng/lib/src/config/config.ts +++ b/src/ui_ng/lib/src/config/config.ts @@ -119,4 +119,4 @@ export class Configuration { }, true); this.read_only = new BoolValueItem(false, true); } -} \ No newline at end of file +} diff --git a/src/ui_ng/lib/src/config/index.ts b/src/ui_ng/lib/src/config/index.ts index 4abd60d4b..0d9671725 100644 --- a/src/ui_ng/lib/src/config/index.ts +++ b/src/ui_ng/lib/src/config/index.ts @@ -16,4 +16,4 @@ export const CONFIGURATION_DIRECTIVES: Type[] = [ SystemSettingsComponent, VulnerabilityConfigComponent, RegistryConfigComponent -]; \ No newline at end of file +]; diff --git a/src/ui_ng/lib/src/config/registry-config.component.spec.ts b/src/ui_ng/lib/src/config/registry-config.component.spec.ts index eb47d4fa4..84ed549ce 100644 --- a/src/ui_ng/lib/src/config/registry-config.component.spec.ts +++ b/src/ui_ng/lib/src/config/registry-config.component.spec.ts @@ -114,4 +114,4 @@ describe('RegistryConfigComponent (inline template)', () => { expect(saveSpy.calls.any).toBeTruthy(); })); -}); \ No newline at end of file +}); diff --git a/src/ui_ng/lib/src/config/registry-config.component.ts b/src/ui_ng/lib/src/config/registry-config.component.ts index 30ddf4139..fcf6ed468 100644 --- a/src/ui_ng/lib/src/config/registry-config.component.ts +++ b/src/ui_ng/lib/src/config/registry-config.component.ts @@ -1,7 +1,11 @@ -import { Component, OnInit, EventEmitter, Output, ViewChild, Input } from '@angular/core'; +import { Component, OnInit, ViewChild, Input } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; -import { Configuration, ComplexValueItem } from './config'; -import { ConfigurationService, SystemInfoService, SystemInfo, ClairDBStatus } from '../service/index'; +import { ConfirmationState, ConfirmationTargets } 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 { ConfigurationService, SystemInfoService, SystemInfo } from '../service/index'; import { toPromise, compareValue, @@ -9,17 +13,8 @@ import { clone } from '../utils'; import { ErrorHandler } from '../error-handler/index'; -import { - 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'; - +import { SystemSettingsComponent, VulnerabilityConfigComponent } from './index'; +import { Configuration } from './config'; @Component({ selector: 'hbr-registry-config', @@ -62,7 +57,7 @@ export class RegistryConfigComponent implements OnInit { ngOnInit(): void { this.loadSystemInfo(); - //Initialize + // Initialize this.load(); } @@ -77,14 +72,14 @@ export class RegistryConfigComponent implements OnInit { return !isEmptyObject(this.getChanges()); } - //Get system info + // Get system info loadSystemInfo(): void { toPromise(this.systemInfoService.getSystemInfo()) .then((info: SystemInfo) => this.systemInfo = info) .catch(error => this.errorHandler.error(error)); } - //Load configurations + // Load configurations load(): void { this.onGoing = true; toPromise(this.configService.getConfigurations()) @@ -99,12 +94,12 @@ export class RegistryConfigComponent implements OnInit { }); } - //Save configuration changes + // Save configuration changes save(): void { let changes: { [key: string]: any | any[] } = this.getChanges(); if (isEmptyObject(changes)) { - //Guard code, do nothing + // Guard code, do nothing return; } @@ -116,10 +111,10 @@ export class RegistryConfigComponent implements OnInit { this.translate.get("CONFIG.SAVE_SUCCESS").subscribe((res: string) => { this.errorHandler.info(res); }); - //Reload to fetch all the updates + // Reload to fetch all the updates this.load(); - //Reload all system info - //this.loadSystemInfo(); + // Reload all system info + // this.loadSystemInfo(); }) .catch(error => { this.onGoing = false; @@ -127,7 +122,7 @@ export class RegistryConfigComponent implements OnInit { }); } - //Cancel the changes if have + // Cancel the changes if have cancel(): void { let msg = new ConfirmationMessage( "CONFIG.CONFIRM_TITLE", @@ -139,7 +134,7 @@ export class RegistryConfigComponent implements OnInit { this.confirmationDlg.open(msg); } - //Confirm cancel + // Confirm cancel confirmCancel(ack: ConfirmationAcknowledgement): void { if (ack && ack.source === ConfirmationTargets.CONFIG && ack.state === ConfirmationState.CONFIRMED) { @@ -148,9 +143,9 @@ export class RegistryConfigComponent implements OnInit { } reset(): void { - //Reset to the values of copy + // Reset to the values of copy let changes: { [key: string]: any | any[] } = this.getChanges(); - for (let prop in changes) { + for (let prop of Object.keys(changes)) { this.config[prop] = clone(this.configCopy[prop]); } } @@ -161,17 +156,17 @@ export class RegistryConfigComponent implements OnInit { return changes; } - for (let prop in this.config) { + for (let prop of Object.keys(this.config)) { let field = this.configCopy[prop]; if (field && field.editable) { if (!compareValue(field.value, this.config[prop].value)) { changes[prop] = this.config[prop].value; - //Number + // Number if (typeof field.value === "number") { changes[prop] = +changes[prop]; } - //Trim string value + // Trim string value if (typeof field.value === "string") { changes[prop] = ('' + changes[prop]).trim(); } @@ -181,4 +176,4 @@ export class RegistryConfigComponent implements OnInit { return changes; } -} \ No newline at end of file +} diff --git a/src/ui_ng/lib/src/config/replication/replication-config.component.ts b/src/ui_ng/lib/src/config/replication/replication-config.component.ts index 5d8bd96f6..e8f385a29 100644 --- a/src/ui_ng/lib/src/config/replication/replication-config.component.ts +++ b/src/ui_ng/lib/src/config/replication/replication-config.component.ts @@ -21,7 +21,7 @@ export class ReplicationConfigComponent { this.configChange.emit(this.config); } - @Input() showSubTitle: boolean = false + @Input() showSubTitle: boolean = false; @ViewChild("replicationConfigFrom") replicationConfigForm: NgForm; @@ -34,4 +34,4 @@ export class ReplicationConfigComponent { get isValid(): boolean { return this.replicationConfigForm && this.replicationConfigForm.valid; } -} \ No newline at end of file +} diff --git a/src/ui_ng/lib/src/config/system/system-settings.component.ts b/src/ui_ng/lib/src/config/system/system-settings.component.ts index 4d1dc61ee..a66a9fe4c 100644 --- a/src/ui_ng/lib/src/config/system/system-settings.component.ts +++ b/src/ui_ng/lib/src/config/system/system-settings.component.ts @@ -53,4 +53,4 @@ export class SystemSettingsComponent { this.downloadLink = this.configInfo.systemInfoEndpoint + "/getcert"; } } -} \ No newline at end of file +} diff --git a/src/ui_ng/lib/src/config/vulnerability/vulnerability-config.component.ts b/src/ui_ng/lib/src/config/vulnerability/vulnerability-config.component.ts index 41f89c517..3a09083a9 100644 --- a/src/ui_ng/lib/src/config/vulnerability/vulnerability-config.component.ts +++ b/src/ui_ng/lib/src/config/vulnerability/vulnerability-config.component.ts @@ -10,7 +10,7 @@ import { import { ErrorHandler } from '../../error-handler/index'; import { toPromise } from '../../utils'; import { TranslateService } from '@ngx-translate/core'; -import { ClairDBStatus, ClairDetail } from '../../service/interface'; +import { ClairDetail } from '../../service/interface'; const ONE_HOUR_SECONDS: number = 3600; const ONE_DAY_SECONDS: number = 24 * ONE_HOUR_SECONDS; @@ -85,7 +85,7 @@ export class VulnerabilityConfigComponent implements OnInit { return []; } - //UTC time + // UTC time get dailyTime(): string { if (!(this.config && this.config.scan_all_policy && @@ -94,7 +94,7 @@ export class VulnerabilityConfigComponent implements OnInit { return "00:00"; } - let timeOffset: number = 0;//seconds + let timeOffset: number = 0; // seconds 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") { @@ -102,9 +102,9 @@ export class VulnerabilityConfigComponent implements OnInit { } } - //Convert to current time + // Convert to current time let timezoneOffset: number = this._localTime.getTimezoneOffset(); - //Local time + // Local time timeOffset = timeOffset - timezoneOffset * 60; if (timeOffset < 0) { timeOffset = timeOffset + ONE_DAY_SECONDS; @@ -114,7 +114,7 @@ export class VulnerabilityConfigComponent implements OnInit { timeOffset -= ONE_DAY_SECONDS; } - //To time string + // To time string let hours: number = Math.floor(timeOffset / ONE_HOUR_SECONDS); let minutes: number = Math.floor((timeOffset - hours * ONE_HOUR_SECONDS) / 60); @@ -143,7 +143,7 @@ export class VulnerabilityConfigComponent implements OnInit { return; } - //Double confirm inner parameter existing. + // Double confirm inner parameter existing. if (!this.config.scan_all_policy.value.parameter) { this.config.scan_all_policy.value.parameter = { daily_time: 0 @@ -157,7 +157,7 @@ export class VulnerabilityConfigComponent implements OnInit { let hours: number = +values[0]; let minutes: number = +values[1]; - //Convert to UTC time + // Convert to UTC time let timezoneOffset: number = this._localTime.getTimezoneOffset(); let utcTimes: number = hours * ONE_HOUR_SECONDS + minutes * 60; utcTimes += timezoneOffset * 60; @@ -172,14 +172,14 @@ export class VulnerabilityConfigComponent implements OnInit { this.config.scan_all_policy.value.parameter.daily_time = utcTimes; } - //Scanning type + // 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 + // default return "none"; } } @@ -191,12 +191,12 @@ export class VulnerabilityConfigComponent implements OnInit { let type: string = (v && v.trim() !== "") ? v : "none"; this.config.scan_all_policy.value.type = type; if (type !== "daily") { - //No parameter + // No parameter if (this.config.scan_all_policy.value.parameter) { delete (this.config.scan_all_policy.value.parameter); } } else { - //Has parameter + // Has parameter if (!this.config.scan_all_policy.value.parameter) { this.config.scan_all_policy.value.parameter = { daily_time: 0 @@ -251,11 +251,11 @@ export class VulnerabilityConfigComponent implements OnInit { scanNow(): void { if (this.onSubmitting) { - return;//Aoid duplicated submitting + return; // Aoid duplicated submitting } - if(!this.scanAvailable) { - return; //Aoid page hacking + if (!this.scanAvailable) { + return; // Aoid page hacking } this.onSubmitting = true; @@ -265,7 +265,7 @@ export class VulnerabilityConfigComponent implements OnInit { this.errorHandler.info(res); }); - //Update system info + // Update system info this.getSystemInfo().then(() => { this.onSubmitting = false; }).catch(() => { @@ -284,9 +284,9 @@ export class VulnerabilityConfigComponent implements OnInit { }); } - getSystemInfo(): Promise { + getSystemInfo(): Promise { return toPromise(this.systemInfoService.getSystemInfo()) .then((info: SystemInfo) => this.systemInfo = info) .catch(error => this.errorHandler.error(error)); } -} \ No newline at end of file +} diff --git a/src/ui_ng/lib/src/confirmation-dialog/confirmation-message.ts b/src/ui_ng/lib/src/confirmation-dialog/confirmation-message.ts index a06f4fecd..afb080159 100644 --- a/src/ui_ng/lib/src/confirmation-dialog/confirmation-message.ts +++ b/src/ui_ng/lib/src/confirmation-dialog/confirmation-message.ts @@ -11,21 +11,31 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -import { ConfirmationTargets, ConfirmationButtons } from '../shared/shared.const'; +import { + ConfirmationTargets, + ConfirmationButtons +} from "../shared/shared.const"; export class ConfirmationMessage { - public constructor(title: string, message: string, param: string, data: any, targetId: ConfirmationTargets, buttons?: ConfirmationButtons) { - this.title = title; - this.message = message; - this.data = data; - this.targetId = targetId; - this.param = param; - this.buttons = buttons ? buttons : ConfirmationButtons.CONFIRM_CANCEL; - } - title: string; - message: string; - data: any = {};//default is empty - targetId: ConfirmationTargets = ConfirmationTargets.EMPTY; - param: string; - buttons: ConfirmationButtons; -} \ No newline at end of file + public constructor( + title: string, + message: string, + param: string, + data: any, + targetId: ConfirmationTargets, + buttons?: ConfirmationButtons + ) { + this.title = title; + this.message = message; + this.data = data; + this.targetId = targetId; + this.param = param; + this.buttons = buttons ? buttons : ConfirmationButtons.CONFIRM_CANCEL; + } + title: string; + message: string; + data: any = {}; // default is empty + targetId: ConfirmationTargets = ConfirmationTargets.EMPTY; + param: string; + buttons: ConfirmationButtons; +} diff --git a/src/ui_ng/lib/src/confirmation-dialog/confirmation-state-message.ts b/src/ui_ng/lib/src/confirmation-dialog/confirmation-state-message.ts index 19c15ff4c..ea2e0689e 100644 --- a/src/ui_ng/lib/src/confirmation-dialog/confirmation-state-message.ts +++ b/src/ui_ng/lib/src/confirmation-dialog/confirmation-state-message.ts @@ -23,4 +23,4 @@ export class ConfirmationAcknowledgement { state: ConfirmationState = ConfirmationState.NA; data: any = {}; source: ConfirmationTargets = ConfirmationTargets.EMPTY; -} \ No newline at end of file +} diff --git a/src/ui_ng/lib/src/confirmation-dialog/index.ts b/src/ui_ng/lib/src/confirmation-dialog/index.ts index 9ff71ecb0..bf21ae196 100644 --- a/src/ui_ng/lib/src/confirmation-dialog/index.ts +++ b/src/ui_ng/lib/src/confirmation-dialog/index.ts @@ -1,6 +1,6 @@ -import { Type } from '@angular/core'; +import { Type } from "@angular/core"; -import { ConfirmationDialogComponent } from './confirmation-dialog.component'; +import { ConfirmationDialogComponent } from "./confirmation-dialog.component"; export * from "./confirmation-dialog.component"; export * from "./confirmation-batch-message"; @@ -9,4 +9,4 @@ export * from "./confirmation-state-message"; export const CONFIRMATION_DIALOG_DIRECTIVES: Type[] = [ ConfirmationDialogComponent -]; \ No newline at end of file +]; diff --git a/src/ui_ng/lib/src/create-edit-endpoint/create-edit-endpoint.component.spec.ts b/src/ui_ng/lib/src/create-edit-endpoint/create-edit-endpoint.component.spec.ts index 59bb2d26c..1f9ab77fd 100644 --- a/src/ui_ng/lib/src/create-edit-endpoint/create-edit-endpoint.component.spec.ts +++ b/src/ui_ng/lib/src/create-edit-endpoint/create-edit-endpoint.component.spec.ts @@ -1,35 +1,39 @@ -import { ComponentFixture, TestBed, async, fakeAsync, tick } from '@angular/core/testing'; +import { + ComponentFixture, + TestBed, + async +} from "@angular/core/testing"; import { NoopAnimationsModule } from "@angular/platform-browser/animations"; -import { By } from '@angular/platform-browser'; -import { DebugElement } from '@angular/core'; -import { SharedModule } from '../shared/shared.module'; +import { SharedModule } from "../shared/shared.module"; -import { FilterComponent } from '../filter/filter.component'; - -import { CreateEditEndpointComponent } from '../create-edit-endpoint/create-edit-endpoint.component'; -import { InlineAlertComponent } from '../inline-alert/inline-alert.component'; -import { ErrorHandler } from '../error-handler/error-handler'; -import { Endpoint } from '../service/interface'; -import { EndpointService, EndpointDefaultService } from '../service/endpoint.service'; -import { IServiceConfig, SERVICE_CONFIG } from '../service.config'; -describe('CreateEditEndpointComponent (inline template)', () => { +import { FilterComponent } from "../filter/filter.component"; +import { CreateEditEndpointComponent } from "../create-edit-endpoint/create-edit-endpoint.component"; +import { InlineAlertComponent } from "../inline-alert/inline-alert.component"; +import { ErrorHandler } from "../error-handler/error-handler"; +import { Endpoint } from "../service/interface"; +import { + EndpointService, + EndpointDefaultService +} from "../service/endpoint.service"; +import { IServiceConfig, SERVICE_CONFIG } from "../service.config"; +describe("CreateEditEndpointComponent (inline template)", () => { let mockData: Endpoint = { - "id": 1, - "endpoint": "https://10.117.4.151", - "name": "target_01", - "username": "admin", - "password": "", - "insecure": false, - "type": 0 + id: 1, + endpoint: "https://10.117.4.151", + name: "target_01", + username: "admin", + password: "", + insecure: false, + type: 0 }; let comp: CreateEditEndpointComponent; let fixture: ComponentFixture; let config: IServiceConfig = { - systemInfoEndpoint: '/api/endpoints/testing' + systemInfoEndpoint: "/api/endpoints/testing" }; let endpointService: EndpointService; @@ -38,14 +42,12 @@ describe('CreateEditEndpointComponent (inline template)', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - imports: [ - SharedModule, - NoopAnimationsModule + imports: [SharedModule, NoopAnimationsModule], + declarations: [ + FilterComponent, + CreateEditEndpointComponent, + InlineAlertComponent ], - declarations: [ - FilterComponent, - CreateEditEndpointComponent, - InlineAlertComponent ], providers: [ ErrorHandler, { provide: SERVICE_CONFIG, useValue: config }, @@ -54,24 +56,26 @@ describe('CreateEditEndpointComponent (inline template)', () => { }); })); - beforeEach(()=>{ + beforeEach(() => { fixture = TestBed.createComponent(CreateEditEndpointComponent); comp = fixture.componentInstance; endpointService = fixture.debugElement.injector.get(EndpointService); - spy = spyOn(endpointService, 'getEndpoint').and.returnValue(Promise.resolve(mockData)); + spy = spyOn(endpointService, "getEndpoint").and.returnValue( + Promise.resolve(mockData) + ); fixture.detectChanges(); comp.openCreateEditTarget(true, 1); fixture.detectChanges(); }); - it('should be created', () => { + it("should be created", () => { fixture.detectChanges(); expect(comp).toBeTruthy(); }); - it('should get endpoint be called', async(() => { + it("should get endpoint be called", async(() => { fixture.detectChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); @@ -79,16 +83,16 @@ describe('CreateEditEndpointComponent (inline template)', () => { }); })); - it('should get endpoint and open modal', async(() => { + it("should get endpoint and open modal", async(() => { fixture.detectChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); - expect(comp.target.name).toEqual('target_01'); + expect(comp.target.name).toEqual("target_01"); }); })); - it('should endpoint be initialized', () => { + it("should endpoint be initialized", () => { fixture.detectChanges(); - expect(config.systemInfoEndpoint).toEqual('/api/endpoints/testing'); + expect(config.systemInfoEndpoint).toEqual("/api/endpoints/testing"); }); -}); \ No newline at end of file +}); diff --git a/src/ui_ng/lib/src/create-edit-endpoint/create-edit-endpoint.component.ts b/src/ui_ng/lib/src/create-edit-endpoint/create-edit-endpoint.component.ts index fe391e74e..cf828c03c 100644 --- a/src/ui_ng/lib/src/create-edit-endpoint/create-edit-endpoint.component.ts +++ b/src/ui_ng/lib/src/create-edit-endpoint/create-edit-endpoint.component.ts @@ -12,371 +12,367 @@ // See the License for the specific language governing permissions and // limitations under the License. import { - Component, - Output, - EventEmitter, - ViewChild, - AfterViewChecked, - ChangeDetectorRef, - OnDestroy -} from '@angular/core'; -import { NgForm } from '@angular/forms'; + Component, + Output, + EventEmitter, + ViewChild, + AfterViewChecked, + ChangeDetectorRef, + OnDestroy +} from "@angular/core"; +import { NgForm } from "@angular/forms"; +import { Subscription } from "rxjs/Subscription"; +import { TranslateService } from "@ngx-translate/core"; -import { EndpointService } from '../service/endpoint.service'; -import { ErrorHandler } from '../error-handler/index'; -import { ActionType } from '../shared/shared.const'; +import { EndpointService } from "../service/endpoint.service"; +import { ErrorHandler } from "../error-handler/index"; +import { InlineAlertComponent } from "../inline-alert/inline-alert.component"; +import { Endpoint } from "../service/interface"; +import { toPromise, clone, compareValue, isEmptyObject } from "../utils"; -import { InlineAlertComponent } from '../inline-alert/inline-alert.component'; -import { Endpoint } from '../service/interface'; - -import { TranslateService } from '@ngx-translate/core'; - -import { toPromise, clone, compareValue, isEmptyObject } from '../utils'; - -import { Subscription } from 'rxjs/Subscription'; - -const FAKE_PASSWORD = 'rjGcfuRu'; +const FAKE_PASSWORD = "rjGcfuRu"; @Component({ - selector: 'hbr-create-edit-endpoint', - templateUrl: './create-edit-endpoint.component.html', - styleUrls: ['./create-edit-endpoint.component.scss'] + selector: "hbr-create-edit-endpoint", + templateUrl: "./create-edit-endpoint.component.html", + styleUrls: ["./create-edit-endpoint.component.scss"] }) -export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy { - modalTitle: string; - createEditDestinationOpened: boolean; - staticBackdrop: boolean = true; - closable: boolean = false; - editable: boolean; +export class CreateEditEndpointComponent + implements AfterViewChecked, OnDestroy { + modalTitle: string; + createEditDestinationOpened: boolean; + staticBackdrop: boolean = true; + closable: boolean = false; + editable: boolean; - target: Endpoint = this.initEndpoint(); - initVal: Endpoint; + target: Endpoint = this.initEndpoint(); + initVal: Endpoint; - targetForm: NgForm; - @ViewChild('targetForm') - currentForm: NgForm; + targetForm: NgForm; + @ViewChild("targetForm") currentForm: NgForm; - testOngoing: boolean; - onGoing: boolean; - endpointId: number | string; + testOngoing: boolean; + onGoing: boolean; + endpointId: number | string; - @ViewChild(InlineAlertComponent) - inlineAlert: InlineAlertComponent; + @ViewChild(InlineAlertComponent) inlineAlert: InlineAlertComponent; - @Output() reload = new EventEmitter(); + @Output() reload = new EventEmitter(); - timerHandler: any; - valueChangesSub: Subscription; - formValues: { [key: string]: string } | any; + timerHandler: any; + valueChangesSub: Subscription; + formValues: { [key: string]: string } | any; - constructor( - private endpointService: EndpointService, - private errorHandler: ErrorHandler, - private translateService: TranslateService, - private ref: ChangeDetectorRef - ) { } + constructor( + private endpointService: EndpointService, + private errorHandler: ErrorHandler, + private translateService: TranslateService, + private ref: ChangeDetectorRef + ) {} - public get isValid(): boolean { - return !this.testOngoing && - !this.onGoing && - this.targetForm && - this.targetForm.valid && - this.editable && - !compareValue(this.target, this.initVal); + public get isValid(): boolean { + return ( + !this.testOngoing && + !this.onGoing && + this.targetForm && + this.targetForm.valid && + this.editable && + !compareValue(this.target, this.initVal) + ); + } + + public get inProgress(): boolean { + return this.onGoing || this.testOngoing; + } + + setInsecureValue($event: any) { + this.target.insecure = !$event; + } + + ngOnDestroy(): void { + if (this.valueChangesSub) { + this.valueChangesSub.unsubscribe(); } + } - public get inProgress(): boolean { - return this.onGoing || this.testOngoing; + initEndpoint(): Endpoint { + return { + endpoint: "", + name: "", + username: "", + password: "", + insecure: false, + type: 0 + }; + } + + open(): void { + this.createEditDestinationOpened = true; + } + + close(): void { + this.createEditDestinationOpened = false; + } + + reset(): void { + // Reset status variables + this.testOngoing = false; + this.onGoing = false; + + // Reset data + this.target = this.initEndpoint(); + this.initVal = this.initEndpoint(); + this.formValues = null; + this.endpointId = ""; + + this.inlineAlert.close(); + } + + // Forcely refresh the view + forceRefreshView(duration: number): void { + // Reset timer + if (this.timerHandler) { + clearInterval(this.timerHandler); } + this.timerHandler = setInterval(() => this.ref.markForCheck(), 100); + setTimeout(() => { + if (this.timerHandler) { + clearInterval(this.timerHandler); + this.timerHandler = null; + } + }, duration); + } - setInsecureValue($event: any) { - this.target.insecure = !$event; + openCreateEditTarget(editable: boolean, targetId?: number | string) { + this.editable = editable; + // reset + this.reset(); + if (targetId) { + this.endpointId = targetId; + this.translateService + .get("DESTINATION.TITLE_EDIT") + .subscribe(res => (this.modalTitle = res)); + toPromise(this.endpointService.getEndpoint(targetId)) + .then(target => { + this.target = target; + // Keep data cache + this.initVal = clone(target); + this.initVal.password = FAKE_PASSWORD; + this.target.password = FAKE_PASSWORD; + + // Open the modal now + this.open(); + this.forceRefreshView(2000); + }) + .catch(error => this.errorHandler.error(error)); + } else { + this.endpointId = ""; + this.translateService + .get("DESTINATION.TITLE_ADD") + .subscribe(res => (this.modalTitle = res)); + // Directly open the modal + this.open(); } + } - ngOnDestroy(): void { - if (this.valueChangesSub) { - this.valueChangesSub.unsubscribe(); - } - } - - initEndpoint(): Endpoint { - return { - endpoint: "", - name: "", - username: "", - password: "", - insecure: false, - type: 0 - }; - } - - open(): void { - this.createEditDestinationOpened = true; - } - - close(): void { - this.createEditDestinationOpened = false; - } - - reset(): void { - //Reset status variables - this.testOngoing = false; - this.onGoing = false; - - //Reset data - this.target = this.initEndpoint(); - this.initVal = this.initEndpoint(); - this.formValues = null; - this.endpointId = ''; - - this.inlineAlert.close(); - } - - //Forcely refresh the view - forceRefreshView(duration: number): void { - //Reset timer - if (this.timerHandler) { - clearInterval(this.timerHandler); - } - this.timerHandler = setInterval(() => this.ref.markForCheck(), 100); - setTimeout(() => { - if (this.timerHandler) { - clearInterval(this.timerHandler); - this.timerHandler = null; - } - }, duration); - } - - openCreateEditTarget(editable: boolean, targetId?: number | string) { - this.editable = editable; - //reset - this.reset(); - if (targetId) { - this.endpointId = targetId; - this.translateService.get('DESTINATION.TITLE_EDIT').subscribe(res => this.modalTitle = res); - toPromise(this.endpointService - .getEndpoint(targetId)) - .then( - target => { - this.target = target; - //Keep data cache - this.initVal = clone(target); - this.initVal.password = FAKE_PASSWORD; - this.target.password = FAKE_PASSWORD; - - //Open the modal now - this.open(); - this.forceRefreshView(2000); - }) - .catch(error => this.errorHandler.error(error)); - } else { - this.endpointId = ''; - this.translateService.get('DESTINATION.TITLE_ADD').subscribe(res => this.modalTitle = res); - //Directly open the modal - this.open(); - } - } - - testConnection() { - let payload: Endpoint = this.initEndpoint(); - if (!this.endpointId) { - payload.endpoint = this.target.endpoint; - payload.username = this.target.username; - payload.password = this.target.password; - payload.insecure = this.target.insecure; - }else { - let changes: {[key: string]: any} = this.getChanges(); - for (let prop in payload) { - delete payload[prop]; - } - payload.id = this.target.id; - if (!isEmptyObject(changes)) { - let changekeys: {[key: string]: any} = Object.keys(this.getChanges()); - changekeys.forEach((key: string) => { - payload[key] = changes[key]; - }); - } - } - - this.testOngoing = true; - toPromise(this.endpointService - .pingEndpoint(payload)) - .then( - response => { - this.inlineAlert.showInlineSuccess({ message: "DESTINATION.TEST_CONNECTION_SUCCESS" }); - this.forceRefreshView(2000); - this.testOngoing = false; - }).catch( - error => { - this.inlineAlert.showInlineError('DESTINATION.TEST_CONNECTION_FAILURE'); - this.forceRefreshView(2000); - this.testOngoing = false; - }); - } - - onSubmit() { - if (this.endpointId) { - this.updateEndpoint(); - } else { - this.addEndpoint(); - } - } - - addEndpoint() { - if (this.onGoing) { - return;//Avoid duplicated submitting - } - - this.onGoing = true; - toPromise(this.endpointService - .createEndpoint(this.target)) - .then(response => { - this.translateService.get('DESTINATION.CREATED_SUCCESS') - .subscribe(res => this.errorHandler.info(res)); - this.reload.emit(true); - this.onGoing = false; - this.close(); - this.forceRefreshView(2000); - }).catch(error => { - this.onGoing = false; - let errorMessageKey = this.handleErrorMessageKey(error.status); - this.translateService - .get(errorMessageKey) - .subscribe(res => { - this.inlineAlert.showInlineError(res); - }); - this.forceRefreshView(2000); - } - ); - - } - - updateEndpoint() { - if (this.onGoing) { - return;//Avoid duplicated submitting - } - - let payload: Endpoint = this.initEndpoint(); - for (let prop in payload) { - delete payload[prop]; - } - let changes: {[key: string]: any} = this.getChanges(); - if (isEmptyObject(changes)) { - return; - } - let changekeys: {[key: string]: any} = Object.keys(changes); - + testConnection() { + let payload: Endpoint = this.initEndpoint(); + if (!this.endpointId) { + payload.endpoint = this.target.endpoint; + payload.username = this.target.username; + payload.password = this.target.password; + payload.insecure = this.target.insecure; + } else { + let changes: { [key: string]: any } = this.getChanges(); + for (let prop of Object.keys(payload)) { + delete payload[prop]; + } + payload.id = this.target.id; + if (!isEmptyObject(changes)) { + let changekeys: { [key: string]: any } = Object.keys(this.getChanges()); changekeys.forEach((key: string) => { - payload[key] = changes[key]; + payload[key] = changes[key]; }); - - if (!this.target.id) { return; } - - this.onGoing = true; - toPromise(this.endpointService - .updateEndpoint(this.target.id, payload)) - .then( - response => { - this.translateService.get('DESTINATION.UPDATED_SUCCESS') - .subscribe(res => this.errorHandler.info(res)); - this.reload.emit(true); - this.close(); - this.onGoing = false; - this.forceRefreshView(2000); - }) - .catch( - error => { - let errorMessageKey = this.handleErrorMessageKey(error.status); - this.translateService - .get(errorMessageKey) - .subscribe(res => { - this.inlineAlert.showInlineError(res); - }); - this.onGoing = false; - this.forceRefreshView(2000); - } - ); - + } } - handleErrorMessageKey(status: number): string { - switch (status) { - case 409: - return 'DESTINATION.CONFLICT_NAME'; - case 400: - return 'DESTINATION.INVALID_NAME'; - default: - return 'UNKNOWN_ERROR'; - } + this.testOngoing = true; + toPromise(this.endpointService.pingEndpoint(payload)) + .then(response => { + this.inlineAlert.showInlineSuccess({ + message: "DESTINATION.TEST_CONNECTION_SUCCESS" + }); + this.forceRefreshView(2000); + this.testOngoing = false; + }) + .catch(error => { + this.inlineAlert.showInlineError("DESTINATION.TEST_CONNECTION_FAILURE"); + this.forceRefreshView(2000); + this.testOngoing = false; + }); + } + + onSubmit() { + if (this.endpointId) { + this.updateEndpoint(); + } else { + this.addEndpoint(); + } + } + + addEndpoint() { + if (this.onGoing) { + return; // Avoid duplicated submitting } - onCancel() { - let changes: {[key: string]: any} = this.getChanges(); - if (!isEmptyObject(changes)) { - this.inlineAlert.showInlineConfirmation({ message: 'ALERT.FORM_CHANGE_CONFIRMATION' }); - }else { - this.close(); - if (this.targetForm) { - this.targetForm.reset(); - } - } - } - - confirmCancel(confirmed: boolean) { - this.inlineAlert.close(); + this.onGoing = true; + toPromise(this.endpointService.createEndpoint(this.target)) + .then(response => { + this.translateService + .get("DESTINATION.CREATED_SUCCESS") + .subscribe(res => this.errorHandler.info(res)); + this.reload.emit(true); + this.onGoing = false; this.close(); + this.forceRefreshView(2000); + }) + .catch(error => { + this.onGoing = false; + let errorMessageKey = this.handleErrorMessageKey(error.status); + this.translateService.get(errorMessageKey).subscribe(res => { + this.inlineAlert.showInlineError(res); + }); + this.forceRefreshView(2000); + }); + } + + updateEndpoint() { + if (this.onGoing) { + return; // Avoid duplicated submitting } - ngAfterViewChecked(): void { - if (this.targetForm != this.currentForm) { - this.targetForm = this.currentForm; - if (this.targetForm) { - this.valueChangesSub = this.targetForm.valueChanges.subscribe((data: { [key: string]: string } | any) => { - if (data) { - //To avoid invalid change publish events - let keyNumber: number = 0; - for (let key in data) { - //Empty string "" is accepted - if (data[key] !== null) { - keyNumber++; - } - } - if (keyNumber !== 5) { - return; - } + let payload: Endpoint = this.initEndpoint(); + for (let prop of Object.keys(payload)) { + delete payload[prop]; + } + let changes: { [key: string]: any } = this.getChanges(); + if (isEmptyObject(changes)) { + return; + } + let changekeys: { [key: string]: any } = Object.keys(changes); - if (!compareValue(this.formValues, data)) { - this.formValues = data; - this.inlineAlert.close(); - } - } - }); + changekeys.forEach((key: string) => { + payload[key] = changes[key]; + }); + + if (!this.target.id) { + return; + } + + this.onGoing = true; + toPromise( + this.endpointService.updateEndpoint(this.target.id, payload) + ) + .then(response => { + this.translateService + .get("DESTINATION.UPDATED_SUCCESS") + .subscribe(res => this.errorHandler.info(res)); + this.reload.emit(true); + this.close(); + this.onGoing = false; + this.forceRefreshView(2000); + }) + .catch(error => { + let errorMessageKey = this.handleErrorMessageKey(error.status); + this.translateService.get(errorMessageKey).subscribe(res => { + this.inlineAlert.showInlineError(res); + }); + this.onGoing = false; + this.forceRefreshView(2000); + }); + } + + handleErrorMessageKey(status: number): string { + switch (status) { + case 409: + return "DESTINATION.CONFLICT_NAME"; + case 400: + return "DESTINATION.INVALID_NAME"; + default: + return "UNKNOWN_ERROR"; + } + } + + onCancel() { + let changes: { [key: string]: any } = this.getChanges(); + if (!isEmptyObject(changes)) { + this.inlineAlert.showInlineConfirmation({ + message: "ALERT.FORM_CHANGE_CONFIRMATION" + }); + } else { + this.close(); + if (this.targetForm) { + this.targetForm.reset(); + } + } + } + + confirmCancel(confirmed: boolean) { + this.inlineAlert.close(); + this.close(); + } + + ngAfterViewChecked(): void { + if (this.targetForm !== this.currentForm) { + this.targetForm = this.currentForm; + if (this.targetForm) { + this.valueChangesSub = this.targetForm.valueChanges.subscribe( + (data: { [key: string]: string } | any) => { + if (data) { + // To avoid invalid change publish events + let keyNumber: number = 0; + for (let key in data) { + // Empty string "" is accepted + if (data[key] !== null) { + keyNumber++; + } + } + if (keyNumber !== 5) { + return; + } + + if (!compareValue(this.formValues, data)) { + this.formValues = data; + this.inlineAlert.close(); + } } - } + } + ); + } } - getChanges(): { [key: string]: any | any[] } { - let changes: { [key: string]: any | any[] } = {}; - if (!this.target || !this.initVal) { - return changes; - } - for (let prop in this.target) { - let field: any = this.initVal[prop]; - if (!compareValue(field, this.target[prop])) { - changes[prop] = this.target[prop]; - //Number - if (typeof field === "number") { - changes[prop] = +changes[prop]; - } - - //Trim string value - if (typeof field === "string") { - changes[prop] = ('' + changes[prop]).trim(); - } - } + } + getChanges(): { [key: string]: any | any[] } { + let changes: { [key: string]: any | any[] } = {}; + if (!this.target || !this.initVal) { + return changes; + } + for (let prop of Object.keys(this.target)) { + let field: any = this.initVal[prop]; + if (!compareValue(field, this.target[prop])) { + changes[prop] = this.target[prop]; + // Number + if (typeof field === "number") { + changes[prop] = +changes[prop]; } - return changes; + // Trim string value + if (typeof field === "string") { + changes[prop] = ("" + changes[prop]).trim(); + } + } } + return changes; + } } diff --git a/src/ui_ng/lib/src/create-edit-endpoint/index.ts b/src/ui_ng/lib/src/create-edit-endpoint/index.ts index be0ec4caa..b30e7c5bc 100644 --- a/src/ui_ng/lib/src/create-edit-endpoint/index.ts +++ b/src/ui_ng/lib/src/create-edit-endpoint/index.ts @@ -4,4 +4,4 @@ import { CreateEditEndpointComponent } from './create-edit-endpoint.component'; export const CREATE_EDIT_ENDPOINT_DIRECTIVES: Type[] = [ CreateEditEndpointComponent -]; \ No newline at end of file +]; diff --git a/src/ui_ng/lib/src/create-edit-label/create-edit-label.component.spec.ts b/src/ui_ng/lib/src/create-edit-label/create-edit-label.component.spec.ts index 2b9e2265e..70996420a 100644 --- a/src/ui_ng/lib/src/create-edit-label/create-edit-label.component.spec.ts +++ b/src/ui_ng/lib/src/create-edit-label/create-edit-label.component.spec.ts @@ -1,85 +1,84 @@ - -import { ComponentFixture, TestBed, async } from '@angular/core/testing'; +import { ComponentFixture, TestBed, async } from "@angular/core/testing"; import { NoopAnimationsModule } from "@angular/platform-browser/animations"; -import { SharedModule } from '../shared/shared.module'; -import { FilterComponent } from '../filter/filter.component'; +import { SharedModule } from "../shared/shared.module"; +import { FilterComponent } from "../filter/filter.component"; +import { InlineAlertComponent } from "../inline-alert/inline-alert.component"; +import { ErrorHandler } from "../error-handler/error-handler"; +import { Label } from "../service/interface"; +import { IServiceConfig, SERVICE_CONFIG } from "../service.config"; +import { CreateEditLabelComponent } from "./create-edit-label.component"; +import { LabelDefaultService, LabelService } from "../service/label.service"; -import { InlineAlertComponent } from '../inline-alert/inline-alert.component'; -import { ErrorHandler } from '../error-handler/error-handler'; -import {Label} from '../service/interface'; -import { IServiceConfig, SERVICE_CONFIG } from '../service.config'; -import {CreateEditLabelComponent} from "./create-edit-label.component"; -import {LabelDefaultService, LabelService} from "../service/label.service"; +describe("CreateEditLabelComponent (inline template)", () => { + let mockOneData: Label = { + color: "#9b0d54", + creation_time: "", + description: "", + id: 1, + name: "label0-g", + project_id: 0, + scope: "g", + update_time: "" + }; -describe('CreateEditLabelComponent (inline template)', () => { + let comp: CreateEditLabelComponent; + let fixture: ComponentFixture; - let mockOneData: Label = { - color: "#9b0d54", - creation_time: "", - description: "", - id: 1, - name: "label0-g", - project_id: 0, - scope: "g", - update_time: "", - } + let config: IServiceConfig = { + systemInfoEndpoint: "/api/label/testing" + }; - let comp: CreateEditLabelComponent; - let fixture: ComponentFixture; + let labelService: LabelService; - let config: IServiceConfig = { - systemInfoEndpoint: '/api/label/testing' - }; + let spy: jasmine.Spy; + let spyOne: jasmine.Spy; - let labelService: LabelService; - - let spy: jasmine.Spy; - let spyOne: jasmine.Spy; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [ - SharedModule, - NoopAnimationsModule - ], - declarations: [ - FilterComponent, - CreateEditLabelComponent, - InlineAlertComponent ], - providers: [ - ErrorHandler, - { provide: SERVICE_CONFIG, useValue: config }, - { provide: LabelService, useClass: LabelDefaultService } - ] - }); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(CreateEditLabelComponent); - comp = fixture.componentInstance; - - labelService = fixture.debugElement.injector.get(LabelService); - - spy = spyOn(labelService, 'getLabels').and.returnValue(Promise.resolve(mockOneData)); - spyOne = spyOn(labelService, 'createLabel').and.returnValue(Promise.resolve(mockOneData)); - - fixture.detectChanges(); - - comp.openModal(); - fixture.detectChanges(); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [SharedModule, NoopAnimationsModule], + declarations: [ + FilterComponent, + CreateEditLabelComponent, + InlineAlertComponent + ], + providers: [ + ErrorHandler, + { provide: SERVICE_CONFIG, useValue: config }, + { provide: LabelService, useClass: LabelDefaultService } + ] }); + })); - it('should be created', () => { - fixture.detectChanges(); - expect(comp).toBeTruthy(); + beforeEach(() => { + fixture = TestBed.createComponent(CreateEditLabelComponent); + comp = fixture.componentInstance; + + labelService = fixture.debugElement.injector.get(LabelService); + + spy = spyOn(labelService, "getLabels").and.returnValue( + Promise.resolve(mockOneData) + ); + spyOne = spyOn(labelService, "createLabel").and.returnValue( + Promise.resolve(mockOneData) + ); + + fixture.detectChanges(); + + comp.openModal(); + fixture.detectChanges(); + }); + + it("should be created", () => { + fixture.detectChanges(); + expect(comp).toBeTruthy(); + }); + + it("should get label and open modal", async(() => { + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(comp.labelModel.name).toEqual(""); }); - - it('should get label and open modal', async(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - expect(comp.labelModel.name).toEqual(''); - }); - })); -}); \ No newline at end of file + })); +}); diff --git a/src/ui_ng/lib/src/create-edit-label/create-edit-label.component.ts b/src/ui_ng/lib/src/create-edit-label/create-edit-label.component.ts index 860a2c389..d9afc2700 100644 --- a/src/ui_ng/lib/src/create-edit-label/create-edit-label.component.ts +++ b/src/ui_ng/lib/src/create-edit-label/create-edit-label.component.ts @@ -12,163 +12,177 @@ // See the License for the specific language governing permissions and // limitations under the License. import { - Component, - Output, - EventEmitter, - OnDestroy, - Input, OnInit, ViewChild, ChangeDetectionStrategy, ChangeDetectorRef -} from '@angular/core'; + Component, + Output, + EventEmitter, + OnDestroy, + Input, + OnInit, + ViewChild, + ChangeDetectionStrategy, + ChangeDetectorRef +} from "@angular/core"; -import {Label} from '../service/interface'; +import { Label } from "../service/interface"; -import {toPromise, clone, compareValue} from '../utils'; +import { toPromise, clone, compareValue } from "../utils"; -import {LabelService} from "../service/label.service"; -import {ErrorHandler} from "../error-handler/error-handler"; -import {NgForm} from "@angular/forms"; -import {Subject} from "rxjs/Subject"; -import {LabelColor} from "../shared/shared.const"; +import { LabelService } from "../service/label.service"; +import { ErrorHandler } from "../error-handler/error-handler"; +import { NgForm } from "@angular/forms"; +import { Subject } from "rxjs/Subject"; +import { LabelColor } from "../shared/shared.const"; @Component({ - selector: 'hbr-create-edit-label', - templateUrl: './create-edit-label.component.html', - styleUrls: ['./create-edit-label.component.scss'], - changeDetection: ChangeDetectionStrategy.Default + selector: "hbr-create-edit-label", + templateUrl: "./create-edit-label.component.html", + styleUrls: ["./create-edit-label.component.scss"], + changeDetection: ChangeDetectionStrategy.Default }) - export class CreateEditLabelComponent implements OnInit, OnDestroy { - formShow: boolean; - inProgress: boolean; - copeLabelModel: Label; - labelModel: Label = this.initLabel(); - labelId = 0; + formShow: boolean; + inProgress: boolean; + copeLabelModel: Label; + labelModel: Label = this.initLabel(); + labelId = 0; - checkOnGoing: boolean; - isLabelNameExist = false; - panelHidden = true; + checkOnGoing: boolean; + isLabelNameExist = false; + panelHidden = true; - nameChecker = new Subject(); + nameChecker = new Subject(); - labelForm: NgForm; - @ViewChild('labelForm') - currentForm: NgForm; + labelForm: NgForm; + @ViewChild("labelForm") currentForm: NgForm; - @Input() projectId: number; - @Input() scope: string; - @Output() reload = new EventEmitter(); + @Input() projectId: number; + @Input() scope: string; + @Output() reload = new EventEmitter(); - constructor( - private labelService: LabelService, - private errorHandler: ErrorHandler, - private ref: ChangeDetectorRef - ) { } + constructor( + private labelService: LabelService, + private errorHandler: ErrorHandler, + private ref: ChangeDetectorRef + ) {} - ngOnInit(): void { - this.nameChecker.debounceTime(500).subscribe((name: string) => { - this.checkOnGoing = true; - let labelName = this.currentForm.controls['name'].value; - toPromise(this.labelService.getLabels(this.scope, this.projectId, labelName)) - .then(targets => { - if (targets && targets.length) { - this.isLabelNameExist = true; - }else { - this.isLabelNameExist = false; - } - this.checkOnGoing = false; - }).catch(error => { - this.checkOnGoing = false; - this.errorHandler.error(error) - }); - setTimeout(() => { - setInterval(() => this.ref.markForCheck(), 100); - }, 3000); + ngOnInit(): void { + this.nameChecker.debounceTime(500).subscribe((name: string) => { + this.checkOnGoing = true; + let labelName = this.currentForm.controls["name"].value; + toPromise( + this.labelService.getLabels(this.scope, this.projectId, labelName) + ) + .then(targets => { + if (targets && targets.length) { + this.isLabelNameExist = true; + } else { + this.isLabelNameExist = false; + } + this.checkOnGoing = false; + }) + .catch(error => { + this.checkOnGoing = false; + this.errorHandler.error(error); + }); + setTimeout(() => { + setInterval(() => this.ref.markForCheck(), 100); + }, 3000); + }); + } + + ngOnDestroy(): void { + this.nameChecker.unsubscribe(); + } + + get labelColor() { + return LabelColor; + } + + initLabel(): Label { + return { + name: "", + description: "", + color: "", + scope: "", + project_id: 0 + }; + } + openModal(): void { + this.labelModel = this.initLabel(); + this.formShow = true; + this.isLabelNameExist = false; + this.labelId = 0; + this.copeLabelModel = null; + } + + editModel(labelId: number, label: Label[]): void { + this.labelModel = clone(label[0]); + this.formShow = true; + this.labelId = labelId; + this.copeLabelModel = clone(label[0]); + } + + openColorPanel(): void { + this.panelHidden = false; + } + closeColorPanel(): void { + this.panelHidden = true; + } + + public get hasChanged(): boolean { + return !compareValue(this.copeLabelModel, this.labelModel); + } + + public get isValid(): boolean { + return !( + this.checkOnGoing || + this.isLabelNameExist || + !(this.currentForm && this.currentForm.valid) || + !this.hasChanged || + this.inProgress + ); + } + + existValid(text: string): void { + if (text) { + this.nameChecker.next(text); + } + } + + onSubmit(): void { + this.inProgress = true; + if (this.labelId <= 0) { + this.labelModel.scope = this.scope; + this.labelModel.project_id = this.projectId; + toPromise