Skip to content

Commit

Permalink
Add status widget to data explorer (#3226)
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcelfrueh authored Sep 14, 2024
1 parent 7b8da89 commit 19cdd22
Show file tree
Hide file tree
Showing 10 changed files with 632 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
<!--
~ 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.
~
-->

<sp-visualization-config-outer
[configurationValid]="
currentlyConfiguredWidget.visualizationConfig.configurationValid
"
>
<sp-configuration-box title="Settings">
<div fxLayout="column" fxLayoutGap="10px">
<div
fxLayout="row"
fxLayoutGap="10px"
fxLayoutAlign="start center"
fxFlex="100"
>
<small fxFlex="30">Select Value Type</small>
<mat-radio-group
[(ngModel)]="
currentlyConfiguredWidget.visualizationConfig
.selectedDataType
"
(change)="selectDataType($event.source.value)"
>
<mat-radio-button [value]="'number'"
>Numeric Value</mat-radio-button
>
<mat-radio-button [value]="'boolean'"
>Boolean Value</mat-radio-button
>
</mat-radio-group>
</div>

<div
*ngIf="
currentlyConfiguredWidget.visualizationConfig
.selectedDataType === 'number'
"
fxLayout="column"
fxLayoutGap="10px"
>
<div
fxLayout="row"
fxLayoutGap="10px"
fxLayoutAlign="start center"
fxFlex="100"
>
<small
fxFlex="30"
matTooltip="Interval in seconds in which an event must arrive"
matTooltipPosition="above"
>Interval [sec]</small
>
<mat-form-field color="accent" appearance="outline" fxFlex>
<input
type="number"
[(ngModel)]="
currentlyConfiguredWidget.visualizationConfig
.selectedInterval
"
matInput
(input)="selectInterval($event.target.value)"
min="0"
/>
</mat-form-field>
</div>
<div
fxLayout="row"
fxLayoutGap="10px"
fxLayoutAlign="start center"
fxFlex="100"
>
<small>Show Last Seen Timestamp</small>
<mat-checkbox
color="accent"
[(ngModel)]="
currentlyConfiguredWidget.visualizationConfig
.selectedLastSeen
"
(ngModelChange)="showLastSeen($event)"
>
</mat-checkbox>
</div>
</div>

<div
*ngIf="
currentlyConfiguredWidget.visualizationConfig
.selectedDataType === 'boolean'
"
fxLayout="column"
fxLayoutGap="10px"
>
<div
fxLayout="row"
fxLayoutGap="10px"
fxLayoutAlign="start center"
fxFlex="100"
>
<small fxFlex="30">Field</small>
<sp-select-property
[availableProperties]="fieldProvider.booleanFields"
[selectedProperty]="
currentlyConfiguredWidget.visualizationConfig
.selectedBooleanFieldToObserve
"
(changeSelectedProperty)="
selectBooleanFieldToObserve($event)
"
fxFlex
></sp-select-property>
</div>

<div
fxLayout="row"
fxLayoutGap="10px"
fxLayoutAlign="start center"
fxFlex="100"
>
<small fxFlex="30">Select Mapping</small>
<mat-radio-group
[(ngModel)]="
currentlyConfiguredWidget.visualizationConfig
.selectedMappingGreenTrue
"
(change)="selectMappingGreenTrue($event.source.value)"
>
<mat-radio-button [value]="true">
<span class="color-box green-box"></span> True
<span class="spacing"></span>
<span class="color-box red-box"></span> False
</mat-radio-button>
<mat-radio-button [value]="false">
<span class="color-box red-box"></span> True
<span class="spacing"></span>
<span class="color-box green-box"></span> False
</mat-radio-button>
</mat-radio-group>
</div>
</div>
</div>
</sp-configuration-box>
</sp-visualization-config-outer>
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* 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.
*/

.color-box {
display: inline-block;
width: 12px;
height: 12px;
margin-right: 5px;
border-radius: 50%;
}
.spacing {
margin-left: 15px;
}
.green-box {
background-color: green;
}

.red-box {
background-color: red;
}

.checkbox-container {
margin-top: 20px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* 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 } from '@angular/core';
import { BaseWidgetConfig } from '../../base/base-widget-config';
import { WidgetConfigurationService } from '../../../../services/widget-configuration.service';
import {
StatusWidgetModel,
StatusVisConfig,
} from '../model/status-widget.model';
import { DataExplorerFieldProviderService } from '../../../../services/data-explorer-field-provider-service';
import { DataExplorerField } from '@streampipes/platform-services';

@Component({
selector: 'sp-data-explorer-status-widget-config',
templateUrl: './status-widget-config.component.html',
styleUrls: ['./status-widget-config.component.scss'],
})
export class StatusWidgetConfigComponent extends BaseWidgetConfig<
StatusWidgetModel,
StatusVisConfig
> {
constructor(
widgetConfigurationService: WidgetConfigurationService,
fieldService: DataExplorerFieldProviderService,
) {
super(widgetConfigurationService, fieldService);
}

selectDataType(selectedDataType: string): void {
this.currentlyConfiguredWidget.visualizationConfig.selectedDataType =
selectedDataType;
this.triggerViewRefresh();
}

selectInterval(selectedInterval: number): void {
this.currentlyConfiguredWidget.visualizationConfig.selectedInterval =
selectedInterval;
this.triggerViewRefresh();
}

showLastSeen(selectedLastSeen: boolean): void {
this.currentlyConfiguredWidget.visualizationConfig.showLastSeen =
selectedLastSeen;
this.triggerViewRefresh();
}

selectBooleanFieldToObserve(
selectedBooleanFieldToObserve: DataExplorerField,
): void {
this.currentlyConfiguredWidget.visualizationConfig.selectedBooleanFieldToObserve =
selectedBooleanFieldToObserve;
this.triggerViewRefresh();
}

selectMappingGreenTrue(selectedMappingGreenTrue: boolean): void {
this.currentlyConfiguredWidget.visualizationConfig.selectedMappingGreenTrue =
selectedMappingGreenTrue;
this.triggerViewRefresh();
}

protected applyWidgetConfig(config: StatusVisConfig): void {
config.selectedBooleanFieldToObserve =
this.fieldService.getSelectedField(
config.selectedBooleanFieldToObserve,
this.fieldProvider.allFields,
() => this.fieldProvider.allFields[0],
);
this.currentlyConfiguredWidget.visualizationConfig.selectedInterval ??= 5;
this.currentlyConfiguredWidget.visualizationConfig.selectedMappingGreenTrue ??=
true;
}
protected requiredFieldsForChartPresent(): boolean {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* 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 {
DataExplorerDataConfig,
DataExplorerWidgetModel,
DataExplorerField,
} from '@streampipes/platform-services';
import { DataExplorerVisConfig } from '../../../../models/dataview-dashboard.model';

export interface StatusVisConfig extends DataExplorerVisConfig {
selectedDataType: string;
selectedInterval: number;
showLastSeen: boolean;
selectedBooleanFieldToObserve: DataExplorerField;
selectedMappingGreenTrue: boolean;
}

export interface StatusWidgetModel extends DataExplorerWidgetModel {
dataConfig: DataExplorerDataConfig;
visualizationConfig: StatusVisConfig;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<!--
~ 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
fxFlex="100"
fxLayoutAlign="center center"
fxLayout="column"
class="main-panel"
[ngStyle]="{
background: dataExplorerWidget.baseAppearanceConfig.backgroundColor,
color: dataExplorerWidget.baseAppearanceConfig.textColor,
overflowX: 'auto'
}"
>
<sp-no-data-in-date-range
*ngIf="showNoDataInDateRange"
[viewDateRange]="timeSettings"
class="h-50"
>
</sp-no-data-in-date-range>

<div fxLayoutAlign="center center">
<div
class="tl-container"
[ngStyle]="{
width: containerWidth + 'px',
height: containerHeight + 'px'
}"
>
<div
class="light"
[ngClass]="{
'light-red': !active,
'light-green': active
}"
[ngStyle]="{
width: lightWidth + 'px',
height: lightHeight + 'px'
}"
></div>
</div>
</div>
<div *ngIf="selectedDataType === 'number' && showLastSeen">
<h5>Last seen: {{ lastTimestamp | date: 'short' }}</h5>
</div>
</div>
Loading

0 comments on commit 19cdd22

Please sign in to comment.