blob: 9e3e962de23c0ce56a77090b99297df28542f59f [file] [log] [blame]
/*
* 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,
ComponentFactoryResolver,
ComponentRef,
EventEmitter,
Input,
OnDestroy,
OnInit,
Output,
ViewChild,
} from '@angular/core';
import { GridsterItemComponent } from 'angular-gridster2';
import {
DashboardItem,
DataExplorerWidgetModel,
DataLakeMeasure,
SpLogMessage,
TimeSettings,
} from '@streampipes/platform-services';
import { interval, Subscription } from 'rxjs';
import { takeWhile } from 'rxjs/operators';
import { DataExplorerWidgetRegistry } from '../../registry/data-explorer-widget-registry';
import { WidgetDirective } from './widget.directive';
import { WidgetTypeService } from '../../services/widget-type.service';
import { AuthService } from '../../../services/auth.service';
import { UserPrivilege } from '../../../_enums/user-privilege.enum';
import { CurrentUserService } from '@streampipes/shared-ui';
import { BaseWidgetData } from '../../models/dataview-dashboard.model';
import { DataExplorerDashboardService } from '../../services/data-explorer-dashboard.service';
@Component({
selector: 'sp-data-explorer-dashboard-widget',
templateUrl: './data-explorer-dashboard-widget.component.html',
styleUrls: ['./data-explorer-dashboard-widget.component.scss'],
})
export class DataExplorerDashboardWidgetComponent implements OnInit, OnDestroy {
@Input()
dashboardItem: DashboardItem;
@Input()
configuredWidget: DataExplorerWidgetModel;
@Input()
dataLakeMeasure: DataLakeMeasure;
@Input()
editMode: boolean;
@Input()
dataViewMode = false;
@Input()
gridsterItemComponent: GridsterItemComponent;
@Input()
previewMode = false;
@Input()
gridMode = true;
@Input()
widgetIndex: number;
/**
* This is the date range (start, end) to view the data and is set in data-explorer.ts
*/
@Input()
timeSettings: TimeSettings;
@Input()
globalTimeEnabled = true;
@Output() deleteCallback: EventEmitter<number> = new EventEmitter<number>();
@Output() startEditModeEmitter: EventEmitter<DataExplorerWidgetModel> =
new EventEmitter<DataExplorerWidgetModel>();
title = '';
widgetLoaded = false;
timerActive = false;
loadingTime = 0;
hasDataExplorerWritePrivileges = false;
authSubscription: Subscription;
widgetTypeChangedSubscription: Subscription;
intervalSubscription: Subscription;
errorMessage: SpLogMessage;
componentRef: ComponentRef<BaseWidgetData<any>>;
@ViewChild(WidgetDirective, { static: true }) widgetHost!: WidgetDirective;
constructor(
private widgetRegistryService: DataExplorerWidgetRegistry,
private dashboardService: DataExplorerDashboardService,
private componentFactoryResolver: ComponentFactoryResolver,
private widgetTypeService: WidgetTypeService,
private authService: AuthService,
private currentUserService: CurrentUserService,
) {}
ngOnInit(): void {
this.authSubscription = this.currentUserService.user$.subscribe(
user => {
this.hasDataExplorerWritePrivileges = this.authService.hasRole(
UserPrivilege.PRIVILEGE_WRITE_DATA_EXPLORER_VIEW,
);
},
);
this.widgetLoaded = true;
this.title = this.dataLakeMeasure.measureName;
this.widgetTypeChangedSubscription =
this.widgetTypeService.widgetTypeChangeSubject.subscribe(
typeChange => {
if (
typeChange.widgetId === this.configuredWidget.elementId
) {
this.chooseWidget(typeChange.newWidgetTypeId);
}
},
);
this.chooseWidget(this.configuredWidget.widgetType);
}
ngOnDestroy() {
this.componentRef?.destroy();
this.authSubscription?.unsubscribe();
this.widgetTypeChangedSubscription?.unsubscribe();
}
chooseWidget(widgetTypeId: string) {
const widgetToDisplay =
this.widgetRegistryService.getWidgetTemplate(widgetTypeId);
this.loadComponent(widgetToDisplay.widgetComponent);
}
loadComponent(widgetToDisplay) {
const componentFactory =
this.componentFactoryResolver.resolveComponentFactory<
BaseWidgetData<any>
>(widgetToDisplay);
const viewContainerRef = this.widgetHost.viewContainerRef;
viewContainerRef.clear();
this.componentRef =
viewContainerRef.createComponent<BaseWidgetData<any>>(
componentFactory,
);
this.componentRef.instance.dataExplorerWidget = this.configuredWidget;
this.componentRef.instance.timeSettings = this.getTimeSettings();
this.componentRef.instance.gridsterItem = this.dashboardItem;
this.componentRef.instance.gridsterItemComponent =
this.gridsterItemComponent;
this.componentRef.instance.editMode = this.editMode;
this.componentRef.instance.dataViewDashboardItem = this.dashboardItem;
this.componentRef.instance.dataExplorerWidget = this.configuredWidget;
this.componentRef.instance.previewMode = this.previewMode;
this.componentRef.instance.gridMode = this.gridMode;
const removeSub =
this.componentRef.instance.removeWidgetCallback.subscribe(ev =>
this.removeWidget(),
);
const timerSub = this.componentRef.instance.timerCallback.subscribe(
ev => this.handleTimer(ev),
);
const errorSub = this.componentRef.instance.errorCallback.subscribe(
ev => (this.errorMessage = ev),
);
this.componentRef.onDestroy(destroy => {
this.componentRef.instance.cleanupSubscriptions();
removeSub?.unsubscribe();
timerSub?.unsubscribe();
errorSub?.unsubscribe();
});
}
getTimeSettings(): TimeSettings {
return this.globalTimeEnabled
? this.timeSettings
: (this.configuredWidget.timeSettings as TimeSettings);
}
removeWidget() {
this.deleteCallback.emit(this.widgetIndex);
}
startEditMode() {
this.startEditModeEmitter.emit(this.configuredWidget);
}
startLoadingTimer() {
this.timerActive = true;
this.intervalSubscription = interval(100)
.pipe(takeWhile(() => this.timerActive))
.subscribe(value => {
this.loadingTime = (value * 100) / 1000;
});
}
stopLoadingTimer() {
this.timerActive = false;
this.intervalSubscription.unsubscribe();
}
handleTimer(start: boolean) {
start ? this.startLoadingTimer() : this.stopLoadingTimer();
}
downloadDataAsFile(): void {
this.dashboardService.downloadDataAsFile(
this.timeSettings,
this.configuredWidget,
);
}
}