This is an automated email from the ASF dual-hosted git repository.
zehnder pushed a commit to branch STREAMPIPES-380
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git
The following commit(s) were added to refs/heads/STREAMPIPES-380 by this push:
new a97449a [STREAMPIPES-380] Add components for stream rules
a97449a is described below
commit a97449a4a2367302f09f1f519b20b70b8fba054a
Author: Philipp Zehnder <[email protected]>
AuthorDate: Thu Jul 8 17:19:45 2021 +0200
[STREAMPIPES-380] Add components for stream rules
---
ui/karma.conf.js | 2 +-
.../event-rate-reduction-rule.component.css | 0
.../event-rate-reduction-rule.component.html | 25 +++++++
.../event-rate-reduction-rule.component.spec.ts | 25 +++++++
.../event-rate-reduction-rule.component.ts | 73 +++++++++++++++++++
.../format-configuration.component.ts | 3 +
.../remove-duplicate-rule.component.css | 18 +++++
.../remove-duplicate-rule.component.html | 31 ++++++++
.../remove-duplicate-rule.component.spec.ts | 47 ++++++++++++
.../remove-duplicate-rule.component.ts | 83 ++++++++++++++++++++++
.../start-adapter-configuration.component.html | 34 +++------
.../start-adapter-configuration.component.ts | 61 ++++++++--------
ui/src/app/connect/connect.module.ts | 6 +-
13 files changed, 351 insertions(+), 57 deletions(-)
diff --git a/ui/karma.conf.js b/ui/karma.conf.js
index 4cb07db..59161eb 100644
--- a/ui/karma.conf.js
+++ b/ui/karma.conf.js
@@ -63,6 +63,6 @@ module.exports = function (config) {
browserNoActivityTimeout: 50000,
colors: true,
logLevel: config.LOG_INFO,
- browsers: ['ChromeHeadless', 'FirefoxHeadless']
+ browsers: ['ChromeHeadless']
});
};
diff --git
a/ui/src/app/connect/components/event-rate-reduction-rule/event-rate-reduction-rule.component.css
b/ui/src/app/connect/components/event-rate-reduction-rule/event-rate-reduction-rule.component.css
new file mode 100644
index 0000000..e69de29
diff --git
a/ui/src/app/connect/components/event-rate-reduction-rule/event-rate-reduction-rule.component.html
b/ui/src/app/connect/components/event-rate-reduction-rule/event-rate-reduction-rule.component.html
new file mode 100644
index 0000000..7ee07e9
--- /dev/null
+++
b/ui/src/app/connect/components/event-rate-reduction-rule/event-rate-reduction-rule.component.html
@@ -0,0 +1,25 @@
+
+<div [formGroup]="eventReductionRuleForm" fxLayoutAlign="center"
fxLayout="column" fxFlex="100">
+ <mat-checkbox formControlName="eventRateReduction"
+ matTooltip="Send maximum one event in the specified time
window">Reduce the event rate
+ </mat-checkbox>
+ <mat-form-field *ngIf="showEventRateReductionInput">
+ <input matInput
+ id="input-evenRateTime"
+ placeholder="Time Window (Milliseconds)"
+ matTooltipPosition="above"
+ formControlName="eventRateTime">
+ <mat-error *ngIf="!eventRateTimeValid">
+ {{errorMessage}}
+ </mat-error>
+ </mat-form-field>
+ <mat-form-field *ngIf="showEventRateReductionInput">
+ <mat-label>Event Aggregation</mat-label>
+ <mat-select formControlName="eventRateMode">
+ <mat-option class="md-elevation-z1" style="background: white;"
+ matTooltip="Last Event in Time Window" value="none">
+ None
+ </mat-option>
+ </mat-select>
+ </mat-form-field>
+</div>
diff --git
a/ui/src/app/connect/components/event-rate-reduction-rule/event-rate-reduction-rule.component.spec.ts
b/ui/src/app/connect/components/event-rate-reduction-rule/event-rate-reduction-rule.component.spec.ts
new file mode 100644
index 0000000..fd34e9d
--- /dev/null
+++
b/ui/src/app/connect/components/event-rate-reduction-rule/event-rate-reduction-rule.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { EventRateReductionRuleComponent } from
'./event-rate-reduction-rule.component';
+
+describe('EventRateReductionRuleComponent', () => {
+ let component: EventRateReductionRuleComponent;
+ let fixture: ComponentFixture<EventRateReductionRuleComponent>;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ EventRateReductionRuleComponent ]
+ })
+ .compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(EventRateReductionRuleComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git
a/ui/src/app/connect/components/event-rate-reduction-rule/event-rate-reduction-rule.component.ts
b/ui/src/app/connect/components/event-rate-reduction-rule/event-rate-reduction-rule.component.ts
new file mode 100644
index 0000000..9ec63e1
--- /dev/null
+++
b/ui/src/app/connect/components/event-rate-reduction-rule/event-rate-reduction-rule.component.ts
@@ -0,0 +1,73 @@
+import { Component, EventEmitter, OnInit, Output } from '@angular/core';
+import {
+ EventRateTransformationRuleDescription,
+ RemoveDuplicatesTransformationRuleDescription
+} from '../../../core-model/gen/streampipes-model';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+
+@Component({
+ selector: 'sp-event-rate-reduction-rule',
+ templateUrl: './event-rate-reduction-rule.component.html',
+ styleUrls: ['./event-rate-reduction-rule.component.css']
+})
+export class EventRateReductionRuleComponent implements OnInit {
+
+ showEventRateReductionInput = false;
+
+ eventReductionRuleForm: FormGroup;
+
+ eventRateTimeValid = true;
+ errorMessage = 'Please enter a numerical value';
+
+ private rule: EventRateTransformationRuleDescription;
+
+ @Output()
+ updateRuleEmitter: EventEmitter<EventRateTransformationRuleDescription> =
+ new EventEmitter<EventRateTransformationRuleDescription>();
+
+ constructor(private fb: FormBuilder) {
+ this.eventReductionRuleForm = this.fb.group({
+ eventRateReduction: [false],
+ eventRateTime: [''],
+ eventRateMode: ['none']
+ });
+
+ this.onChanges();
+ }
+
+ ngOnInit(): void {
+ this.rule = new EventRateTransformationRuleDescription();
+ this.rule['@class'] =
'org.apache.streampipes.model.connect.rules.stream.EventRateTransformationRuleDescription';
+ this.rule.aggregationType = 'None';
+ }
+
+ onChanges() {
+ const eventRateTimeControl =
this.eventReductionRuleForm.get('eventRateTime');
+ const eventRateModeControl =
this.eventReductionRuleForm.get('eventRateMode');
+
+
this.eventReductionRuleForm.get('eventRateReduction').valueChanges.subscribe(val
=> {
+ if (val) {
+ eventRateTimeControl.setValidators([Validators.required,
Validators.pattern(/^(0|[1-9]\d*)?$/)]);
+ eventRateModeControl.setValidators(Validators.required);
+ this.eventRateTimeValid = false;
+ } else {
+ eventRateTimeControl.setValidators(null);
+ eventRateModeControl.setValidators(null);
+ this.updateRuleEmitter.emit(null);
+ }
+
+ this.showEventRateReductionInput = val;
+ });
+
+
this.eventReductionRuleForm.get('eventRateTime').statusChanges.subscribe(status
=> {
+ this.eventRateTimeValid = status === 'VALID';
+ });
+
+
this.eventReductionRuleForm.get('eventRateTime').valueChanges.subscribe(val => {
+ this.rule.aggregationTimeWindow = val;
+ this.updateRuleEmitter.emit(this.rule);
+ });
+ }
+
+
+}
diff --git
a/ui/src/app/connect/components/format-configuration/format-configuration.component.ts
b/ui/src/app/connect/components/format-configuration/format-configuration.component.ts
index ccf3e64..c87660b 100644
---
a/ui/src/app/connect/components/format-configuration/format-configuration.component.ts
+++
b/ui/src/app/connect/components/format-configuration/format-configuration.component.ts
@@ -123,6 +123,9 @@ export class FormatConfigurationComponent implements OnInit
{
this.clickNextEmitter.emit();
}
+ /**
+ * Go one step back in the adapter configuration process
+ */
public goBack() {
this.goBackEmitter.emit();
}
diff --git
a/ui/src/app/connect/components/remove-duplicate-rule/remove-duplicate-rule.component.css
b/ui/src/app/connect/components/remove-duplicate-rule/remove-duplicate-rule.component.css
new file mode 100644
index 0000000..58ba04b
--- /dev/null
+++
b/ui/src/app/connect/components/remove-duplicate-rule/remove-duplicate-rule.component.css
@@ -0,0 +1,18 @@
+/*
+ * 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.
+ *
+ */
+
diff --git
a/ui/src/app/connect/components/remove-duplicate-rule/remove-duplicate-rule.component.html
b/ui/src/app/connect/components/remove-duplicate-rule/remove-duplicate-rule.component.html
new file mode 100644
index 0000000..0361726
--- /dev/null
+++
b/ui/src/app/connect/components/remove-duplicate-rule/remove-duplicate-rule.component.html
@@ -0,0 +1,31 @@
+<!--
+ ~ 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 [formGroup]="duplicateRuleForm" fxLayoutAlign="center" fxLayout="column"
fxFlex="100">
+ <mat-checkbox formControlName="removeDuplicates">Remove
Duplicates</mat-checkbox>
+ <mat-form-field *ngIf="showRemoveDuplicateTimeInput">
+ <input matInput id="input-removeDuplicatesTime"
+ formControlName="removeDuplicatesTime"
+ type="number"
+ placeholder="Remove Duplicates Time Window">
+ <mat-error *ngIf="!removeDuplicatesTimeValid">
+ {{errorMessage}}
+ </mat-error>
+ </mat-form-field>
+</div>
+
diff --git
a/ui/src/app/connect/components/remove-duplicate-rule/remove-duplicate-rule.component.spec.ts
b/ui/src/app/connect/components/remove-duplicate-rule/remove-duplicate-rule.component.spec.ts
new file mode 100644
index 0000000..c93ecf0
--- /dev/null
+++
b/ui/src/app/connect/components/remove-duplicate-rule/remove-duplicate-rule.component.spec.ts
@@ -0,0 +1,47 @@
+/*
+ * 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 { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { RemoveDuplicateRuleComponent } from
'./remove-duplicate-rule.component';
+
+describe('RemoveDuplicateRuleComponent', () => {
+ // let fixture: ComponentFixture<RemoveDuplicateRuleComponent>;
+ let component: RemoveDuplicateRuleComponent;
+
+ // beforeEach(async () => {
+ // await TestBed.configureTestingModule({
+ // declarations: [ RemoveDuplicateRuleComponent ]
+ // })
+ // .compileComponents();
+ // });
+
+ // beforeEach(() => {
+ // fixture = TestBed.createComponent(RemoveDuplicateRuleComponent);
+ // component = fixture.componentInstance;
+ // fixture.detectChanges();
+ // });
+
+ it('should create', () => {
+ // @ts-ignore
+ component = new RemoveDuplicateRuleComponent();
+ component.ngOnInit();
+
+ expect(false).toBeTrue();
+ });
+});
diff --git
a/ui/src/app/connect/components/remove-duplicate-rule/remove-duplicate-rule.component.ts
b/ui/src/app/connect/components/remove-duplicate-rule/remove-duplicate-rule.component.ts
new file mode 100644
index 0000000..7655d5f
--- /dev/null
+++
b/ui/src/app/connect/components/remove-duplicate-rule/remove-duplicate-rule.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, EventEmitter, OnInit, Output } from '@angular/core';
+import { RemoveDuplicatesTransformationRuleDescription } from
'../../../core-model/gen/streampipes-model';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+
+@Component({
+ selector: 'sp-remove-duplicate-rule',
+ templateUrl: './remove-duplicate-rule.component.html',
+ styleUrls: ['./remove-duplicate-rule.component.css']
+})
+export class RemoveDuplicateRuleComponent implements OnInit {
+
+ duplicateRuleForm: FormGroup;
+
+ showRemoveDuplicateTimeInput = false;
+
+ errorMessage = 'Please enter a numerical value';
+
+ removeDuplicatesTimeValid = true;
+
+ private rule: RemoveDuplicatesTransformationRuleDescription;
+
+ @Output()
+ updateRuleEmitter:
EventEmitter<RemoveDuplicatesTransformationRuleDescription> =
+ new EventEmitter<RemoveDuplicatesTransformationRuleDescription>();
+
+ constructor(private fb: FormBuilder) {
+ this.duplicateRuleForm = this.fb.group({
+ 'removeDuplicates': [false],
+ removeDuplicatesTime: ['']
+ });
+
+ this.onChanges();
+ }
+
+ ngOnInit(): void {
+ this.rule = new RemoveDuplicatesTransformationRuleDescription();
+ this.rule['@class'] =
'org.apache.streampipes.model.connect.rules.stream.RemoveDuplicatesTransformationRuleDescription';
+ }
+
+ onChanges() {
+ const removeDuplicatesTimeControl =
this.duplicateRuleForm.get('removeDuplicatesTime');
+
+ this.duplicateRuleForm.get('removeDuplicates').valueChanges.subscribe(val
=> {
+ if (val) {
+ removeDuplicatesTimeControl.setValidators([Validators.required,
Validators.pattern(/^(0|[1-9]\d*)?$/)]);
+ this.removeDuplicatesTimeValid = false;
+ } else {
+ removeDuplicatesTimeControl.setValidators(null);
+ this.updateRuleEmitter.emit(null);
+ }
+
+ this.showRemoveDuplicateTimeInput = val;
+ });
+
+
this.duplicateRuleForm.get('removeDuplicatesTime').statusChanges.subscribe(status
=> {
+ this.removeDuplicatesTimeValid = status === 'VALID';
+ });
+
+
this.duplicateRuleForm.get('removeDuplicatesTime').valueChanges.subscribe(val
=> {
+ this.rule.filterTimeWindow = val;
+ this.updateRuleEmitter.emit(this.rule);
+ });
+ }
+
+}
diff --git
a/ui/src/app/connect/components/start-adapter-configuration/start-adapter-configuration.component.html
b/ui/src/app/connect/components/start-adapter-configuration/start-adapter-configuration.component.html
index c26b2c9..ce1f129 100644
---
a/ui/src/app/connect/components/start-adapter-configuration/start-adapter-configuration.component.html
+++
b/ui/src/app/connect/components/start-adapter-configuration/start-adapter-configuration.component.html
@@ -21,6 +21,8 @@
<h4>Adapter settings</h4>
</div>
+ <!-- TODO NEXT Remove ngModel and replace it with a FormGroup oder
FormControls-->
+
<div class="sp-blue-border padding" style="padding: 15px; margin-bottom:
2%;">
<div fxLayoutAlign="center" fxLayout="column" fxFlex="100">
<mat-form-field>
@@ -43,33 +45,13 @@
<!-- </button>-->
<!-- </mat-form-field>-->
+ <sp-remove-duplicate-rule
+ (updateRuleEmitter)="setDuplicateRule($event)">
+ </sp-remove-duplicate-rule>
- <mat-checkbox [(ngModel)]="removeDuplicates"
- [ngModelOptions]="{standalone: true}">Remove
Duplicates</mat-checkbox>
- <mat-form-field *ngIf="removeDuplicates">
- <input matInput id="input-removeDuplicatesTime"
- [ngModelOptions]="{standalone: true}"
placeholder="Remove Duplicates Time Window"
- [(ngModel)]="removeDuplicatesTime">
- </mat-form-field>
-
- <mat-checkbox [(ngModel)]="eventRateReduction"
- [ngModelOptions]="{standalone: true}"
- matTooltip="Send maximum one event in the specified
time window">Reduce the event rate
- </mat-checkbox>
- <mat-form-field *ngIf="eventRateReduction">
- <input type="number" matInput id="input-evenRateTime"
- [ngModelOptions]="{standalone: true}"
[(ngModel)]="eventRateTime"
- placeholder="Time Window (Milliseconds)"
matTooltipPosition="above">
- </mat-form-field>
- <mat-form-field *ngIf="eventRateReduction">
- <mat-label>Event Aggregation</mat-label>
- <mat-select [(ngModel)]="eventRateMode"
[ngModelOptions]="{standalone: true}">
- <mat-option class="md-elevation-z1" style="background:
white;"
- matTooltip="Last Event in Time Window"
value="none">
- None
- </mat-option>
- </mat-select>
- </mat-form-field>
+ <sp-event-rate-reduction-rule
+ (updateRuleEmitter)="setEventRateReductionRule($event)">
+ </sp-event-rate-reduction-rule>
<!-- Start pipeline template to store raw events in data lake -->
<!--<mat-checkbox *ngIf="timestampPropertiesInSchema.length ==
0"-->
diff --git
a/ui/src/app/connect/components/start-adapter-configuration/start-adapter-configuration.component.ts
b/ui/src/app/connect/components/start-adapter-configuration/start-adapter-configuration.component.ts
index 3306fcd..1cc61eb 100644
---
a/ui/src/app/connect/components/start-adapter-configuration/start-adapter-configuration.component.ts
+++
b/ui/src/app/connect/components/start-adapter-configuration/start-adapter-configuration.component.ts
@@ -65,20 +65,14 @@ export class StartAdapterConfigurationComponent implements
OnInit {
startAdapterSettingsFormValid = false;
-
- // preprocessing rule variables
- removeDuplicates = false;
- removeDuplicatesTime: number;
-
- eventRateReduction = false;
- eventRateTime: number;
- eventRateMode = 'none';
-
saveInDataLake = false;
dataLakeTimestampField: string;
isSetAdapter = false;
+ private duplicateRule: RemoveDuplicatesTransformationRuleDescription;
+ private eventRateReductionRule: EventRateTransformationRuleDescription;
+
constructor(
private dialogService: DialogService,
@@ -98,19 +92,30 @@ export class StartAdapterConfigurationComponent implements
OnInit {
}
}
- public triggerDialog(storeAsTemplate: boolean) {
- if (this.removeDuplicates) {
- const removeDuplicates: RemoveDuplicatesTransformationRuleDescription =
new RemoveDuplicatesTransformationRuleDescription();
- removeDuplicates['@class'] =
'org.apache.streampipes.model.connect.rules.stream.RemoveDuplicatesTransformationRuleDescription';
- removeDuplicates.filterTimeWindow = (this.removeDuplicatesTime) as any;
- this.adapterDescription.rules.push(removeDuplicates);
+
+ setDuplicateRule(rule) {
+ this.duplicateRule = rule;
+ }
+
+ setEventRateReductionRule(rule) {
+ this.eventRateReductionRule = rule;
+ }
+
+ public saveTemplate() {
+ this.triggerDialog(true);
+ }
+
+ public startAdapter() {
+ this.triggerDialog(false);
+ }
+
+ private triggerDialog(storeAsTemplate: boolean) {
+ if (this.duplicateRule) {
+ this.adapterDescription.rules.push(this.duplicateRule);
}
- if (this.eventRateReduction) {
- const eventRate: EventRateTransformationRuleDescription = new
EventRateTransformationRuleDescription();
- eventRate['@class'] =
'org.apache.streampipes.model.connect.rules.stream.EventRateTransformationRuleDescription';
- eventRate.aggregationTimeWindow = this.eventRateMode as any;
- eventRate.aggregationType = this.eventRateMode;
- this.adapterDescription.rules.push(eventRate);
+
+ if (this.eventRateReductionRule) {
+ this.adapterDescription.rules.push(this.eventRateReductionRule);
}
const dialogRef = this.dialogService.open(AdapterStartedDialog, {
@@ -132,18 +137,16 @@ export class StartAdapterConfigurationComponent
implements OnInit {
});
}
- public saveTemplate() {
- this.triggerDialog(true);
- }
-
- public startAdapter() {
- this.triggerDialog(false);
- }
-
+ /**
+ * Cancel the adapter configuration process
+ */
public removeSelection() {
this.removeSelectionEmitter.emit();
}
+ /**
+ * Go one step back in the adapter configuration process
+ */
public goBack() {
this.goBackEmitter.emit();
}
diff --git a/ui/src/app/connect/connect.module.ts
b/ui/src/app/connect/connect.module.ts
index 79e7e2b..fc7bc1b 100644
--- a/ui/src/app/connect/connect.module.ts
+++ b/ui/src/app/connect/connect.module.ts
@@ -80,6 +80,8 @@ import { LoadingMessageComponent } from
'./components/schema-editor/loading-mess
import { SchemaEditorHeaderComponent } from
'./components/schema-editor/schema-editor-header/schema-editor-header.component';
import { StartAdapterConfigurationComponent } from
'./components/start-adapter-configuration/start-adapter-configuration.component';
import { DeleteAdapterDialogComponent } from
'./dialog/delete-adapter-dialog/delete-adapter-dialog.component';
+import { RemoveDuplicateRuleComponent } from
'./components/remove-duplicate-rule/remove-duplicate-rule.component';
+import { EventRateReductionRuleComponent } from
'./components/event-rate-reduction-rule/event-rate-reduction-rule.component';
@NgModule({
imports: [
@@ -133,7 +135,9 @@ import { DeleteAdapterDialogComponent } from
'./dialog/delete-adapter-dialog/del
ErrorMessageComponent,
LoadingMessageComponent,
SchemaEditorHeaderComponent,
- StartAdapterConfigurationComponent
+ StartAdapterConfigurationComponent,
+ RemoveDuplicateRuleComponent,
+ EventRateReductionRuleComponent
],
providers: [
RestService,