"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EmbeddableRenderer = void 0; exports.useEmbeddableFactory = useEmbeddableFactory; var _react = _interopRequireWildcard(require("react")); var _embeddable_root = require("./embeddable_root"); var _error_embeddable = require("./error_embeddable"); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /* * 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 and the Server Side Public License, v 1; you may not use this file except * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ function isWithFactory(props) { return 'factory' in props; } function useEmbeddableFactory({ input, factory, onInputUpdated }) { const [embeddable, setEmbeddable] = (0, _react.useState)(undefined); const [loading, setLoading] = (0, _react.useState)(false); const [error, setError] = (0, _react.useState)(); const latestInput = _react.default.useRef(input); (0, _react.useEffect)(() => { latestInput.current = input; }, [input]); (0, _react.useEffect)(() => { let canceled = false; // keeping track of embeddables created by this component to be able to destroy them let createdEmbeddableRef; setEmbeddable(undefined); setLoading(true); factory.create(latestInput.current).then(createdEmbeddable => { if (canceled) { if (createdEmbeddable) { createdEmbeddable.destroy(); } } else { createdEmbeddableRef = createdEmbeddable; setEmbeddable(createdEmbeddable); } }).catch(err => { if (canceled) return; setError(err === null || err === void 0 ? void 0 : err.message); }).finally(() => { if (canceled) return; setLoading(false); }); return () => { canceled = true; if (createdEmbeddableRef) { createdEmbeddableRef.destroy(); } }; }, [factory]); (0, _react.useEffect)(() => { if (!embeddable) return; if ((0, _error_embeddable.isErrorEmbeddable)(embeddable)) return; if (!onInputUpdated) return; const sub = embeddable.getInput$().subscribe(newInput => { onInputUpdated(newInput); }); return () => { sub.unsubscribe(); }; }, [embeddable, onInputUpdated]); return [embeddable, loading, error]; } /** * Helper react component to render an embeddable * Can be used if you have an embeddable object or an embeddable factory * Supports updating input by passing `input` prop * * @remarks * This component shouldn't be used inside an embeddable container to render embeddable children * because children may lose inherited input, here is why: * * When passing `input` inside a prop, internally there is a call: * * ```ts * embeddable.updateInput(input); * ``` * If you are simply rendering an embeddable, it's no problem. * * However when you are dealing with containers, * you want to be sure to only pass into updateInput the actual state that changed. * This is because calling child.updateInput({ foo }) will make foo explicit state. * It cannot be inherited from it's parent. * * For example, on a dashboard, the time range is inherited by all children, * unless they had their time range set explicitly. * This is how "per panel time range" works. * That action calls embeddable.updateInput({ timeRange }), * and the time range will no longer be inherited from the container. * * see: https://github.com/elastic/kibana/pull/67783#discussion_r435447657 for more details. * refer to: examples/embeddable_explorer for examples with correct usage of this component. * * @public * @param props - {@link EmbeddableRendererProps} */ const EmbeddableRenderer = props => { if (isWithFactory(props)) { return /*#__PURE__*/_react.default.createElement(EmbeddableByFactory, props); } return /*#__PURE__*/_react.default.createElement(_embeddable_root.EmbeddableRoot, { embeddable: props.embeddable, input: props.input }); }; // exports.EmbeddableRenderer = EmbeddableRenderer; const EmbeddableByFactory = ({ factory, input, onInputUpdated }) => { const [embeddable, loading, error] = useEmbeddableFactory({ factory, input, onInputUpdated }); return /*#__PURE__*/_react.default.createElement(_embeddable_root.EmbeddableRoot, { embeddable: embeddable, loading: loading, error: error, input: input }); };