"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.EmbeddablePanel = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _lodash = require("lodash");
var _classnames = _interopRequireDefault(require("classnames"));
var _rxjs = require("rxjs");
var _react = _interopRequireWildcard(require("react"));
var _eui = require("@elastic/eui");
var _std = require("@kbn/std");
var _common = require("@kbn/data-plugin/common");
var _panel_actions = require("./panel_actions");
var _use_select_from_embeddable = require("./use_select_from_embeddable");
var _embeddable_panel_error = require("./embeddable_panel_error");
var _kibana_services = require("../kibana_services");
var _lib = require("../lib");
var _embeddable_panel_header = require("./panel_header/embeddable_panel_header");
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.
 */

const getEventStatus = output => {
  if (!(0, _lodash.isNil)(output.error)) {
    return 'error';
  } else if (output.rendered === true) {
    return 'rendered';
  } else if (output.loading === false) {
    return 'loaded';
  } else {
    return 'loading';
  }
};
const EmbeddablePanel = panelProps => {
  const {
    hideHeader,
    showShadow,
    embeddable,
    hideInspector,
    onPanelStatusChange
  } = panelProps;
  const [node, setNode] = (0, _react.useState)();
  const embeddableRoot = (0, _react.useMemo)(() => /*#__PURE__*/_react.default.createRef(), []);
  const headerId = (0, _react.useMemo)(() => (0, _eui.htmlIdGenerator)()(), []);
  const [outputError, setOutputError] = (0, _react.useState)();

  /**
   * Universal actions are exposed on the context menu for every embeddable, they
   * bypass the trigger registry.
   */
  const universalActions = (0, _react.useMemo)(() => {
    const commonlyUsedRanges = _kibana_services.core.uiSettings.get(_common.UI_SETTINGS.TIMEPICKER_QUICK_RANGES);
    const dateFormat = _kibana_services.core.uiSettings.get(_common.UI_SETTINGS.DATE_FORMAT);
    const stateTransfer = _kibana_services.embeddableStart.getStateTransfer();
    const editPanel = new _panel_actions.EditPanelAction(_kibana_services.embeddableStart.getEmbeddableFactory, _kibana_services.core.application, stateTransfer);
    const actions = {
      customizePanel: new _panel_actions.CustomizePanelAction(_kibana_services.core.overlays, _kibana_services.core.theme, editPanel, commonlyUsedRanges, dateFormat),
      removePanel: new _panel_actions.RemovePanelAction(),
      editPanel
    };
    if (!hideInspector) actions.inspectPanel = new _panel_actions.InspectPanelAction(_kibana_services.inspector);
    return actions;
  }, [hideInspector]);

  /**
   * Track panel status changes
   */
  (0, _react.useEffect)(() => {
    if (!onPanelStatusChange) return;
    let loadingStartTime = 0;
    const subscription = embeddable.getOutput$().pipe(
    // Map loaded event properties
    (0, _rxjs.map)(output => {
      if (output.loading === true) {
        loadingStartTime = performance.now();
      }
      return {
        id: embeddable.id,
        status: getEventStatus(output),
        error: output.error
      };
    }),
    // Dedupe
    (0, _rxjs.distinct)(output => loadingStartTime + output.id + output.status + !!output.error),
    // Map loaded event properties
    (0, _rxjs.map)(output => {
      return {
        ...output,
        timeToEvent: performance.now() - loadingStartTime
      };
    })).subscribe(statusOutput => {
      onPanelStatusChange(statusOutput);
    });
    return () => subscription === null || subscription === void 0 ? void 0 : subscription.unsubscribe();

    // Panel status change subscription should only be run on mount.
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  /**
   * Select state from the embeddable
   */
  const loading = (0, _use_select_from_embeddable.useSelectFromEmbeddableOutput)('loading', embeddable);
  const viewMode = (0, _use_select_from_embeddable.useSelectFromEmbeddableInput)('viewMode', embeddable);

  /**
   * Render embeddable into ref, set up error subscription
   */
  (0, _react.useEffect)(() => {
    var _embeddable$render;
    if (!embeddableRoot.current) return;
    const nextNode = (_embeddable$render = embeddable.render(embeddableRoot.current)) !== null && _embeddable$render !== void 0 ? _embeddable$render : undefined;
    if ((0, _std.isPromise)(nextNode)) {
      nextNode.then(resolved => setNode(resolved));
    } else {
      setNode(nextNode);
    }
    const errorSubscription = embeddable.getOutput$().subscribe({
      next: output => {
        setOutputError(output.error);
      },
      error: error => setOutputError(error)
    });
    return () => {
      embeddable === null || embeddable === void 0 ? void 0 : embeddable.destroy();
      errorSubscription === null || errorSubscription === void 0 ? void 0 : errorSubscription.unsubscribe();
    };
  }, [embeddable, embeddableRoot]);
  const classes = (0, _react.useMemo)(() => (0, _classnames.default)('embPanel', {
    'embPanel--editing': viewMode !== _lib.ViewMode.VIEW,
    'embPanel--loading': loading
  }), [viewMode, loading]);
  const contentAttrs = (0, _react.useMemo)(() => {
    const attrs = {};
    if (loading) attrs['data-loading'] = true;
    if (outputError) attrs['data-error'] = true;
    return attrs;
  }, [loading, outputError]);
  return /*#__PURE__*/_react.default.createElement(_eui.EuiPanel, {
    role: "figure",
    paddingSize: "none",
    className: classes,
    hasShadow: showShadow,
    "aria-labelledby": headerId,
    "data-test-subj": "embeddablePanel",
    "data-test-embeddable-id": embeddable.id
  }, !hideHeader && /*#__PURE__*/_react.default.createElement(_embeddable_panel_header.EmbeddablePanelHeader, (0, _extends2.default)({}, panelProps, {
    headerId: headerId,
    universalActions: universalActions
  })), outputError && /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, {
    alignItems: "center",
    className: "eui-fullHeight embPanel__error",
    "data-test-subj": "embeddableError",
    justifyContent: "center"
  }, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, null, /*#__PURE__*/_react.default.createElement(_lib.EmbeddableErrorHandler, {
    embeddable: embeddable,
    error: outputError
  }, error => /*#__PURE__*/_react.default.createElement(_embeddable_panel_error.EmbeddablePanelError, {
    editPanelAction: universalActions.editPanel,
    embeddable: embeddable,
    error: error
  })))), /*#__PURE__*/_react.default.createElement("div", (0, _extends2.default)({
    className: "embPanel__content",
    ref: embeddableRoot
  }, contentAttrs), node));
};
exports.EmbeddablePanel = EmbeddablePanel;