import isNull from 'lodash/isNull'; import isUndefined from 'lodash/isUndefined'; import React from 'react'; import {DashboardsContext} from '../context'; import {ServiceState, lookupService} from '../lib'; export class ServiceContainer extends React.Component { constructor (props) { super(props); this.serviceUnsubscribe = null; this.state = { serviceState: null, showSettingsModal: false, nextCharacteristics: null, }; } service = () => { return lookupService( this.context.dashboards, this.props.kind, this.props.instance ); } setServiceState = (payload, {reset}) => { let nextServiceState = null; if (reset || isNull(this.state.serviceState)) { nextServiceState = new ServiceState(payload); } else { nextServiceState = this.state.serviceState.update(payload); } this.setState({serviceState: nextServiceState}); } setNextCharacteristics = (nextCharacteristics) => { this.setState({nextCharacteristics: nextCharacteristics}); } setNextCharacteristicsFromService = (fromService) => { let nextCharacteristics = null; if (fromService && this.service().widgetComponent && !fromService.isDummy()) { nextCharacteristics = {...fromService.characteristics}; } this.setState({nextCharacteristics: nextCharacteristics}); } showHideSettingsModal = (show) => { if (show) { this.setNextCharacteristicsFromService(this.service()); } else { this.setNextCharacteristicsFromService(null); } this.setState({showSettingsModal: show}); } onSettingsButtonClick = () => { this.showHideSettingsModal(true); } onSettingsModalClose = () => { this.showHideSettingsModal(false); } onSettingsModalSaveButtonClick = () => { this.context.saveServiceCharacteristics( this.props.kind, this.props.instance, this.state.nextCharacteristics ); this.onSettingsModalClose(); } onSettingsModalNukeButtonClick = () => { this.context.nukeService(this.props.kind, this.props.instance); this.onSettingsModalClose(); } onAppearancePopupColorChange = (color) => { const currentCharacteristics = this.service().characteristics; this.context.saveServiceCharacteristics( this.props.kind, this.props.instance, { ...currentCharacteristics, appearance: { ...(currentCharacteristics.appearance || {}), color: color, }, } ); } onServiceRestartButtonClick = () => { this.service().restart(); } unsubscribeIfNeeded = () => { if (!isNull(this.serviceUnsubscribe)) { this.serviceUnsubscribe(); } } componentDidMount () { const service = this.service(); if (service && service.widgetComponent && !service.isDummy()) { this.setServiceState(service.initialState(), true); service.start(); this.unsubscribeIfNeeded(); this.serviceUnsubscribe = service.subscribe(this.setServiceState); } } componentWillUnmount () { this.unsubscribeIfNeeded(); } render () { const WidgetComponent = this.service().widgetComponent; const hasSettingsView = Boolean( !this.service().isDummy() && WidgetComponent && !isUndefined(WidgetComponent.settingsView) ); const settingsViewProps = { kind: this.props.kind, instance: this.props.instance, nextCharacteristics: this.state.nextCharacteristics, setNextCharacteristics: this.setNextCharacteristics, }; return this.props.children({ hasSettingsView: hasSettingsView, service: this.service(), serviceState: this.state.serviceState, setServiceState: this.setServiceState, settingsViewProps: settingsViewProps, showSettingsModal: this.state.showSettingsModal, onAppearancePopupColorChange: this.onAppearancePopupColorChange, onServiceRestartButtonClick: this.onServiceRestartButtonClick, onSettingsButtonClick: this.onSettingsButtonClick, onSettingsModalClose: this.onSettingsModalClose, onSettingsModalNukeButtonClick: this.onSettingsModalNukeButtonClick, onSettingsModalSaveButtonClick: this.onSettingsModalSaveButtonClick, }); } } ServiceContainer.contextType = DashboardsContext;