"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.annotationsRefreshed = exports.annotationsRefresh$ = exports.annotation$ = exports.AnnotationUpdatesService = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _rxjs = require("rxjs"); var _operators = require("rxjs/operators"); /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ /* This observable offers a way to share state between components that don't have a direct parent -> * -> child relationship. It's also useful in mixed React environments. For example, we want to trigger the flyout for editing annotations from both the timeseries_chart and the annotations_table. Since we don't want two flyout instances, we cannot simply add the flyout component as a child to each of the other two components. The directive/component/DOM structure may look somewhat like this: -> / --> \ -> In this mixed angular/react environment, we want the siblings (chart, table and flyout) to be able to communicate with each other. The observable can be used as follows to achieve this: - To trigger an update, use `annotation$.next()` - To reset the currently editable annotation, use `annotation$.next(null)` There are two ways to deal with updates of the observable: 1. Inline subscription in an existing component. This requires the component to be a class component and manage its own state. - To react to an update, use `annotation$.subscribe(annotation => { })`. - To add it to a given components state, just use `annotation$.subscribe(annotation => this.setState({ annotation }));` in `componentDidMount()`. 2. useObservable() from 'react-use', offers a way to wrap observables into another component which passes on updated values as props. - To subscribe to updates this way, wrap your component like: const MyOriginalComponent = ({ annotation }) => { // don't render if the annotation isn't set if (annotation === null) { return null; } return {annotation.annotation}; } export const MyObservableComponent = (props) => { const annotationProp = useObservable(annotation$); if (annotationProp === undefined) { return null; } return ; }; */ const annotation$ = new _rxjs.BehaviorSubject(null); /* This observable provides a way to trigger a reload of annotations based on a given event. Instead of passing around callbacks or deeply nested props, it can be imported in React components. */ exports.annotation$ = annotation$; const annotationsRefresh$ = new _rxjs.BehaviorSubject(Date.now()); exports.annotationsRefresh$ = annotationsRefresh$; const annotationsRefreshed = () => annotationsRefresh$.next(Date.now()); exports.annotationsRefreshed = annotationsRefreshed; class AnnotationUpdatesService { constructor() { (0, _defineProperty2.default)(this, "_annotation$", new _rxjs.BehaviorSubject(null)); } update$() { return this._annotation$.asObservable(); } isAnnotationInitialized$() { return this._annotation$.asObservable().pipe((0, _operators.distinctUntilChanged)((prev, curr) => { // prevent re-rendering return prev !== null && curr !== null; })); } setValue(annotation) { this._annotation$.next(annotation); } } exports.AnnotationUpdatesService = AnnotationUpdatesService;