http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/auth-guard.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/auth-guard.ts b/metron-interface/metron-config/src/app/shared/auth-guard.ts new file mode 100644 index 0000000..66c27cf --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/auth-guard.ts @@ -0,0 +1,50 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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 { Injectable } from '@angular/core'; +import { + CanActivate, + Router, + ActivatedRouteSnapshot, + RouterStateSnapshot +} from '@angular/router'; +import { Observable } from 'rxjs/Observable'; +import { AuthenticationService } from '../service/authentication.service'; + +@Injectable() +export class AuthGuard implements CanActivate { + + constructor(private authService: AuthenticationService, private router: Router) {} + + canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) { + if (!this.authService.isAuthenticationChecked()) { + return Observable.create(observer => { + this.authService.onLoginEvent.subscribe(isLoggedIn => { + if (isLoggedIn) { + observer.next(true); + observer.complete(); + } else { + observer.next(false); + observer.complete(); + this.router.navigateByUrl('/login'); + } + }); + }); + } + return this.authService.isAuthenticated(); + } +}
http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/index.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/index.ts b/metron-interface/metron-config/src/app/shared/index.ts new file mode 100644 index 0000000..be1e874 --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/index.ts @@ -0,0 +1,19 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +export * from './metron-dialog-box'; +export * from './metron-modal'; http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/login-guard.spec.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/login-guard.spec.ts b/metron-interface/metron-config/src/app/shared/login-guard.spec.ts new file mode 100644 index 0000000..a49b124 --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/login-guard.spec.ts @@ -0,0 +1,61 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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 {async, inject, TestBed} from '@angular/core/testing'; +import {AuthenticationService} from '../service/authentication.service'; +import {Router} from '@angular/router'; +import {LoginGuard} from './login-guard'; + +class MockAuthenticationService { + public logout(): void {} +} + +class MockRouter { + navigateByUrl(): any {} +} + +describe('LoginGuard', () => { + + beforeEach(async(() => { + TestBed.configureTestingModule({ + providers: [ + LoginGuard, + {provide: AuthenticationService, useClass: MockAuthenticationService}, + {provide: Router, useClass: MockRouter} + ] + }) + .compileComponents(); + + })); + + it('can instantiate auth guard', + inject([LoginGuard], (loginGaurd: LoginGuard) => { + expect(loginGaurd instanceof LoginGuard).toBe(true); + })); + + it('test when login is checked', + inject([LoginGuard, AuthenticationService], (loginGuard: LoginGuard, authenticationService: MockAuthenticationService) => { + + spyOn(authenticationService, 'logout'); + + expect(loginGuard.canActivate(null, null)).toBe(true); + + expect(authenticationService.logout).toHaveBeenCalled(); + + })); + +}); http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/login-guard.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/login-guard.ts b/metron-interface/metron-config/src/app/shared/login-guard.ts new file mode 100644 index 0000000..d8b8f0d --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/login-guard.ts @@ -0,0 +1,40 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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 { Injectable } from '@angular/core'; +import { + CanActivate, + Router, + ActivatedRouteSnapshot, + RouterStateSnapshot +} from '@angular/router'; +import { AuthenticationService } from '../service/authentication.service'; + +// This guard will ensure that logout is called even if you call /login manually +@Injectable() +export class LoginGuard implements CanActivate { + + constructor(private authService: AuthenticationService, private router: Router) {} + + canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) { + + this.authService.logout(); + + return true; + + } +} http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/metron-alerts.spec.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/metron-alerts.spec.ts b/metron-interface/metron-config/src/app/shared/metron-alerts.spec.ts new file mode 100644 index 0000000..5efe063 --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/metron-alerts.spec.ts @@ -0,0 +1,75 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +/* tslint:disable:no-unused-variable */ + +import {MetronAlerts} from './metron-alerts'; + +describe('MetronAlerts', () => { + + beforeEach(function() { + MetronAlerts.SUCESS_MESSAGE_DISPALY_TIME = 500; + }); + + afterEach(function() { + MetronAlerts.SUCESS_MESSAGE_DISPALY_TIME = 5000; + }); + + it('should create an instance', () => { + expect(new MetronAlerts()).toBeTruthy(); + }); + + it('should close success message after timeout', (done) => { + new MetronAlerts().showSuccessMessage('test message'); + + expect($(document).find('.alert.alert-success span').text()).toEqual('test message'); + + setTimeout(() => { + expect($(document).find('.alert .alert-success').length).toEqual(0); + done(); + }, MetronAlerts.SUCESS_MESSAGE_DISPALY_TIME); + }); + + it('should close success message on click of close', (done) => { + new MetronAlerts().showSuccessMessage('test message'); + + expect($(document).find('.alert.alert-success span').text()).toEqual('test message'); + + $(document).find('.alert.alert-success .close').click(); + + expect($(document).find('.alert .alert-success').length).toEqual(0); + + setTimeout(() => { + expect($(document).find('.alert .alert-success').length).toEqual(0); + done(); + }, MetronAlerts.SUCESS_MESSAGE_DISPALY_TIME); + + }); + + // it('should close error message on click of close', () => { + // new MetronAlerts().showErrorMessage('test message'); + // + // expect($(document).find('.alert.alert-danger span').text()).toEqual('test message'); + // + // $(document).find('.alert.alert-danger .close').click(); + // + // expect($(document).find('.alert .alert-danger').length).toEqual(0); + // + // }); + +}); + http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/metron-alerts.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/metron-alerts.ts b/metron-interface/metron-config/src/app/shared/metron-alerts.ts new file mode 100644 index 0000000..5b307e4 --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/metron-alerts.ts @@ -0,0 +1,52 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +export class MetronAlerts { + + public static SUCESS_MESSAGE_DISPALY_TIME = 5000; + + private createMessage(message: string, type: string): Node { + let element = document.createElement('div'); + element.id = 'alert_placeholder'; + element.style.zIndex = '1000'; + element.style.position = 'fixed'; + element.style.display = 'inline-block'; + element.style.minWidth = '250px'; + element.style.cssFloat = 'right'; + element.style.top = '5px'; + element.style.right = '35px'; + + element.innerHTML = '<div id="alertdiv" class="alert ' + type + '"><a class="close" data-dismiss="alert">Ã</a><span>' + + message + '</span></div>'; + document.body.appendChild(element); + + return element; + } + + showErrorMessage(message: string): void { + this.createMessage(message, 'alert-danger'); + } + + showSuccessMessage(message: string): void { + let element = this.createMessage(message, 'alert-success'); + setTimeout(function () { + + document.body.removeChild(element); + + }, MetronAlerts.SUCESS_MESSAGE_DISPALY_TIME); + } +} http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/metron-dialog-box.spec.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/metron-dialog-box.spec.ts b/metron-interface/metron-config/src/app/shared/metron-dialog-box.spec.ts new file mode 100644 index 0000000..3c4acb7 --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/metron-dialog-box.spec.ts @@ -0,0 +1,63 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +/* tslint:disable:no-unused-variable */ + +import {MetronDialogBox} from './metron-dialog-box'; + +describe('MetronDialogBox', () => { + + it('should create an instance', () => { + expect(new MetronDialogBox()).toBeTruthy(); + }); + + it('should return true', () => { + let showConfirmationMessage = new MetronDialogBox().showConfirmationMessage('test message'); + let subscription = showConfirmationMessage.subscribe(result => { + expect(result).toEqual(true); + subscription.unsubscribe(); + }); + spyOn(showConfirmationMessage, 'subscribe'); + + expect($(document).find('.metron-dialog .modal-title').text()).toEqual('Confirmation'); + expect($(document).find('.metron-dialog .modal-body p').text()).toEqual('test message'); + + $(document).find('.metron-dialog .btn-primary').click(); + + $(document).find('.metron-dialog').trigger('hidden.bs.modal'); + + expect($(document).find('.metron-dialog').length).toEqual(0); + + }); + + it('should return false', () => { + let showConfirmationMessage = new MetronDialogBox().showConfirmationMessage('test message'); + let subscription = showConfirmationMessage.subscribe(result => { + expect(result).toEqual(false); + subscription.unsubscribe(); + }); + spyOn(showConfirmationMessage, 'subscribe'); + + $(document).find('.metron-dialog .form-enable-disable-button').click(); + + $(document).find('.metron-dialog').trigger('hidden.bs.modal'); + + expect($(document).find('.metron-dialog').length).toEqual(0); + + }); +}); + http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/metron-dialog-box.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/metron-dialog-box.ts b/metron-interface/metron-config/src/app/shared/metron-dialog-box.ts new file mode 100644 index 0000000..5e0e32b --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/metron-dialog-box.ts @@ -0,0 +1,75 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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 {EventEmitter} from '@angular/core'; + +export class MetronDialogBox { + + private createDialogBox(message: string, title: string) { + + let html = `<div class="metron-dialog modal fade" data-backdrop="static" > + <div class="modal-dialog modal-sm" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"> + <span aria-hidden="true">×</span> + </button> + <span class="modal-title"><b>` + title + `</b></span> + </div> + <div class="modal-body"> + <p>` + message + `</p> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-primary">OK</button> + <button type="button" class="btn form-enable-disable-button" data-dismiss="modal">Cancel</button> + </div> + </div> + </div> + </div>`; + + let element = document.createElement('div'); + element.innerHTML = html; + + document.body.appendChild(element); + + return element; + } + + public showConfirmationMessage(message: string): EventEmitter<boolean> { + let eventEmitter = new EventEmitter<boolean>(); + let element = this.createDialogBox(message, 'Confirmation'); + + $(element).find('.metron-dialog').modal('show'); + + $(element).find('.btn-primary').on('click', function (e) { + $(element).find('.metron-dialog').modal('hide'); + eventEmitter.emit(true); + }); + + $(element).find('.form-enable-disable-button').on('click', function (e) { + $(element).find('.metron-dialog').modal('hide'); + eventEmitter.emit(false); + }); + + $(element).find('.metron-dialog').on('hidden.bs.modal', function (e) { + $(element).remove(); + }); + + return eventEmitter; + + } +} http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/metron-modal/index.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/metron-modal/index.ts b/metron-interface/metron-config/src/app/shared/metron-modal/index.ts new file mode 100644 index 0000000..ec19caf --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/metron-modal/index.ts @@ -0,0 +1 @@ +export * from './metron-modal.component'; http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/metron-modal/metron-modal.component.html ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/metron-modal/metron-modal.component.html b/metron-interface/metron-config/src/app/shared/metron-modal/metron-modal.component.html new file mode 100644 index 0000000..3a0b18e --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/metron-modal/metron-modal.component.html @@ -0,0 +1,20 @@ +<!-- + Licensed to the Apache Software + Foundation (ASF) under one or more contributor license agreements. See the + NOTICE file distributed with this work for additional information regarding + copyright ownership. The ASF licenses this file to You under the Apache License, + Version 2.0 (the "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software distributed + under the License is distributed on an "AS IS" BASIS, 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. + --> +<div [ngClass]="{'metron-modal': backgroundMasked, 'metron-modal-clickable': !backgroundMasked}" data-backdrop="static" data-keyboard="false"> + <div class="dialog-pane"> + <ng-content></ng-content> + </div> +</div> http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/metron-modal/metron-modal.component.scss ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/metron-modal/metron-modal.component.scss b/metron-interface/metron-config/src/app/shared/metron-modal/metron-modal.component.scss new file mode 100644 index 0000000..b47468f --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/metron-modal/metron-modal.component.scss @@ -0,0 +1,45 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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 "../../../styles.scss"; + +.metron-modal { + position: fixed; + z-index: 1; + left: 0; + top: 0; + width: 100%; + height: 100%; + background-color: rgb(0,0,0); + background-color: rgba(0,0,0,0.4); + overflow-x: hidden; + overflow-y: auto; +} + +.metron-modal-clickable { + position: fixed; + z-index: 1; + right: 0; + top: 0; + height: 100%; + padding-left: 15px; + overflow-x: hidden; + overflow-y: auto; +} +.dialog-pane { + @extend .flexbox-row-reverse; +} http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/metron-modal/metron-modal.component.spec.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/metron-modal/metron-modal.component.spec.ts b/metron-interface/metron-config/src/app/shared/metron-modal/metron-modal.component.spec.ts new file mode 100644 index 0000000..74f6c1e --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/metron-modal/metron-modal.component.spec.ts @@ -0,0 +1,43 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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 {async, TestBed, ComponentFixture} from '@angular/core/testing'; +import {SharedModule} from '../shared.module'; +import { MetronModalComponent } from './metron-modal.component'; + +describe('MetronModalComponent', () => { + + let fixture: ComponentFixture<MetronModalComponent>; + let component: MetronModalComponent; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [SharedModule], + providers: [ + MetronModalComponent + ] + }); + + fixture = TestBed.createComponent(MetronModalComponent); + component = fixture.componentInstance; + + })); + + it('can instantiate MetronModalComponent', async(() => { + expect(component instanceof MetronModalComponent).toBe(true); + })); +}); http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/metron-modal/metron-modal.component.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/metron-modal/metron-modal.component.ts b/metron-interface/metron-config/src/app/shared/metron-modal/metron-modal.component.ts new file mode 100644 index 0000000..22a95d6 --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/metron-modal/metron-modal.component.ts @@ -0,0 +1,27 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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 { Component, Input } from '@angular/core'; + +@Component({ + selector: 'metron-config-metron-modal', + templateUrl: 'metron-modal.component.html', + styleUrls: ['metron-modal.component.scss'] +}) +export class MetronModalComponent { + @Input() backgroundMasked = true; +} http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/metron-table/metron-sorter/index.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/metron-table/metron-sorter/index.ts b/metron-interface/metron-config/src/app/shared/metron-table/metron-sorter/index.ts new file mode 100644 index 0000000..325568a --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/metron-table/metron-sorter/index.ts @@ -0,0 +1 @@ +export * from './metron-sorter.component'; http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/metron-table/metron-sorter/metron-sorter.component.html ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/metron-table/metron-sorter/metron-sorter.component.html b/metron-interface/metron-config/src/app/shared/metron-table/metron-sorter/metron-sorter.component.html new file mode 100644 index 0000000..988bec1 --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/metron-table/metron-sorter/metron-sorter.component.html @@ -0,0 +1,21 @@ +<!-- + Licensed to the Apache Software + Foundation (ASF) under one or more contributor license agreements. See the + NOTICE file distributed with this work for additional information regarding + copyright ownership. The ASF licenses this file to You under the Apache License, + Version 2.0 (the "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software distributed + under the License is distributed on an "AS IS" BASIS, 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. + --> +<a style="cursor: pointer" class="text-nowrap" (click)="sort()"> + <ng-content></ng-content> + <i class="fa fa-sort" aria-hidden="true" *ngIf="!sortAsc && !sortDesc"></i> + <i class="fa fa-sort-asc" aria-hidden="true" *ngIf="sortAsc"></i> + <i class="fa fa-sort-desc" aria-hidden="true" *ngIf="sortDesc"></i> +</a> http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/metron-table/metron-sorter/metron-sorter.component.scss ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/metron-table/metron-sorter/metron-sorter.component.scss b/metron-interface/metron-config/src/app/shared/metron-table/metron-sorter/metron-sorter.component.scss new file mode 100644 index 0000000..5d5f1e3 --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/metron-table/metron-sorter/metron-sorter.component.scss @@ -0,0 +1,17 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/metron-table/metron-sorter/metron-sorter.component.spec.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/metron-table/metron-sorter/metron-sorter.component.spec.ts b/metron-interface/metron-config/src/app/shared/metron-table/metron-sorter/metron-sorter.component.spec.ts new file mode 100644 index 0000000..cac8667 --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/metron-table/metron-sorter/metron-sorter.component.spec.ts @@ -0,0 +1,75 @@ +/* tslint:disable:no-unused-variable */ +// directiveSelectorNameRule + +import {MetronSorterComponent} from './metron-sorter.component'; +import {MetronTableDirective} from '../metron-table.directive'; + +describe('Component: MetronSorter', () => { + + it('should create an instance', () => { + let metronTable = new MetronTableDirective(); + let component = new MetronSorterComponent(metronTable); + expect(component).toBeTruthy(); + }); + + it('should set the variables according to sorter', () => { + let metronTable = new MetronTableDirective(); + let sorter1 = new MetronSorterComponent(metronTable); + let sorter2 = new MetronSorterComponent(metronTable); + let sorter3 = new MetronSorterComponent(metronTable); + + sorter1.sortBy = 'col1'; + sorter2.sortBy = 'col2'; + sorter3.sortBy = 'col3'; + + sorter1.sort(); + expect(sorter1.sortAsc).toEqual(true); + expect(sorter1.sortDesc).toEqual(false); + expect(sorter2.sortAsc).toEqual(false); + expect(sorter2.sortDesc).toEqual(false); + expect(sorter3.sortAsc).toEqual(false); + expect(sorter3.sortDesc).toEqual(false); + + sorter1.sort(); + expect(sorter1.sortAsc).toEqual(false); + expect(sorter1.sortDesc).toEqual(true); + expect(sorter2.sortAsc).toEqual(false); + expect(sorter2.sortDesc).toEqual(false); + expect(sorter3.sortAsc).toEqual(false); + expect(sorter3.sortDesc).toEqual(false); + + sorter2.sort(); + expect(sorter1.sortAsc).toEqual(false); + expect(sorter1.sortDesc).toEqual(false); + expect(sorter2.sortAsc).toEqual(true); + expect(sorter2.sortDesc).toEqual(false); + expect(sorter3.sortAsc).toEqual(false); + expect(sorter3.sortDesc).toEqual(false); + + sorter2.sort(); + expect(sorter1.sortAsc).toEqual(false); + expect(sorter1.sortDesc).toEqual(false); + expect(sorter2.sortAsc).toEqual(false); + expect(sorter2.sortDesc).toEqual(true); + expect(sorter3.sortAsc).toEqual(false); + expect(sorter3.sortDesc).toEqual(false); + + sorter3.sort(); + expect(sorter1.sortAsc).toEqual(false); + expect(sorter1.sortDesc).toEqual(false); + expect(sorter2.sortAsc).toEqual(false); + expect(sorter2.sortDesc).toEqual(false); + expect(sorter3.sortAsc).toEqual(true); + expect(sorter3.sortDesc).toEqual(false); + + sorter3.sort(); + expect(sorter1.sortAsc).toEqual(false); + expect(sorter1.sortDesc).toEqual(false); + expect(sorter2.sortAsc).toEqual(false); + expect(sorter2.sortDesc).toEqual(false); + expect(sorter3.sortAsc).toEqual(false); + expect(sorter3.sortDesc).toEqual(true); + + }); + +}); http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/metron-table/metron-sorter/metron-sorter.component.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/metron-table/metron-sorter/metron-sorter.component.ts b/metron-interface/metron-config/src/app/shared/metron-table/metron-sorter/metron-sorter.component.ts new file mode 100644 index 0000000..11ada7d --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/metron-table/metron-sorter/metron-sorter.component.ts @@ -0,0 +1,28 @@ +import { Component, Input } from '@angular/core'; +import {Sort} from '../../../util/enums'; +import {MetronTableDirective, SortEvent} from '../metron-table.directive'; + +@Component({ + selector: 'metron-config-sorter', + templateUrl: './metron-sorter.component.html', + styleUrls: ['./metron-sorter.component.scss'] +}) +export class MetronSorterComponent { + + @Input() sortBy: string; + + sortAsc: boolean = false; + sortDesc: boolean = false; + + constructor(private metronTable: MetronTableDirective ) { + this.metronTable.onSortColumnChange.subscribe((event: SortEvent) => { + this.sortAsc = (event.sortBy === this.sortBy && event.sortOrder === Sort.ASC); + this.sortDesc = (event.sortBy === this.sortBy && event.sortOrder === Sort.DSC); + }); + } + + sort() { + let order = this.sortAsc ? Sort.DSC : Sort.ASC; + this.metronTable.setSort({sortBy: this.sortBy, sortOrder: order}); + } +} http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/metron-table/metron-table.directive.spec.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/metron-table/metron-table.directive.spec.ts b/metron-interface/metron-config/src/app/shared/metron-table/metron-table.directive.spec.ts new file mode 100644 index 0000000..b469d46 --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/metron-table/metron-table.directive.spec.ts @@ -0,0 +1,52 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +/* tslint:disable:no-unused-variable */ + +import {Sort} from '../../util/enums'; +import {MetronTableDirective, SortEvent} from './metron-table.directive'; + +describe('Directive: MetronTable', () => { + + it('should create an instance', () => { + let directive = new MetronTableDirective(); + expect(directive).toBeTruthy(); + }); + + it('should emmit listeners ', () => { + let eventToTest: SortEvent = null; + let directive = new MetronTableDirective(); + + let event1 = { sortBy: 'col1', sortOrder: Sort.ASC }; + let event2 = { sortBy: 'col2', sortOrder: Sort.DSC }; + + directive.onSort.subscribe((sortEvent: SortEvent) => { + expect(sortEvent).toEqual(eventToTest); + }); + directive.onSortColumnChange.subscribe((sortEvent: SortEvent) => { + expect(sortEvent).toEqual(eventToTest); + }); + + eventToTest = event1; + directive.setSort(eventToTest); + + eventToTest = event2; + directive.setSort(eventToTest); + + }); + +}); http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/metron-table/metron-table.directive.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/metron-table/metron-table.directive.ts b/metron-interface/metron-config/src/app/shared/metron-table/metron-table.directive.ts new file mode 100644 index 0000000..682fecc --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/metron-table/metron-table.directive.ts @@ -0,0 +1,42 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +/* tslint:disable:directive-selector-name */ +import {Directive, Output, EventEmitter} from '@angular/core'; +import {Sort} from '../../util/enums'; + +export interface SortEvent { + sortBy: string; + sortOrder: Sort; +} + +@Directive({ + selector: '[metron-config-table]' +}) + +export class MetronTableDirective { + + @Output() onSort = new EventEmitter<SortEvent>(); + + onSortColumnChange = new EventEmitter<SortEvent>(); + + public setSort(sortEvent: SortEvent): void { + this.onSortColumnChange.emit(sortEvent); + this.onSort.emit(sortEvent); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/metron-table/metron-table.module.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/metron-table/metron-table.module.ts b/metron-interface/metron-config/src/app/shared/metron-table/metron-table.module.ts new file mode 100644 index 0000000..57369df --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/metron-table/metron-table.module.ts @@ -0,0 +1,14 @@ +import {NgModule} from '@angular/core'; + +import {MetronSorterComponent} from './metron-sorter/metron-sorter.component'; +import {MetronTableDirective} from './metron-table.directive'; +import {SharedModule} from '../shared.module'; + +@NgModule({ + imports: [ SharedModule ], + exports: [ MetronSorterComponent, MetronTableDirective ], + declarations: [ MetronSorterComponent, MetronTableDirective ], + providers: [], +}) +export class MetronTableModule { +} http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/multiple-input/index.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/multiple-input/index.ts b/metron-interface/metron-config/src/app/shared/multiple-input/index.ts new file mode 100644 index 0000000..3697be3 --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/multiple-input/index.ts @@ -0,0 +1 @@ +export * from './multiple-input.component'; http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/multiple-input/multiple-input.component.html ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/multiple-input/multiple-input.component.html b/metron-interface/metron-config/src/app/shared/multiple-input/multiple-input.component.html new file mode 100644 index 0000000..f070dd7 --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/multiple-input/multiple-input.component.html @@ -0,0 +1,39 @@ +<!-- + Licensed to the Apache Software + Foundation (ASF) under one or more contributor license agreements. See the + NOTICE file distributed with this work for additional information regarding + copyright ownership. The ASF licenses this file to You under the Apache License, + Version 2.0 (the "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software distributed + under the License is distributed on an "AS IS" BASIS, 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. + --> +<!--Configured--> +<div *ngFor="let configuredItem of configuredItems; let i = index" class="row mx-0"> + <div class="col-md-10 px-0"> + <input *ngIf="type==='text'" class="form-control disabled" readonly [ngModel]="configuredItem.name"> + <select *ngIf="type==='select'" #select class="form-control" [ngModel]="configuredItem.name" (change)="onUpdate(configuredItem,select.value)"> + <option *ngFor="let availableFunction of getAvailableFunctions()" [disabled]="availableFunction===''" [selected]="availableFunction===''"> {{ availableFunction.name }} </option> + </select> + </div> + <div class="col-md-2 px-0"> + <i class="fa fa-minus fa-border icon-button" aria-hidden="true" style="margin-left: 0.3rem;" (click)="onRemove(configuredItem)"></i> + </div> +</div> + +<!--new--> +<div class="row mx-0" *ngIf="(this.configuredItems.length !== this.availableItems.length) || configuredItems.length === 0 "> + <div class="col-md-10 px-0"> + <select #select class="form-control" (change)="onAdd(select)"> + <option [disabled]="true" [selected]="true"></option> + <option *ngFor="let availableFunction of getAvailableFunctions()"> {{ availableFunction.name }} </option> + </select> + </div> + <div class="col-md-3 px-0"> </div> +</div> + http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/multiple-input/multiple-input.component.scss ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/multiple-input/multiple-input.component.scss b/metron-interface/metron-config/src/app/shared/multiple-input/multiple-input.component.scss new file mode 100644 index 0000000..611a44a --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/multiple-input/multiple-input.component.scss @@ -0,0 +1,21 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +.form-control +{ + margin-bottom: 4px; +} http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/multiple-input/multiple-input.component.spec.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/multiple-input/multiple-input.component.spec.ts b/metron-interface/metron-config/src/app/shared/multiple-input/multiple-input.component.spec.ts new file mode 100644 index 0000000..0bf9b76 --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/multiple-input/multiple-input.component.spec.ts @@ -0,0 +1,147 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +/* tslint:disable:no-unused-variable */ + +import {async, TestBed, ComponentFixture} from '@angular/core/testing'; +import { MultipleInputComponent } from './multiple-input.component'; +import {SharedModule} from '../shared.module'; +import {AutocompleteOption} from '../../model/autocomplete-option'; + +describe('Component: MultipleInput', () => { + + let fixture: ComponentFixture<MultipleInputComponent>; + let component: MultipleInputComponent; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [SharedModule], + declarations: [ MultipleInputComponent ], + providers: [ + MultipleInputComponent + ] + }); + + fixture = TestBed.createComponent(MultipleInputComponent); + component = fixture.componentInstance; + + })); + + it('should create an instance', () => { + expect(component).toBeDefined(); + }); + + it('should get AvailableFunctions', () => { + let availableItems: AutocompleteOption[] = []; + availableItems.push(new AutocompleteOption('option1')); + availableItems.push(new AutocompleteOption('option2')); + availableItems.push(new AutocompleteOption('option3')); + availableItems.push(new AutocompleteOption('option4')); + + let configuredItems: AutocompleteOption[] = []; + configuredItems.push(new AutocompleteOption('option1')); + configuredItems.push(new AutocompleteOption('option3')); + + component.allowDuplicates = false; + + component.availableItems = availableItems; + expect(component.getAvailableFunctions()).toEqual(availableItems); + + component.configuredItems = configuredItems; + expect(component.getAvailableFunctions()).toEqual([new AutocompleteOption('option2'), new AutocompleteOption('option4')]); + + component.allowDuplicates = true; + expect(component.getAvailableFunctions()).toEqual(availableItems); + + fixture.destroy(); + }); + + it('should get item by name', () => { + let availableItems: AutocompleteOption[] = []; + availableItems.push(new AutocompleteOption('option1')); + availableItems.push(new AutocompleteOption('option2')); + availableItems.push(new AutocompleteOption('option3')); + + component.availableItems = availableItems; + expect(component.getAvailableItemByName('option1')).toEqual(new AutocompleteOption('option1')); + expect(component.getAvailableItemByName('option4')).toEqual(new AutocompleteOption()); + + fixture.destroy(); + }); + + it('should add', () => { + spyOn(component.onConfigChange, 'emit'); + + let availableItems: AutocompleteOption[] = []; + availableItems.push(new AutocompleteOption('option1')); + availableItems.push(new AutocompleteOption('option2')); + availableItems.push(new AutocompleteOption('option3')); + + let select = {'value': 'option1'}; + component.availableItems = availableItems; + component.onAdd(select); + expect(component.configuredItems.length).toEqual(1); + expect(component.configuredItems[0].name).toEqual('option1'); + expect(component.showAddNew).toEqual(false); + expect(component.onConfigChange.emit).toHaveBeenCalled(); + expect(select.value).toEqual(''); + + fixture.destroy(); + }); + + it('should remove', () => { + spyOn(component.onConfigChange, 'emit'); + + let configuredItems: AutocompleteOption[] = []; + configuredItems.push(new AutocompleteOption('option1')); + configuredItems.push(new AutocompleteOption('option2')); + configuredItems.push(new AutocompleteOption('option3')); + + component.configuredItems = configuredItems; + component.onRemove(new AutocompleteOption('option1')); + expect(component.configuredItems.length).toEqual(2); + expect(component.onConfigChange.emit).toHaveBeenCalled(); + + fixture.destroy(); + }); + + it('should update', () => { + spyOn(component.onConfigChange, 'emit'); + + let availableItems: AutocompleteOption[] = []; + availableItems.push(new AutocompleteOption('option1')); + availableItems.push(new AutocompleteOption('option2')); + availableItems.push(new AutocompleteOption('option3')); + availableItems.push(new AutocompleteOption('option4')); + + let configuredItems: AutocompleteOption[] = []; + let option1 = new AutocompleteOption('option1'); + configuredItems.push(option1); + configuredItems.push(new AutocompleteOption('option3')); + + component.availableItems = availableItems; + component.configuredItems = configuredItems; + + component.onUpdate(option1, 'option4'); + expect(component.configuredItems.length).toEqual(2); + expect(component.configuredItems[0].name).toEqual('option4'); + expect(component.onConfigChange.emit).toHaveBeenCalled(); + + fixture.destroy(); + }); + +}); http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/multiple-input/multiple-input.component.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/multiple-input/multiple-input.component.ts b/metron-interface/metron-config/src/app/shared/multiple-input/multiple-input.component.ts new file mode 100644 index 0000000..eb76f40 --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/multiple-input/multiple-input.component.ts @@ -0,0 +1,83 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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 { Component, Input, Output, EventEmitter } from '@angular/core'; +import {AutocompleteOption} from '../../model/autocomplete-option'; + +@Component({ + selector: 'metron-config-multiple-input', + templateUrl: './multiple-input.component.html', + styleUrls: ['./multiple-input.component.scss'] +}) +export class MultipleInputComponent { + + @Input() type: string = 'text'; + @Input() allowDuplicates: boolean = true; + @Input() configuredItems: AutocompleteOption[] = []; + @Input() availableItems: AutocompleteOption[] = []; + + @Output() onConfigChange: EventEmitter<void> = new EventEmitter<void>(); + + showAddNew: boolean = false; + + constructor() { } + + getAvailableFunctions(): AutocompleteOption[] { + if (this.allowDuplicates) { + return this.availableItems; + } + + let tAvailable: AutocompleteOption[] = []; + let configuredFunctionNames: string[] = []; + for (let item of this.configuredItems) { + configuredFunctionNames.push(item.name); + } + for (let item of this.availableItems) { + if (configuredFunctionNames.indexOf(item.name) === -1) { + tAvailable.push(item); + } + } + + return tAvailable; + } + + getAvailableItemByName(name: string): AutocompleteOption { + for (let item of this.availableItems) { + if (name === item.name) { + return item; + } + } + + return new AutocompleteOption(); + } + + onAdd(select: any) { + this.configuredItems.push(this.getAvailableItemByName(select.value)); + select.value = ''; + this.onConfigChange.emit(); + } + + onRemove(configuredItem: AutocompleteOption) { + this.configuredItems.splice(this.configuredItems.indexOf(configuredItem), 1); + this.onConfigChange.emit(); + } + + onUpdate(configuredItem: AutocompleteOption, value: string) { + this.configuredItems.splice(this.configuredItems.indexOf(configuredItem), 1, this.getAvailableItemByName(value)); + this.onConfigChange.emit(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/multiple-input/multiple-input.module.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/multiple-input/multiple-input.module.ts b/metron-interface/metron-config/src/app/shared/multiple-input/multiple-input.module.ts new file mode 100644 index 0000000..39e0290 --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/multiple-input/multiple-input.module.ts @@ -0,0 +1,13 @@ +import {NgModule} from '@angular/core'; + +import {MultipleInputComponent} from './multiple-input.component'; +import {SharedModule} from '../shared.module'; + +@NgModule({ + imports: [ SharedModule ], + exports: [ MultipleInputComponent ], + declarations: [ MultipleInputComponent ], + providers: [], +}) +export class MultipleInputModule { +} http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/number-spinner/index.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/number-spinner/index.ts b/metron-interface/metron-config/src/app/shared/number-spinner/index.ts new file mode 100644 index 0000000..b37c764 --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/number-spinner/index.ts @@ -0,0 +1 @@ +export * from './number-spinner.component'; http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/number-spinner/number-spinner.component.html ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/number-spinner/number-spinner.component.html b/metron-interface/metron-config/src/app/shared/number-spinner/number-spinner.component.html new file mode 100644 index 0000000..b63908f --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/number-spinner/number-spinner.component.html @@ -0,0 +1,22 @@ +<!-- + Licensed to the Apache Software + Foundation (ASF) under one or more contributor license agreements. See the + NOTICE file distributed with this work for additional information regarding + copyright ownership. The ASF licenses this file to You under the Apache License, + Version 2.0 (the "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software distributed + under the License is distributed on an "AS IS" BASIS, 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. + --> +<div class="input-group spinner"> + <input type="text" class="form-control" [(ngModel)]="value"> + <div class="input-group-btn-vertical"> + <button class="btn btn-default" type="button" (click)="value=value+1" [disabled]="value >= max"><i class="fa fa-caret-up"></i></button> + <button class="btn btn-default" type="button" (click)="value=value-1" [disabled]="value <= min"><i class="fa fa-caret-down"></i></button> + </div> +</div> http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/number-spinner/number-spinner.component.scss ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/number-spinner/number-spinner.component.scss b/metron-interface/metron-config/src/app/shared/number-spinner/number-spinner.component.scss new file mode 100644 index 0000000..b4352c4 --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/number-spinner/number-spinner.component.scss @@ -0,0 +1,55 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +.input-group-btn-vertical +{ + width: 2%; + position: relative; + white-space: nowrap; + vertical-align: middle; + display: table-cell; +} + +.input-group-btn-vertical > .btn +{ + display: block; + float: none; + width: 100%; + max-width: 100%; + padding: 8px; + margin-left: -1px; + position: relative; + border-radius: 0; +} + +.input-group-btn-vertical > .btn:first-child +{ + border-top-right-radius: 0.25em; +} + +.input-group-btn-vertical > .btn:last-child +{ + margin-top: -1px; + border-bottom-right-radius: 0.25em; +} + +.input-group-btn-vertical i +{ + position: absolute; + top: 0; + left: 4px; +} http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/number-spinner/number-spinner.component.spec.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/number-spinner/number-spinner.component.spec.ts b/metron-interface/metron-config/src/app/shared/number-spinner/number-spinner.component.spec.ts new file mode 100644 index 0000000..ca3042d --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/number-spinner/number-spinner.component.spec.ts @@ -0,0 +1,46 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +/* tslint:disable:no-unused-variable */ + +import {NumberSpinnerComponent} from './number-spinner.component'; + +describe('NumberSpinnerComponent', () => { + + it('should create an instance', () => { + expect(new NumberSpinnerComponent()).toBeTruthy(); + }); + + it('spec for all inherited functions', () => { + let numberSpinnerComponent = new NumberSpinnerComponent(); + + numberSpinnerComponent.writeValue(10); + expect(numberSpinnerComponent.innerValue).toEqual(10); + expect(numberSpinnerComponent.value).toEqual(10); + + numberSpinnerComponent.registerOnChange((_: any) => {}); + numberSpinnerComponent.value = 11; + expect(numberSpinnerComponent.innerValue).toEqual(11); + expect(numberSpinnerComponent.value).toEqual(11); + + numberSpinnerComponent.value = 'abc'; + expect(numberSpinnerComponent.innerValue).toEqual(11); + expect(numberSpinnerComponent.value).toEqual(11); + + }); + +}); http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/number-spinner/number-spinner.component.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/number-spinner/number-spinner.component.ts b/metron-interface/metron-config/src/app/shared/number-spinner/number-spinner.component.ts new file mode 100644 index 0000000..1fd1521 --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/number-spinner/number-spinner.component.ts @@ -0,0 +1,70 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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 { Component, Input, forwardRef } from '@angular/core'; +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; + +@Component({ + selector: 'metron-config-number-spinner', + templateUrl: './number-spinner.component.html', + styleUrls: ['./number-spinner.component.scss'], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => NumberSpinnerComponent), + multi: true + } + ] +}) +export class NumberSpinnerComponent implements ControlValueAccessor { + + @Input() min: number; + @Input() max: number; + + innerValue: number = 0; + + private onTouchedCallback ; + private onChangeCallback ; + + writeValue(val: any) { + this.innerValue = val; + } + + registerOnChange(fn: any) { + this.onChangeCallback = fn; + } + + registerOnTouched(fn: any) { + this.onTouchedCallback = fn; + } + + get value(): any { + if (typeof this.innerValue === 'string') { + this.innerValue = parseInt(this.innerValue, 10); + } + return this.innerValue; + }; + + set value(v: any) { + v = Number(v); + if (!isNaN(v) && v !== this.innerValue) { + this.innerValue = v; + this.onChangeCallback(v); + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/number-spinner/number-spinner.module.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/number-spinner/number-spinner.module.ts b/metron-interface/metron-config/src/app/shared/number-spinner/number-spinner.module.ts new file mode 100644 index 0000000..db622b6 --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/number-spinner/number-spinner.module.ts @@ -0,0 +1,13 @@ +import {NgModule} from '@angular/core'; + +import {NumberSpinnerComponent} from './number-spinner.component'; +import {SharedModule} from '../shared.module'; + +@NgModule({ + imports: [ SharedModule ], + exports: [ NumberSpinnerComponent ], + declarations: [ NumberSpinnerComponent ], + providers: [], +}) +export class NumberSpinnerModule { +} http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/sample-data/sample-data.component.html ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/sample-data/sample-data.component.html b/metron-interface/metron-config/src/app/shared/sample-data/sample-data.component.html new file mode 100644 index 0000000..887211c --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/sample-data/sample-data.component.html @@ -0,0 +1,22 @@ +<!-- + Licensed to the Apache Software + Foundation (ASF) under one or more contributor license agreements. See the + NOTICE file distributed with this work for additional information regarding + copyright ownership. The ASF licenses this file to You under the Apache License, + Version 2.0 (the "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software distributed + under the License is distributed on an "AS IS" BASIS, 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. + --> +<label attr.for="sampleData">SAMPLE ( {{sampleDataIndex + 1}} of {{sampleData.length}} )</label> +<div> + <i class="fa fa-caret-left sample-iterator sample-unavailable" aria-hidden="true" [class.sample-available]="sampleDataIndex > 0" [class.sample-unavailable]="sampleDataIndex < 1" (click)="getPreviousSample()"></i> + <textarea #sampleDataElement type="text" class="form-control sample-input" name="sampleData" [ngModel]="sampleData[sampleDataIndex]" (blur)="onBlur(sample)" + [attr.placeholder]="placeHolderText" (focus)="sampleDataElement.placeholder=''"> </textarea> + <i class="fa fa-caret-right sample-iterator sample-available" aria-hidden="true" (click)="getNextSample()"></i> +</div> http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/sample-data/sample-data.component.scss ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/sample-data/sample-data.component.scss b/metron-interface/metron-config/src/app/shared/sample-data/sample-data.component.scss new file mode 100644 index 0000000..918e468 --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/sample-data/sample-data.component.scss @@ -0,0 +1,66 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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 "../../_variables.scss"; + +.sample-input { + height:60px; + display:inline-block; + width: 94%; + resize: none; + margin-right: -4px; + margin-left: -4px; + border-radius: inherit; +} + +.sample-iterator { + background-color:#195d68; + vertical-align: top; + width: 3%; + height: 60px; + padding-top: 22px; + padding-left: 6px; + cursor: pointer; +} + +.sample-available { + color: #27aae1; +} + +.sample-unavailable { + color: #404040; +} + + +textarea { + &::-webkit-input-placeholder { + @include place-holder-text; + } + &:-moz-placeholder { + @include place-holder-text; + } + + &::-moz-placeholder { + @include place-holder-text; + } + + &:-ms-input-placeholder { + @include place-holder-text; + } +} + + http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/sample-data/sample-data.component.spec.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/sample-data/sample-data.component.spec.ts b/metron-interface/metron-config/src/app/shared/sample-data/sample-data.component.spec.ts new file mode 100644 index 0000000..5488209 --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/sample-data/sample-data.component.spec.ts @@ -0,0 +1,188 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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 {async, TestBed, ComponentFixture} from '@angular/core/testing'; +import {KafkaService} from '../../service/kafka.service'; +import {Observable} from 'rxjs/Observable'; +import {SampleDataComponent} from './sample-data.component'; +import {SharedModule} from '../shared.module'; +import '../../rxjs-operators'; + +class MockKafkaService { + _sample: string[]; + _sampleCounter: number = 0; + + + public setSample(sampleMessages: string[]): void { + this._sample = sampleMessages; + this._sampleCounter = 0; + } + + public sample(name: string): Observable<string> { + + if (this._sampleCounter < this._sample.length) { + return Observable.create(observer => { + observer.next(this._sample[this._sampleCounter++]); + observer.complete(); + }); + } + + return Observable.throw('Error'); + } +} + +describe('SampleDataComponent', () => { + let fixture: ComponentFixture<SampleDataComponent>; + let sampleDataComponent: SampleDataComponent; + let kafkaService: MockKafkaService; + let sampleMessages: string[] = [ + 'This is first message', + 'This is second message', + 'This is third message' + ]; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [SharedModule], + declarations: [ SampleDataComponent], + providers: [ + SampleDataComponent, + {provide: KafkaService, useClass: MockKafkaService} + ] + }); + + fixture = TestBed.createComponent(SampleDataComponent); + sampleDataComponent = fixture.componentInstance; + kafkaService = fixture.debugElement.injector.get(KafkaService); + + })); + + it('can instantiate SampleDataComponent', async(() => { + expect(sampleDataComponent instanceof SampleDataComponent).toBe(true); + })); + + + it('should emmit messages', async(() => { + let expectedMessage; + let successCount = 0; + let failureCount = 0; + + kafkaService.setSample(sampleMessages); + + sampleDataComponent.onSampleDataChanged.subscribe((message: string) => { + ++successCount; + expect(message).toEqual(expectedMessage); + }); + + sampleDataComponent.onSampleDataNotAvailable.subscribe(() => { + ++failureCount; + }); + + spyOn(sampleDataComponent.onSampleDataNotAvailable, 'subscribe'); + spyOn(sampleDataComponent.onSampleDataChanged, 'subscribe'); + + expectedMessage = sampleMessages[0]; + sampleDataComponent.getNextSample(); + expect(successCount).toEqual(1); + expect(failureCount).toEqual(0); + + expectedMessage = sampleMessages[1]; + sampleDataComponent.getNextSample(); + expect(successCount).toEqual(2); + expect(failureCount).toEqual(0); + + expectedMessage = sampleMessages[2]; + sampleDataComponent.getNextSample(); + expect(successCount).toEqual(3); + expect(failureCount).toEqual(0); + + let tmp; + expectedMessage = tmp; + sampleDataComponent.getNextSample(); + expect(successCount).toEqual(3); + expect(failureCount).toEqual(1); + + expectedMessage = sampleMessages[1]; + sampleDataComponent.getPreviousSample(); + expect(successCount).toEqual(4); + expect(failureCount).toEqual(1); + + expectedMessage = sampleMessages[0]; + sampleDataComponent.getPreviousSample(); + expect(successCount).toEqual(5); + expect(failureCount).toEqual(1); + + expectedMessage = sampleMessages[1]; + sampleDataComponent.getNextSample(); + expect(successCount).toEqual(6); + expect(failureCount).toEqual(1); + + expectedMessage = sampleMessages[0]; + sampleDataComponent.getPreviousSample(); + expect(successCount).toEqual(7); + expect(failureCount).toEqual(1); + + expectedMessage = tmp; + sampleDataComponent.getPreviousSample(); + expect(successCount).toEqual(7); + expect(failureCount).toEqual(1); + + })); + + it('should emmit messages on blur', async(() => { + + let expectedMessage; + let successCount = 0; + + kafkaService.setSample(sampleMessages); + + sampleDataComponent.onSampleDataChanged.subscribe((message: string) => { + ++successCount; + expect(message).toEqual(expectedMessage); + }); + + + expectedMessage = 'This is a simple message'; + fixture.debugElement.nativeElement.querySelector('textarea').value = expectedMessage; + sampleDataComponent.onBlur(); + + expect(successCount).toEqual(1); + expect(sampleDataComponent.sampleDataIndex).toEqual(0); + expect(sampleDataComponent.sampleData.length).toEqual(1); + expect(sampleDataComponent.sampleData[0]).toEqual(expectedMessage); + + + expectedMessage = ''; + fixture.debugElement.nativeElement.querySelector('textarea').value = expectedMessage; + sampleDataComponent.onBlur(); + + expect(successCount).toEqual(2); + expect(sampleDataComponent.sampleDataIndex).toEqual(0); + expect(sampleDataComponent.sampleData.length).toEqual(1); + + + expectedMessage = sampleMessages[0]; + sampleDataComponent.getNextSample(); + + expect(successCount).toEqual(3); + expect(sampleDataComponent.sampleDataIndex).toEqual(1); + expect(sampleDataComponent.sampleData.length).toEqual(2); + expect(sampleDataComponent.sampleData[1]).toEqual(sampleMessages[0]); + + })); + +}); http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/sample-data/sample-data.component.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/sample-data/sample-data.component.ts b/metron-interface/metron-config/src/app/shared/sample-data/sample-data.component.ts new file mode 100644 index 0000000..801e883 --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/sample-data/sample-data.component.ts @@ -0,0 +1,84 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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 {Component, Input, Output, EventEmitter, ViewChild, ElementRef} from '@angular/core'; +import {KafkaService} from '../../service/kafka.service'; + +@Component({ + selector: 'metron-config-sample-data', + templateUrl: 'sample-data.component.html', + styleUrls: ['sample-data.component.scss'], +}) + +export class SampleDataComponent { + + @Input() topic: string; + @Output() onSampleDataChanged = new EventEmitter<string>(); + @Output() onSampleDataNotAvailable = new EventEmitter<void>(); + + @ViewChild('sampleDataElement') sampleDataElement: ElementRef; + + sampleData: string[] = []; + sampleDataIndex: number = -1; + placeHolderText = 'Paste Sample Message' + '\n' + + 'A data sample cannot automatically be loaded. Connect to a Kafka Topic or paste a message here.'; + + + constructor(private kafkaService: KafkaService) { + } + + + getPreviousSample() { + if (this.sampleDataIndex > 0) { + this.sampleDataIndex = this.sampleDataIndex - 1; + this.onSampleDataChanged.emit(this.sampleData[this.sampleDataIndex]); + } + } + + getNextSample() { + if (this.sampleData.length - 1 === this.sampleDataIndex) { + this.kafkaService.sample(this.topic).subscribe((sampleData: string) => { + this.sampleDataIndex = this.sampleDataIndex + 1; + this.sampleData[this.sampleDataIndex] = sampleData; + this.onSampleDataChanged.emit(this.sampleData[this.sampleDataIndex]); + }, + error => { + this.onSampleDataNotAvailable.emit(); + }); + } else { + this.sampleDataIndex = this.sampleDataIndex + 1; + this.onSampleDataChanged.emit(this.sampleData[this.sampleDataIndex]); + } + + } + + onBlur() { + let currentValue = this.sampleDataElement.nativeElement.value; + + if (currentValue.trim() !== '' && this.sampleData[this.sampleDataIndex] !== currentValue) { + this.sampleDataIndex = this.sampleDataIndex + 1; + this.sampleData[this.sampleDataIndex] = currentValue; + this.onSampleDataChanged.emit(this.sampleData[this.sampleDataIndex]); + } + + if (currentValue.trim() === '') { + this.sampleDataElement.nativeElement.placeholder = this.placeHolderText; + this.onSampleDataChanged.emit(''); + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/sample-data/sample-data.module.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/sample-data/sample-data.module.ts b/metron-interface/metron-config/src/app/shared/sample-data/sample-data.module.ts new file mode 100644 index 0000000..e700903 --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/sample-data/sample-data.module.ts @@ -0,0 +1,13 @@ +import {NgModule} from '@angular/core'; + +import {SampleDataComponent} from './sample-data.component'; +import {SharedModule} from '../shared.module'; + +@NgModule({ + imports: [ SharedModule ], + exports: [ SampleDataComponent ], + declarations: [ SampleDataComponent ], + providers: [], +}) +export class SampleDataModule { +} http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/shared/shared.module.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/shared/shared.module.ts b/metron-interface/metron-config/src/app/shared/shared.module.ts new file mode 100644 index 0000000..4b2c4cc --- /dev/null +++ b/metron-interface/metron-config/src/app/shared/shared.module.ts @@ -0,0 +1,29 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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 { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import {MetronModalComponent} from './metron-modal/metron-modal.component'; + +@NgModule({ + imports: [ CommonModule ], + declarations: [ MetronModalComponent ], + exports: [ MetronModalComponent, + CommonModule, FormsModule ] +}) +export class SharedModule { } http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/util/enums.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/util/enums.ts b/metron-interface/metron-config/src/app/util/enums.ts new file mode 100644 index 0000000..b89af94 --- /dev/null +++ b/metron-interface/metron-config/src/app/util/enums.ts @@ -0,0 +1,21 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +export enum Sort { + ASC, + DSC +} http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/1ef8cd8f/metron-interface/metron-config/src/app/util/httpUtil.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-config/src/app/util/httpUtil.ts b/metron-interface/metron-config/src/app/util/httpUtil.ts new file mode 100644 index 0000000..a93e66e --- /dev/null +++ b/metron-interface/metron-config/src/app/util/httpUtil.ts @@ -0,0 +1,45 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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 {Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {RestError} from '../model/rest-error'; +export class HttpUtil { + + public static extractString(res: Response): string { + let text: string = res.text(); + return text || ''; + } + + public static extractData(res: Response): any { + let body = res.json(); + return body || {}; + } + + public static handleError(res: Response): Observable<RestError> { + // In a real world app, we might use a remote logging infrastructure + // We'd also dig deeper into the error to get a better message + let restError: RestError; + if (res.status !== 404) { + restError = res.json(); + } else { + restError = new RestError(); + restError.responseCode = 404; + } + return Observable.throw(restError); + } +}