This is an automated email from the ASF dual-hosted git repository. sardell pushed a commit to branch feature/METRON-1856-parser-aggregation in repository https://gitbox.apache.org/repos/asf/metron.git
The following commit(s) were added to refs/heads/feature/METRON-1856-parser-aggregation by this push: new 5599d18 METRON-2136 Add parser aggregation sidebar (ruffle1986 via sardell) closes apache/metron#1427 5599d18 is described below commit 5599d181d552924ef2c035337574f01529c26c53 Author: ruffle1986 <ftamas.m...@gmail.com> AuthorDate: Fri Aug 2 14:36:41 2019 +0200 METRON-2136 Add parser aggregation sidebar (ruffle1986 via sardell) closes apache/metron#1427 --- .../{effects/index.ts => models/parser.model.ts} | 9 +- .../sensor-parser-aggregate-sidebar.component.html | 74 ++++++++++ .../sensor-parser-aggregate-sidebar.component.scss | 97 +++++++++++++ .../sensor-parser-aggregate-sidebar.component.ts | 157 +++++++++++++++++++++ .../sensor-parser-aggregate-sidebar.module.ts} | 19 ++- .../sensor-parser-aggregate-sidebar.routing.ts} | 13 +- 6 files changed, 357 insertions(+), 12 deletions(-) diff --git a/metron-interface/metron-config/src/app/sensors/effects/index.ts b/metron-interface/metron-config/src/app/sensors/models/parser.model.ts similarity index 85% copy from metron-interface/metron-config/src/app/sensors/effects/index.ts copy to metron-interface/metron-config/src/app/sensors/models/parser.model.ts index 8f6ad93..bc02f0c 100644 --- a/metron-interface/metron-config/src/app/sensors/effects/index.ts +++ b/metron-interface/metron-config/src/app/sensors/models/parser.model.ts @@ -15,9 +15,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +export interface ParserModel { + group?: string, - import { SensorsEffects } from './sensors.effects'; + setName(value: string) - export * from './sensors.effects'; + getName(): string - export const effects = [ SensorsEffects ]; + getDescription(): string +} diff --git a/metron-interface/metron-config/src/app/sensors/sensor-parser-aggregate-sidebar/sensor-parser-aggregate-sidebar.component.html b/metron-interface/metron-config/src/app/sensors/sensor-parser-aggregate-sidebar/sensor-parser-aggregate-sidebar.component.html new file mode 100644 index 0000000..8b3692c --- /dev/null +++ b/metron-interface/metron-config/src/app/sensors/sensor-parser-aggregate-sidebar/sensor-parser-aggregate-sidebar.component.html @@ -0,0 +1,74 @@ +<!-- + 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. + --> +<metron-config-metron-modal> + <div class="metron-slider-pane-edit load-right-to-left dialog1x aggregate-sensors-pane"> + <i class="fa fa-times float-right close-button" (click)="close()"></i> + <div class="form-title"> + Aggregate Sensors + </div> + <div> + <div *ngIf="showCreateForm()"> + <div class="form-fields"> + <div class="form-field"> + <label> + <span class="label-text">NAME *</span> + <input #groupNameInput type="text" class="form-control" [value]="name" [readOnly]="existingGroup" (keyup)="onNameChange($event)" /> + <div *ngIf="groupNameInvalid"><label><span class="warning-text"> Group already exists </span></label></div> + </label> + </div> + <div class="form-field"> + <label> + <span class="label-text">DESCRIPTION</span> + <input #descriptionInput type="text" class="form-control" [value]="description"/> + </label> + </div> + </div> + <div> + <button (click)="createNew(groupNameInput.value, descriptionInput.value)" + (keyup.enter)="createNew(groupNameInput.value, descriptionInput.value)" + class="btn save-button" + [disabled]="groupNameInvalid">DONE</button> + <button (click)="close()" + (keyup.enter)="close()" + class="btn form-enable-disable-button">CANCEL</button> + </div> + </div> + <div *ngIf="!showCreateForm()"> + <div class="form-fields"> + <span class="label-text">JOIN BY GROUP</span> + <div class="switch-buttons"> + <button + (click)="allowMerge = true" + [ngClass]="{ 'active': allowMerge }" + > + MERGE + </button><button + (click)="allowMerge = false" + [ngClass]="{ 'active': !allowMerge }" + > + CREATE NEW + </button> + </div> + </div> + <div> + <button (click)="mergeOrCreate()" class="btn save-button">DONE</button> + <button (click)="close()" class="btn form-enable-disable-button">CANCEL</button> + </div> + </div> + </div> + + </div> +</metron-config-metron-modal> \ No newline at end of file diff --git a/metron-interface/metron-config/src/app/sensors/sensor-parser-aggregate-sidebar/sensor-parser-aggregate-sidebar.component.scss b/metron-interface/metron-config/src/app/sensors/sensor-parser-aggregate-sidebar/sensor-parser-aggregate-sidebar.component.scss new file mode 100644 index 0000000..4264588 --- /dev/null +++ b/metron-interface/metron-config/src/app/sensors/sensor-parser-aggregate-sidebar/sensor-parser-aggregate-sidebar.component.scss @@ -0,0 +1,97 @@ +/** + * 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. + */ +$base-gutter: 20px; + +.aggregate-sensors-pane { + padding: $base-gutter; +} + +.form-title { + margin-bottom: $base-gutter; +} + +.form-fields { + border-top: 1px solid #2B576B; + border-bottom: 1px solid #2B576B; + padding: $base-gutter 0 0; + margin-bottom: $base-gutter; +} + +.form-field { + + margin-bottom: $base-gutter; + + label { + display: block; + } + + & .label-text { + display: block; + } + + & input { + width: 100%; + } +} + +.save-button { + background-color: #006ea0; + border-color: #006ea0; + color: white; + font-size: 14px; + width: 32%; +} + +.switch-buttons { + margin-bottom: $base-gutter; + + & button { + appearance: none; + display: inline-block; + color: #999; + border-color: #4D4D4D; + width: 139px; + height: 35px; + line-height: 35px; + vertical-align: middle; + font-size: 14px; + cursor: pointer; + background: #404040; + outline: none; + + &:first-child { + border-right: none; + } + + &:nth-child(2) { + border-left: none; + } + + &.active { + color: #fff; + background: #2C5E6B; + border-color: #2C5E6B; + cursor: default; + } + } +} + +label .warning-text { + font-size: 12px; + font-family: Roboto-Medium; +} \ No newline at end of file diff --git a/metron-interface/metron-config/src/app/sensors/sensor-parser-aggregate-sidebar/sensor-parser-aggregate-sidebar.component.ts b/metron-interface/metron-config/src/app/sensors/sensor-parser-aggregate-sidebar/sensor-parser-aggregate-sidebar.component.ts new file mode 100644 index 0000000..a68f93c --- /dev/null +++ b/metron-interface/metron-config/src/app/sensors/sensor-parser-aggregate-sidebar/sensor-parser-aggregate-sidebar.component.ts @@ -0,0 +1,157 @@ +/** + * 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, OnInit, OnDestroy } from '@angular/core'; +import { Router, ActivatedRoute } from '@angular/router'; +import { Store, select } from '@ngrx/store'; +import { Observable, Subscription, combineLatest } from 'rxjs'; +import * as fromReducers from '../reducers'; +import * as fromActions from '../actions'; +import { getGroups, GroupState } from '../reducers'; + +@Component({ + selector: 'metron-config-sensor-aggregate', + templateUrl: './sensor-parser-aggregate-sidebar.component.html', + styleUrls: ['./sensor-parser-aggregate-sidebar.component.scss'] +}) +export class SensorParserAggregateSidebarComponent implements OnInit, OnDestroy { + + private forceCreate = false; + private draggedId: string; + private dropTargetId: string; + private state$: Observable<fromReducers.SensorState>; + private stateSub: Subscription; + private targetGroup: string; + private groupDetails = { + name: '', + description: '' + }; + groups: GroupState; + name: string; + description: string; + existingGroup = null; + allowMerge = true; + groupNameInvalid = false; + + constructor( + private router: Router, + private store: Store<fromReducers.State>, + private route: ActivatedRoute, + ) { + this.state$ = store.pipe(select(fromReducers.getSensorsState)); + } + + ngOnInit() { + const combined = combineLatest(this.state$, this.route.params); + this.stateSub = combined.subscribe(([state, routeParams]) => { + this.draggedId = state.layout.dnd.draggedId; + this.dropTargetId = state.layout.dnd.dropTargetId; + this.targetGroup = state.layout.dnd.targetGroup; + this.groups = state.groups; + if (routeParams['id']) { + this.existingGroup = this.groups.items.filter(g => g.config.getName() === routeParams['id']); + this.name = this.existingGroup[0].config.getName(); + this.description = this.existingGroup[0].config.getDescription(); + } else { + this.name = 'Aggregate-' + [this.draggedId, this.dropTargetId].join('-') ; + this.description = ''; + } + }); + } + + close() { + this.forceCreate = false; + this.router.navigateByUrl('/sensors'); + } + + createNew(groupName: string, groupDescription: string) { + groupName = groupName.trim(); + groupDescription = groupDescription.trim(); + + this.groupDetails.name = groupName; + this.groupDetails.description = groupDescription; + const group = this.groups.items.filter(item => item.config.getName() === this.name); + if (group.length) { + this.store.dispatch(new fromActions.UpdateGroupDescription(this.groupDetails)); + this.close(); + return; + } else { + this.store.dispatch(new fromActions.CreateGroup(this.groupDetails)); + } + + if (!this.targetGroup) { + this.store.dispatch(new fromActions.AggregateParsers({ + groupName, + parserIds: [ + this.dropTargetId, + this.draggedId, + ] + })); + } else { + const parserIds = [this.draggedId, this.dropTargetId]; + this.store.dispatch(new fromActions.AddToGroup({ + groupName, + parserIds + })); + parserIds.forEach((parserId) => { + this.store.dispatch(new fromActions.InjectAfter({ + reference: groupName, + parserId, + })); + }); + } + + this.close(); + } + + mergeOrCreate() { + if (this.allowMerge) { + this.addToExisting(); + } else { + this.forceCreate = true; + } + } + + addToExisting() { + + this.store.dispatch(new fromActions.AddToGroup({ + groupName: this.targetGroup, + parserIds: [this.draggedId] + })); + + this.store.dispatch(new fromActions.InjectAfter({ + reference: this.dropTargetId, + parserId: this.draggedId, + })); + + this.close(); + } + + showCreateForm(): boolean { + return !this.targetGroup || this.forceCreate; + } + + onNameChange(e) { + const value = e.target.value.trim(); + const groupWithSameName = this.groups.items.find(group => group.config.getName() === value); + this.groupNameInvalid = !!(groupWithSameName); + } + + ngOnDestroy() { + this.stateSub.unsubscribe(); + } +} diff --git a/metron-interface/metron-config/src/app/sensors/effects/index.ts b/metron-interface/metron-config/src/app/sensors/sensor-parser-aggregate-sidebar/sensor-parser-aggregate-sidebar.module.ts similarity index 64% copy from metron-interface/metron-config/src/app/sensors/effects/index.ts copy to metron-interface/metron-config/src/app/sensors/sensor-parser-aggregate-sidebar/sensor-parser-aggregate-sidebar.module.ts index 8f6ad93..c5f2522 100644 --- a/metron-interface/metron-config/src/app/sensors/effects/index.ts +++ b/metron-interface/metron-config/src/app/sensors/sensor-parser-aggregate-sidebar/sensor-parser-aggregate-sidebar.module.ts @@ -15,9 +15,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { NgModule } from '@angular/core'; +import { routing } from './sensor-parser-aggregate-sidebar.routing'; +import { SensorParserAggregateSidebarComponent } from './sensor-parser-aggregate-sidebar.component'; +import { SharedModule } from '../../shared/shared.module'; - import { SensorsEffects } from './sensors.effects'; - - export * from './sensors.effects'; - - export const effects = [ SensorsEffects ]; +@NgModule({ + imports: [ + routing, + SharedModule + ], + declarations: [ + SensorParserAggregateSidebarComponent + ], +}) +export class SensorParserAggregateSidebarModule {} diff --git a/metron-interface/metron-config/src/app/sensors/effects/index.ts b/metron-interface/metron-config/src/app/sensors/sensor-parser-aggregate-sidebar/sensor-parser-aggregate-sidebar.routing.ts similarity index 56% rename from metron-interface/metron-config/src/app/sensors/effects/index.ts rename to metron-interface/metron-config/src/app/sensors/sensor-parser-aggregate-sidebar/sensor-parser-aggregate-sidebar.routing.ts index 8f6ad93..ba994f7 100644 --- a/metron-interface/metron-config/src/app/sensors/effects/index.ts +++ b/metron-interface/metron-config/src/app/sensors/sensor-parser-aggregate-sidebar/sensor-parser-aggregate-sidebar.routing.ts @@ -15,9 +15,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { ModuleWithProviders } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; +import { SensorParserAggregateSidebarComponent } from './sensor-parser-aggregate-sidebar.component'; +import { AuthGuard } from '../../shared/auth-guard'; - import { SensorsEffects } from './sensors.effects'; +const routes: Routes = [ + { path: 'sensor-aggregate', component: SensorParserAggregateSidebarComponent, canActivate: [ AuthGuard ], outlet: 'dialog'}, + { path: 'sensor-aggregate/:id', component: SensorParserAggregateSidebarComponent, canActivate: [ AuthGuard ], outlet: 'dialog'} +]; - export * from './sensors.effects'; - - export const effects = [ SensorsEffects ]; +export const routing: ModuleWithProviders = RouterModule.forChild(routes);