"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.Embeddable = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _lodash = require("lodash"); var _react = _interopRequireDefault(require("react")); var _react2 = require("@emotion/react"); var _i18n = require("@kbn/i18n"); var _reactDom = require("react-dom"); var _esQuery = require("@kbn/es-query"); var _public = require("@kbn/data-plugin/public"); var _rxjs = require("rxjs"); var _interpreter = require("@kbn/interpreter"); var _operators = require("rxjs/operators"); var _fastDeepEqual = _interopRequireDefault(require("fast-deep-equal")); var _public2 = require("@kbn/kibana-react-plugin/public"); var _public3 = require("@kbn/visualizations-plugin/public"); var _public4 = require("@kbn/embeddable-plugin/public"); var _i18nReact = require("@kbn/i18n-react"); var _eui = require("@elastic/eui"); var _lens_ui_telemetry = require("../lens_ui_telemetry"); var _expression_wrapper = require("./expression_wrapper"); var _types = require("../types"); var _constants = require("../../common/constants"); var _lens_inspector_service = require("../lens_inspector_service"); var _utils = require("../utils"); var _show_underlying_data = require("../app_plugin/show_underlying_data"); var _get_application_user_messages = require("../app_plugin/get_application_user_messages"); var _message_list = require("../editor_frame_service/editor_frame/workspace_panel/message_list"); var _embeddable_info_badges = require("./embeddable_info_badges"); var _utils2 = require("../state_management/utils"); 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; } function VisualizationErrorPanel({ errors, canEdit }) { const showMore = errors.length > 1; const canFixInLens = canEdit && errors.some(({ fixableInEditor }) => fixableInEditor); return /*#__PURE__*/_react.default.createElement("div", { className: "lnsEmbeddedError" }, /*#__PURE__*/_react.default.createElement(_eui.EuiEmptyPrompt, { iconType: "warning", iconColor: "danger", "data-test-subj": "embeddable-lens-failure", body: /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, errors.length ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("p", null, errors[0].longMessage), showMore && !canFixInLens ? /*#__PURE__*/_react.default.createElement("p", null, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.lens.embeddable.moreErrors", defaultMessage: "Edit in Lens editor to see more errors" })) : null, canFixInLens ? /*#__PURE__*/_react.default.createElement("p", null, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.lens.embeddable.fixErrors", defaultMessage: "Edit in Lens editor to fix the error" })) : null) : /*#__PURE__*/_react.default.createElement("p", null, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.lens.embeddable.failure", defaultMessage: "Visualization couldn't be displayed" }))) })); } const getExpressionFromDocument = async (document, documentToExpression) => { const { ast, indexPatterns, indexPatternRefs, activeVisualizationState } = await documentToExpression(document); return { ast: ast ? (0, _interpreter.toExpression)(ast) : null, indexPatterns, indexPatternRefs, activeVisualizationState }; }; function getViewUnderlyingDataArgs({ activeDatasource, activeDatasourceState, activeVisualization, activeVisualizationState, activeData, dataViews, capabilities, query, filters, timeRange, esQueryConfig, indexPatternsCache }) { const { error, meta } = (0, _show_underlying_data.getLayerMetaInfo)(activeDatasource, activeDatasourceState, activeVisualization, activeVisualizationState, activeData, indexPatternsCache, timeRange, capabilities); if (error || !meta) { return; } const luceneOrKuery = []; const aggregateQuery = []; if (Array.isArray(query)) { query.forEach(q => { if ((0, _esQuery.isOfQueryType)(q)) { luceneOrKuery.push(q); } else { aggregateQuery.push(q); } }); } const { filters: newFilters, query: newQuery } = (0, _show_underlying_data.combineQueryAndFilters)(luceneOrKuery.length > 0 ? luceneOrKuery : query, filters, meta, dataViews, esQueryConfig); const dataViewSpec = indexPatternsCache[meta.id].spec; return { dataViewSpec, timeRange, filters: newFilters, query: aggregateQuery.length > 0 ? aggregateQuery[0] : newQuery, columns: meta.columns }; } const EmbeddableMessagesPopover = ({ messages }) => { const { euiTheme } = (0, _eui.useEuiTheme)(); const xsFontSize = (0, _eui.useEuiFontSize)('xs').fontSize; if (!messages.length) { return null; } return /*#__PURE__*/_react.default.createElement(_message_list.MessageList, { messages: messages, customButtonStyles: (0, _react2.css)` block-size: ${euiTheme.size.l}; font-size: ${xsFontSize}; padding: 0 ${euiTheme.size.xs}; & > * { gap: ${euiTheme.size.xs}; } ` }); }; const blockingMessageDisplayLocations = ['visualization', 'visualizationOnEmbeddable']; const MessagesBadge = ({ onMount }) => /*#__PURE__*/_react.default.createElement("div", { css: (0, _react2.css)({ position: 'absolute', zIndex: 2, left: 0, bottom: 0 }), ref: el => { if (el) { onMount(el); } } }); class Embeddable extends _public4.Embeddable { logError(type) { (0, _lens_ui_telemetry.trackUiCounterEvents)(type === 'runtime' ? 'embeddable_runtime_error' : 'embeddable_validation_error', this.getExecutionContext()); } constructor(deps, initialInput, parent) { super(initialInput, { editApp: 'lens' }, parent); (0, _defineProperty2.default)(this, "type", _constants.DOC_TYPE); (0, _defineProperty2.default)(this, "deferEmbeddableLoad", true); (0, _defineProperty2.default)(this, "expressionRenderer", void 0); (0, _defineProperty2.default)(this, "savedVis", void 0); (0, _defineProperty2.default)(this, "expression", void 0); (0, _defineProperty2.default)(this, "domNode", void 0); (0, _defineProperty2.default)(this, "isInitialized", false); (0, _defineProperty2.default)(this, "inputReloadSubscriptions", void 0); (0, _defineProperty2.default)(this, "isDestroyed", void 0); (0, _defineProperty2.default)(this, "lensInspector", void 0); (0, _defineProperty2.default)(this, "activeData", void 0); (0, _defineProperty2.default)(this, "dataViews", []); (0, _defineProperty2.default)(this, "viewUnderlyingDataArgs", void 0); (0, _defineProperty2.default)(this, "activeVisualizationState", void 0); (0, _defineProperty2.default)(this, "indexPatterns", {}); (0, _defineProperty2.default)(this, "indexPatternRefs", []); (0, _defineProperty2.default)(this, "fullAttributes", void 0); (0, _defineProperty2.default)(this, "getUserMessages", (locationId, filters) => { return (0, _get_application_user_messages.filterAndSortUserMessages)([...this._userMessages, ...Object.values(this.additionalUserMessages)], locationId, filters !== null && filters !== void 0 ? filters : {}); }); (0, _defineProperty2.default)(this, "_userMessages", []); (0, _defineProperty2.default)(this, "additionalUserMessages", {}); // used to add warnings and errors from elsewhere in the embeddable (0, _defineProperty2.default)(this, "addUserMessages", messages => { const newMessageMap = { ...this.additionalUserMessages }; const addedMessageIds = []; messages.forEach(message => { if (!newMessageMap[message.uniqueId]) { addedMessageIds.push(message.uniqueId); newMessageMap[message.uniqueId] = message; } }); if (addedMessageIds.length) { this.additionalUserMessages = newMessageMap; this.renderUserMessages(); } return () => { messages.forEach(({ uniqueId }) => { delete this.additionalUserMessages[uniqueId]; }); }; }); (0, _defineProperty2.default)(this, "removeActiveDataWarningMessages", () => {}); (0, _defineProperty2.default)(this, "updateActiveData", (data, adapters) => { var _adapters$tables; if (this.input.onLoad) { // once onData$ is get's called from expression renderer, loading becomes false this.input.onLoad(false, adapters); } const { type, error } = data; this.updateOutput({ loading: false, error: type === 'error' ? error : undefined }); const newActiveData = adapters === null || adapters === void 0 ? void 0 : (_adapters$tables = adapters.tables) === null || _adapters$tables === void 0 ? void 0 : _adapters$tables.tables; this.removeActiveDataWarningMessages(); const searchWarningMessages = this.getSearchWarningMessages(adapters); this.removeActiveDataWarningMessages = this.addUserMessages(searchWarningMessages.filter(_types.isMessageRemovable)); this.activeData = newActiveData; // Refresh messanges if info type is found as with active data // these messages can be enriched if (this._userMessages.some(({ severity }) => severity === 'info')) { this.loadUserMessages(); this.renderUserMessages(); } }); (0, _defineProperty2.default)(this, "onRender", () => { var _this$savedVis; let datasourceEvents = []; let visualizationEvents = []; if (this.savedVis) { datasourceEvents = Object.values(this.deps.datasourceMap).reduce((acc, datasource) => { var _datasource$getRender, _datasource$getRender2; return [...acc, ...((_datasource$getRender = (_datasource$getRender2 = datasource.getRenderEventCounters) === null || _datasource$getRender2 === void 0 ? void 0 : _datasource$getRender2.call(datasource, this.savedVis.state.datasourceStates[datasource.id])) !== null && _datasource$getRender !== void 0 ? _datasource$getRender : [])]; }, []); if (this.savedVis.visualizationType) { var _this$deps$visualizat, _this$deps$visualizat2, _this$deps$visualizat3; visualizationEvents = (_this$deps$visualizat = (_this$deps$visualizat2 = (_this$deps$visualizat3 = this.deps.visualizationMap[this.savedVis.visualizationType]).getRenderEventCounters) === null || _this$deps$visualizat2 === void 0 ? void 0 : _this$deps$visualizat2.call(_this$deps$visualizat3, this.savedVis.state.visualization)) !== null && _this$deps$visualizat !== void 0 ? _this$deps$visualizat : []; } } const executionContext = this.getExecutionContext(); const events = [...datasourceEvents, ...visualizationEvents, ...(0, _lens_ui_telemetry.getExecutionContextEvents)(executionContext)]; const adHocDataViews = Object.values(((_this$savedVis = this.savedVis) === null || _this$savedVis === void 0 ? void 0 : _this$savedVis.state.adHocDataViews) || {}); adHocDataViews.forEach(() => { events.push('ad_hoc_data_view'); }); (0, _lens_ui_telemetry.trackUiCounterEvents)(events, executionContext); this.renderComplete.dispatchComplete(); this.updateOutput({ ...this.getOutput(), rendered: true }); }); (0, _defineProperty2.default)(this, "badgeDomNode", void 0); /** * This method is called on every render, and also whenever the badges dom node is created * That happens after either the expression renderer or the visualization error panel is rendered. * * You should not call this method on its own. Use renderUserMessages instead. */ (0, _defineProperty2.default)(this, "renderBadgeMessages", () => { const messages = this.getUserMessages('embeddableBadge'); const [warningOrErrorMessages, infoMessages] = (0, _lodash.partition)(messages, ({ severity }) => severity !== 'info'); if (this.badgeDomNode) { (0, _reactDom.render)( /*#__PURE__*/_react.default.createElement(_public2.KibanaThemeProvider, { theme$: this.deps.theme.theme$ }, /*#__PURE__*/_react.default.createElement(EmbeddableMessagesPopover, { messages: warningOrErrorMessages }), /*#__PURE__*/_react.default.createElement(_embeddable_info_badges.EmbeddableFeatureBadge, { messages: infoMessages })), this.badgeDomNode); } }); (0, _defineProperty2.default)(this, "hasCompatibleActions", async event => { if ((0, _types.isLensTableRowContextMenuClickEvent)(event) || (0, _types.isLensMultiFilterEvent)(event) || (0, _types.isLensFilterEvent)(event)) { const { getTriggerCompatibleActions } = this.deps; if (!getTriggerCompatibleActions) { return false; } const actions = await getTriggerCompatibleActions(_public3.VIS_EVENT_TO_TRIGGER[event.name], { data: event.data, embeddable: this }); return actions.length > 0; } return false; }); (0, _defineProperty2.default)(this, "getCompatibleCellValueActions", async data => { const { getTriggerCompatibleActions } = this.deps; if (getTriggerCompatibleActions) { const embeddable = this; const actions = await getTriggerCompatibleActions(_public4.CELL_VALUE_TRIGGER, { data, embeddable }); return actions.sort((a, b) => { var _a$order, _b$order; return ((_a$order = a.order) !== null && _a$order !== void 0 ? _a$order : Infinity) - ((_b$order = b.order) !== null && _b$order !== void 0 ? _b$order : Infinity); }).map(action => ({ id: action.id, iconType: action.getIconType({ embeddable, data, trigger: _public4.cellValueTrigger }), displayName: action.getDisplayName({ embeddable, data, trigger: _public4.cellValueTrigger }), execute: cellData => action.execute({ embeddable, data: cellData, trigger: _public4.cellValueTrigger }) })); } return []; }); (0, _defineProperty2.default)(this, "handleEvent", async event => { var _eventHandler; if (!this.deps.getTrigger || this.input.disableTriggers) { return; } let eventHandler; let shouldExecuteDefaultTriggers = true; if ((0, _types.isLensBrushEvent)(event)) { eventHandler = this.input.onBrushEnd; } else if ((0, _types.isLensFilterEvent)(event) || (0, _types.isLensMultiFilterEvent)(event)) { eventHandler = this.input.onFilter; } else if ((0, _types.isLensTableRowContextMenuClickEvent)(event)) { eventHandler = this.input.onTableRowClick; } (_eventHandler = eventHandler) === null || _eventHandler === void 0 ? void 0 : _eventHandler({ ...event.data, preventDefault: () => { shouldExecuteDefaultTriggers = false; } }); if ((0, _types.isLensFilterEvent)(event) || (0, _types.isLensMultiFilterEvent)(event) || (0, _types.isLensBrushEvent)(event)) { if (shouldExecuteDefaultTriggers) { this.deps.getTrigger(_public3.VIS_EVENT_TO_TRIGGER[event.name]).exec({ data: { ...event.data, timeFieldName: event.data.timeFieldName || (0, _utils.inferTimeField)(this.deps.data.datatableUtilities, event) }, embeddable: this }); } } if ((0, _types.isLensTableRowContextMenuClickEvent)(event)) { if (shouldExecuteDefaultTriggers) { this.deps.getTrigger(_public3.VIS_EVENT_TO_TRIGGER[event.name]).exec({ data: event.data, embeddable: this }, true); } } // We allow for edit actions in the Embeddable for display purposes only (e.g. changing the datatable sort order). // No state changes made here with an edit action are persisted. if ((0, _types.isLensEditEvent)(event) && this.onEditAction) { if (!this.savedVis) return; // have to dance since this.savedVis.state is readonly const newVis = JSON.parse(JSON.stringify(this.savedVis)); newVis.state.visualization = this.onEditAction(newVis.state.visualization, event); this.savedVis = newVis; const { ast } = await getExpressionFromDocument(this.savedVis, this.deps.documentToExpression); this.expression = ast; this.loadUserMessages(); this.reload(); } }); (0, _defineProperty2.default)(this, "inputIsRefType", input => { return this.deps.attributeService.inputIsRefType(input); }); (0, _defineProperty2.default)(this, "getInputAsRefType", async () => { return this.deps.attributeService.getInputAsRefType(this.getExplicitInput(), { showSaveModal: true, saveModalTitle: this.getTitle() }); }); (0, _defineProperty2.default)(this, "getInputAsValueType", async () => { return this.deps.attributeService.getInputAsValueType(this.getExplicitInput()); }); this.deps = deps; this.lensInspector = (0, _lens_inspector_service.getLensInspectorService)(deps.inspector); this.expressionRenderer = deps.expressionRenderer; this.initializeSavedVis(initialInput).then(() => { this.loadUserMessages(); this.reload(); }).catch(e => this.onFatalError(e)); const input$ = this.getInput$(); this.inputReloadSubscriptions = []; // Lens embeddable does not re-render when embeddable input changes in // general, to improve performance. This line makes sure the Lens embeddable // re-renders when anything in ".dynamicActions" (e.g. drilldowns) changes. this.inputReloadSubscriptions.push(input$.pipe((0, _operators.map)(input => { var _input$enhancements; return (_input$enhancements = input.enhancements) === null || _input$enhancements === void 0 ? void 0 : _input$enhancements.dynamicActions; }), (0, _operators.distinctUntilChanged)((a, b) => (0, _fastDeepEqual.default)(a, b)), (0, _operators.skip)(1)).subscribe(input => { this.reload(); })); // Lens embeddable does not re-render when embeddable input changes in // general, to improve performance. This line makes sure the Lens embeddable // re-renders when dashboard view mode switches between "view/edit". This is // needed to see the changes to ".dynamicActions" (e.g. drilldowns) when // dashboard's mode is toggled. this.inputReloadSubscriptions.push(input$.pipe((0, _operators.map)(input => input.viewMode), (0, _operators.distinctUntilChanged)(), (0, _operators.skip)(1)).subscribe(input => { var _this$getInput$enhanc; // only reload if drilldowns are set if ((_this$getInput$enhanc = this.getInput().enhancements) !== null && _this$getInput$enhanc !== void 0 && _this$getInput$enhanc.dynamicActions) { this.reload(); } })); // Use a trigger to distinguish between observables in the subscription const withTrigger = trigger => (0, _operators.map)(input => ({ trigger, input })); // Re-initialize the visualization if either the attributes or the saved object id changes const attributesOrSavedObjectId$ = input$.pipe((0, _operators.distinctUntilChanged)((a, b) => (0, _fastDeepEqual.default)(['attributes' in a && a.attributes, 'savedObjectId' in a && a.savedObjectId, 'overrides' in a && a.overrides, 'disableTriggers' in a && a.disableTriggers], ['attributes' in b && b.attributes, 'savedObjectId' in b && b.savedObjectId, 'overrides' in b && b.overrides, 'disableTriggers' in b && b.disableTriggers])), (0, _operators.skip)(1), withTrigger('attributesOrSavedObjectId')); // Update search context and reload on changes related to search const searchContext$ = (0, _public4.shouldFetch$)(input$, () => this.getInput()).pipe(withTrigger('searchContext')); // Merge and debounce the observables to avoid multiple reloads this.inputReloadSubscriptions.push((0, _rxjs.merge)(searchContext$, attributesOrSavedObjectId$).pipe((0, _operators.debounceTime)(0)).subscribe(async ({ trigger, input }) => { if (trigger === 'attributesOrSavedObjectId') { await this.initializeSavedVis(input); } // reset removable messages // Dashboard search/context changes are detected here this.additionalUserMessages = {}; this.reload(); })); } get activeDatasourceId() { return (0, _utils.getActiveDatasourceIdFromDoc)(this.savedVis); } get activeDatasource() { if (!this.activeDatasourceId) return; return this.deps.datasourceMap[this.activeDatasourceId]; } get activeVisualizationId() { return (0, _utils.getActiveVisualizationIdFromDoc)(this.savedVis); } get activeVisualization() { if (!this.activeVisualizationId) return; return this.deps.visualizationMap[this.activeVisualizationId]; } // TODO - consider getting this from the persistedStateToExpression function // where it is already computed get activeDatasourceState() { var _this$savedVis2, _this$savedVis3, _this$savedVis4; if (!this.activeDatasourceId || !this.activeDatasource) return; const docDatasourceState = (_this$savedVis2 = this.savedVis) === null || _this$savedVis2 === void 0 ? void 0 : _this$savedVis2.state.datasourceStates[this.activeDatasourceId]; return this.activeDatasource.initialize(docDatasourceState, [...(((_this$savedVis3 = this.savedVis) === null || _this$savedVis3 === void 0 ? void 0 : _this$savedVis3.references) || []), ...(((_this$savedVis4 = this.savedVis) === null || _this$savedVis4 === void 0 ? void 0 : _this$savedVis4.state.internalReferences) || [])], undefined, undefined, this.indexPatterns); } // loads all available user messages loadUserMessages() { var _this$savedVis5, _mergedSearchContext$, _mergedSearchContext$2, _mergedSearchContext$3, _mergedSearchContext$4, _mergedSearchContext$5, _this$activeDatasourc, _this$activeDatasourc2, _this$activeVisualiza, _this$activeVisualiza2, _this$activeVisualiza3, _this$activeVisualiza4, _this$activeVisualiza5; const userMessages = []; userMessages.push(...(0, _get_application_user_messages.getApplicationUserMessages)({ visualizationType: (_this$savedVis5 = this.savedVis) === null || _this$savedVis5 === void 0 ? void 0 : _this$savedVis5.visualizationType, visualization: { state: this.activeVisualizationState, activeId: this.activeVisualizationId }, visualizationMap: this.deps.visualizationMap, activeDatasource: this.activeDatasource, activeDatasourceState: { isLoading: !this.activeDatasourceState, state: this.activeDatasourceState }, dataViews: { indexPatterns: this.indexPatterns, indexPatternRefs: this.indexPatternRefs // TODO - are these actually used? }, core: this.deps.coreStart })); if (!this.savedVis) { return userMessages; } const mergedSearchContext = this.getMergedSearchContext(); const frameDatasourceAPI = { dataViews: { indexPatterns: this.indexPatterns, indexPatternRefs: this.indexPatternRefs }, datasourceLayers: (0, _utils2.getDatasourceLayers)({ [this.activeDatasourceId]: { isLoading: !this.activeDatasourceState, state: this.activeDatasourceState } }, this.deps.datasourceMap, this.indexPatterns), query: this.savedVis.state.query, filters: (_mergedSearchContext$ = mergedSearchContext.filters) !== null && _mergedSearchContext$ !== void 0 ? _mergedSearchContext$ : [], dateRange: { fromDate: (_mergedSearchContext$2 = (_mergedSearchContext$3 = mergedSearchContext.timeRange) === null || _mergedSearchContext$3 === void 0 ? void 0 : _mergedSearchContext$3.from) !== null && _mergedSearchContext$2 !== void 0 ? _mergedSearchContext$2 : '', toDate: (_mergedSearchContext$4 = (_mergedSearchContext$5 = mergedSearchContext.timeRange) === null || _mergedSearchContext$5 === void 0 ? void 0 : _mergedSearchContext$5.to) !== null && _mergedSearchContext$4 !== void 0 ? _mergedSearchContext$4 : '' }, activeData: this.activeData }; userMessages.push(...((_this$activeDatasourc = (_this$activeDatasourc2 = this.activeDatasource) === null || _this$activeDatasourc2 === void 0 ? void 0 : _this$activeDatasourc2.getUserMessages(this.activeDatasourceState, { setState: () => {}, frame: frameDatasourceAPI, visualizationInfo: (_this$activeVisualiza = this.activeVisualization) === null || _this$activeVisualiza === void 0 ? void 0 : (_this$activeVisualiza2 = _this$activeVisualiza.getVisualizationInfo) === null || _this$activeVisualiza2 === void 0 ? void 0 : _this$activeVisualiza2.call(_this$activeVisualiza, this.activeVisualizationState, frameDatasourceAPI) })) !== null && _this$activeDatasourc !== void 0 ? _this$activeDatasourc : []), ...((_this$activeVisualiza3 = (_this$activeVisualiza4 = this.activeVisualization) === null || _this$activeVisualiza4 === void 0 ? void 0 : (_this$activeVisualiza5 = _this$activeVisualiza4.getUserMessages) === null || _this$activeVisualiza5 === void 0 ? void 0 : _this$activeVisualiza5.call(_this$activeVisualiza4, this.activeVisualizationState, { frame: frameDatasourceAPI })) !== null && _this$activeVisualiza3 !== void 0 ? _this$activeVisualiza3 : [])); this._userMessages = userMessages; } reportsEmbeddableLoad() { return true; } supportedTriggers() { var _this$deps$visualizat4; if (!this.savedVis || !this.savedVis.visualizationType) { return []; } return ((_this$deps$visualizat4 = this.deps.visualizationMap[this.savedVis.visualizationType]) === null || _this$deps$visualizat4 === void 0 ? void 0 : _this$deps$visualizat4.triggers) || []; } getInspectorAdapters() { return this.lensInspector.adapters; } getFullAttributes() { return this.fullAttributes; } isTextBasedLanguage() { if (!this.savedVis) { return; } const query = this.savedVis.state.query; return !(0, _esQuery.isOfQueryType)(query); } getTextBasedLanguage() { var _this$savedVis6, _this$savedVis7; if (!this.isTextBasedLanguage() || !((_this$savedVis6 = this.savedVis) !== null && _this$savedVis6 !== void 0 && _this$savedVis6.state.query)) { return; } const query = (_this$savedVis7 = this.savedVis) === null || _this$savedVis7 === void 0 ? void 0 : _this$savedVis7.state.query; const language = (0, _esQuery.getAggregateQueryMode)(query); return String(language).toUpperCase(); } async updateVisualization(datasourceState, visualizationState) { var _this$activeDatasourc3; const viz = this.savedVis; const activeDatasourceId = (_this$activeDatasourc3 = this.activeDatasourceId) !== null && _this$activeDatasourc3 !== void 0 ? _this$activeDatasourc3 : 'formBased'; if (viz !== null && viz !== void 0 && viz.state) { const datasourceStates = { ...viz.state.datasourceStates, [activeDatasourceId]: datasourceState }; const references = (0, _utils.extractReferencesFromState)({ activeDatasources: Object.keys(datasourceStates).reduce((acc, datasourceId) => ({ ...acc, [datasourceId]: this.deps.datasourceMap[datasourceId] }), {}), datasourceStates: Object.fromEntries(Object.entries(datasourceStates).map(([id, state]) => [id, { isLoading: false, state }])), visualizationState, activeVisualization: this.activeVisualizationId ? this.deps.visualizationMap[this.activeVisualizationId] : undefined }); const attrs = { ...viz, state: { ...viz.state, visualization: visualizationState, datasourceStates }, references }; this.updateInput({ attributes: attrs }); } } async openConfingPanel(startDependencies) { var _this$activeDatasourc4; const { getEditLensConfiguration } = await Promise.resolve().then(() => _interopRequireWildcard(require('../async_services'))); const Component = await getEditLensConfiguration(this.deps.coreStart, startDependencies, this.deps.visualizationMap, this.deps.datasourceMap); const datasourceId = (_this$activeDatasourc4 = this.activeDatasourceId) !== null && _this$activeDatasourc4 !== void 0 ? _this$activeDatasourc4 : 'formBased'; const attributes = this.savedVis; const dataView = this.dataViews[0]; if (attributes) { var _this$lensInspector$a; return /*#__PURE__*/_react.default.createElement(Component, { attributes: attributes, dataView: dataView, updateAll: this.updateVisualization.bind(this), datasourceId: datasourceId, adaptersTables: (_this$lensInspector$a = this.lensInspector.adapters.tables) === null || _this$lensInspector$a === void 0 ? void 0 : _this$lensInspector$a.tables, panelId: this.id }); } return null; } async initializeSavedVis(input) { var _metaInfo$sharingSave; const unwrapResult = await this.deps.attributeService.unwrapAttributes(input).catch(e => { this.onFatalError(e); return false; }); if (!unwrapResult || this.isDestroyed) { return; } const { metaInfo, attributes } = unwrapResult; this.fullAttributes = attributes; this.savedVis = { ...attributes, type: this.type, savedObjectId: input === null || input === void 0 ? void 0 : input.savedObjectId }; try { const { ast, indexPatterns, indexPatternRefs, activeVisualizationState } = await getExpressionFromDocument(this.savedVis, this.deps.documentToExpression); this.expression = ast; this.indexPatterns = indexPatterns; this.indexPatternRefs = indexPatternRefs; this.activeVisualizationState = activeVisualizationState; } catch { // nothing, errors should be reported via getUserMessages } if ((metaInfo === null || metaInfo === void 0 ? void 0 : (_metaInfo$sharingSave = metaInfo.sharingSavedObjectProps) === null || _metaInfo$sharingSave === void 0 ? void 0 : _metaInfo$sharingSave.outcome) === 'conflict' && !!this.deps.spaces) { var _metaInfo$sharingSave2; this.addUserMessages([{ uniqueId: 'url-conflict', severity: 'error', displayLocations: [{ id: 'visualization' }], shortMessage: _i18n.i18n.translate('xpack.lens.embeddable.legacyURLConflict.shortMessage', { defaultMessage: `You've encountered a URL conflict` }), longMessage: /*#__PURE__*/_react.default.createElement(this.deps.spaces.ui.components.getEmbeddableLegacyUrlConflict, { targetType: _constants.DOC_TYPE, sourceId: metaInfo === null || metaInfo === void 0 ? void 0 : (_metaInfo$sharingSave2 = metaInfo.sharingSavedObjectProps) === null || _metaInfo$sharingSave2 === void 0 ? void 0 : _metaInfo$sharingSave2.sourceId }), fixableInEditor: false }]); } await this.initializeOutput(); // deferred loading of this embeddable is complete this.setInitializationFinished(); this.isInitialized = true; } getSearchWarningMessages(adapters) { var _this$savedVis8; if (!this.activeDatasource || !this.activeDatasourceId || !(adapters !== null && adapters !== void 0 && adapters.requests)) { return []; } const docDatasourceState = (_this$savedVis8 = this.savedVis) === null || _this$savedVis8 === void 0 ? void 0 : _this$savedVis8.state.datasourceStates[this.activeDatasourceId]; const requestWarnings = (0, _utils.getSearchWarningMessages)(adapters.requests, this.activeDatasource, docDatasourceState, { searchService: this.deps.data.search }); return requestWarnings; } getExecutionContext() { if (this.savedVis) { var _this$parent, _this$savedVis$visual; const parentContext = ((_this$parent = this.parent) === null || _this$parent === void 0 ? void 0 : _this$parent.getInput().executionContext) || this.input.executionContext; const child = { type: 'lens', name: (_this$savedVis$visual = this.savedVis.visualizationType) !== null && _this$savedVis$visual !== void 0 ? _this$savedVis$visual : '', id: this.id, description: this.savedVis.title || this.input.title || '', url: this.output.editUrl }; return parentContext ? { ...parentContext, child } : child; } } /** * * @param {HTMLElement} domNode * @param {ContainerState} containerState */ render(domNode) { this.domNode = domNode; if (!this.savedVis || !this.isInitialized || this.isDestroyed) { return; } super.render(domNode); if (this.input.onLoad) { this.input.onLoad(true); } this.domNode.setAttribute('data-shared-item', ''); const blockingErrors = this.getUserMessages(blockingMessageDisplayLocations, { severity: 'error' }); this.updateOutput({ loading: true, error: blockingErrors.length ? new Error(typeof blockingErrors[0].longMessage === 'string' ? blockingErrors[0].longMessage : blockingErrors[0].shortMessage) : undefined }); if (blockingErrors.length) { this.renderComplete.dispatchError(); } else { this.renderComplete.dispatchInProgress(); } const input = this.getInput(); if (this.expression && !blockingErrors.length) { (0, _reactDom.render)( /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_public2.KibanaThemeProvider, { theme$: this.deps.theme.theme$ }, /*#__PURE__*/_react.default.createElement(_expression_wrapper.ExpressionWrapper, { ExpressionRenderer: this.expressionRenderer, expression: this.expression || null, lensInspector: this.lensInspector, searchContext: this.getMergedSearchContext(), variables: { embeddableTitle: this.getTitle(), ...(input.palette ? { theme: { palette: input.palette } } : {}), ...('overrides' in input ? { overrides: input.overrides } : {}) }, searchSessionId: this.getInput().searchSessionId, handleEvent: this.handleEvent, onData$: this.updateActiveData, onRender$: this.onRender, interactive: !input.disableTriggers && !this.isTextBasedLanguage(), renderMode: input.renderMode, syncColors: input.syncColors, syncTooltips: input.syncTooltips, syncCursor: input.syncCursor, hasCompatibleActions: this.hasCompatibleActions, getCompatibleCellValueActions: this.getCompatibleCellValueActions, className: input.className, style: input.style, executionContext: this.getExecutionContext(), addUserMessages: messages => this.addUserMessages(messages), onRuntimeError: message => { this.updateOutput({ error: new Error(message) }); this.logError('runtime'); }, noPadding: this.visDisplayOptions.noPadding, docLinks: this.deps.coreStart.docLinks })), /*#__PURE__*/_react.default.createElement(MessagesBadge, { onMount: el => { this.badgeDomNode = el; this.renderBadgeMessages(); } })), domNode); } this.renderUserMessages(); } renderUserMessages() { const errors = this.getUserMessages(['visualization', 'visualizationOnEmbeddable'], { severity: 'error' }); if (errors.length && this.domNode) { (0, _reactDom.render)( /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_public2.KibanaThemeProvider, { theme$: this.deps.theme.theme$ }, /*#__PURE__*/_react.default.createElement(_i18nReact.I18nProvider, null, /*#__PURE__*/_react.default.createElement(VisualizationErrorPanel, { errors: errors, canEdit: this.getIsEditable() && this.input.viewMode === 'edit' }))), /*#__PURE__*/_react.default.createElement(MessagesBadge, { onMount: el => { this.badgeDomNode = el; this.renderBadgeMessages(); } })), this.domNode); } this.renderBadgeMessages(); } /** * Combines the embeddable context with the saved object context, and replaces * any references to index patterns */ getMergedSearchContext() { var _input$filters; if (!this.savedVis) { throw new Error('savedVis is required for getMergedSearchContext'); } const input = this.getInput(); const context = { timeRange: input.timeslice !== undefined ? { from: new Date(input.timeslice[0]).toISOString(), to: new Date(input.timeslice[1]).toISOString(), mode: 'absolute' } : input.timeRange, query: [this.savedVis.state.query], filters: this.deps.injectFilterReferences(this.savedVis.state.filters, this.savedVis.references), disableShardWarnings: true }; if (input.query) { context.query = [input.query, ...context.query]; } if ((_input$filters = input.filters) !== null && _input$filters !== void 0 && _input$filters.length) { context.filters = [...input.filters.filter(filter => !filter.meta.disabled), ...context.filters]; } return context; } get onEditAction() { var _this$savedVis9; const visType = (_this$savedVis9 = this.savedVis) === null || _this$savedVis9 === void 0 ? void 0 : _this$savedVis9.visualizationType; if (!visType) { return; } return this.deps.visualizationMap[visType].onEditAction; } reload() { if (!this.savedVis || !this.isInitialized || this.isDestroyed) { return; } if (this.domNode) { this.render(this.domNode); } } async loadViewUnderlyingDataArgs() { if (!this.savedVis || !this.activeData || !this.activeDatasource || !this.activeDatasourceState || !this.activeVisualization || !this.activeVisualizationState) { return false; } const mergedSearchContext = this.getMergedSearchContext(); if (!mergedSearchContext.timeRange) { return false; } const viewUnderlyingDataArgs = getViewUnderlyingDataArgs({ activeDatasource: this.activeDatasource, activeDatasourceState: this.activeDatasourceState, activeVisualization: this.activeVisualization, activeVisualizationState: this.activeVisualizationState, activeData: this.activeData, dataViews: this.dataViews, capabilities: this.deps.capabilities, query: mergedSearchContext.query, filters: mergedSearchContext.filters || [], timeRange: mergedSearchContext.timeRange, esQueryConfig: (0, _public.getEsQueryConfig)(this.deps.uiSettings), indexPatternsCache: this.indexPatterns }); const loaded = typeof viewUnderlyingDataArgs !== 'undefined'; if (loaded) { this.viewUnderlyingDataArgs = viewUnderlyingDataArgs; } return loaded; } /** * Returns the necessary arguments to view the underlying data in discover. * * Only makes sense to call this after canViewUnderlyingData has been checked */ getViewUnderlyingDataArgs() { return this.viewUnderlyingDataArgs; } canViewUnderlyingData() { return this.loadViewUnderlyingDataArgs(); } async initializeOutput() { var _this$savedVis10, _this$savedVis11, _input$title, _input$description; if (!this.savedVis) { return; } const { indexPatterns } = await (0, _utils.getIndexPatternsObjects)(((_this$savedVis10 = this.savedVis) === null || _this$savedVis10 === void 0 ? void 0 : _this$savedVis10.references.map(({ id }) => id)) || [], this.deps.dataViews); (await Promise.all(Object.values(((_this$savedVis11 = this.savedVis) === null || _this$savedVis11 === void 0 ? void 0 : _this$savedVis11.state.adHocDataViews) || {}).map(spec => this.deps.dataViews.create(spec)))).forEach(dataView => indexPatterns.push(dataView)); this.dataViews = (0, _lodash.uniqBy)(indexPatterns, 'id'); // passing edit url and index patterns to the output of this embeddable for // the container to pick them up and use them to configure filter bar and // config dropdown correctly. const input = this.getInput(); // if at least one indexPattern is time based, then the Lens embeddable requires the timeRange prop if (input.timeRange == null && indexPatterns.some(indexPattern => indexPattern.isTimeBased())) { this.addUserMessages([{ uniqueId: 'missing-time-range-on-embeddable', severity: 'error', fixableInEditor: false, displayLocations: [{ id: 'visualization' }], shortMessage: _i18n.i18n.translate('xpack.lens.embeddable.missingTimeRangeParam.shortMessage', { defaultMessage: `Missing timeRange property` }), longMessage: _i18n.i18n.translate('xpack.lens.embeddable.missingTimeRangeParam.longMessage', { defaultMessage: `The timeRange property is required for the given configuration` }) }]); } const blockingErrors = this.getUserMessages(blockingMessageDisplayLocations, { severity: 'error' }); if (blockingErrors.length) { this.logError('validation'); } const title = input.hidePanelTitles ? '' : (_input$title = input.title) !== null && _input$title !== void 0 ? _input$title : this.savedVis.title; const description = input.hidePanelTitles ? '' : (_input$description = input.description) !== null && _input$description !== void 0 ? _input$description : this.savedVis.description; const savedObjectId = input.savedObjectId; this.updateOutput({ defaultTitle: this.savedVis.title, defaultDescription: this.savedVis.description, editable: this.getIsEditable() && !this.isTextBasedLanguage(), title, description, editPath: (0, _constants.getEditPath)(savedObjectId), editUrl: this.deps.basePath.prepend(`/app/lens${(0, _constants.getEditPath)(savedObjectId)}`), indexPatterns: this.dataViews }); } getIsEditable() { return this.deps.capabilities.canSaveVisualizations || !this.inputIsRefType(this.getInput()) && this.deps.capabilities.canSaveDashboards && this.deps.capabilities.canOpenVisualizations; } /** * Gets the Lens embeddable's local filters * @returns Local/panel-level array of filters for Lens embeddable */ async getFilters() { var _this$savedVis$state$, _this$savedVis12, _this$savedVis$refere, _this$savedVis13; return (0, _public.mapAndFlattenFilters)(this.deps.injectFilterReferences((_this$savedVis$state$ = (_this$savedVis12 = this.savedVis) === null || _this$savedVis12 === void 0 ? void 0 : _this$savedVis12.state.filters) !== null && _this$savedVis$state$ !== void 0 ? _this$savedVis$state$ : [], (_this$savedVis$refere = (_this$savedVis13 = this.savedVis) === null || _this$savedVis13 === void 0 ? void 0 : _this$savedVis13.references) !== null && _this$savedVis$refere !== void 0 ? _this$savedVis$refere : [])); } /** * Gets the Lens embeddable's local query * @returns Local/panel-level query for Lens embeddable */ async getQuery() { var _this$savedVis14; return (_this$savedVis14 = this.savedVis) === null || _this$savedVis14 === void 0 ? void 0 : _this$savedVis14.state.query; } getSavedVis() { return this.savedVis; } destroy() { this.isDestroyed = true; super.destroy(); if (this.inputReloadSubscriptions.length > 0) { this.inputReloadSubscriptions.forEach(reloadSub => { reloadSub.unsubscribe(); }); } if (this.domNode) { (0, _reactDom.unmountComponentAtNode)(this.domNode); } } getSelfStyledOptions() { return { hideTitle: this.visDisplayOptions.noPanelTitle }; } get visDisplayOptions() { var _this$savedVis15, _this$deps$visualizat5, _this$deps$visualizat6, _this$deps$visualizat7; if (!((_this$savedVis15 = this.savedVis) !== null && _this$savedVis15 !== void 0 && _this$savedVis15.visualizationType)) { return {}; } let displayOptions = (_this$deps$visualizat5 = (_this$deps$visualizat6 = this.deps.visualizationMap[this.savedVis.visualizationType]) === null || _this$deps$visualizat6 === void 0 ? void 0 : (_this$deps$visualizat7 = _this$deps$visualizat6.getDisplayOptions) === null || _this$deps$visualizat7 === void 0 ? void 0 : _this$deps$visualizat7.call(_this$deps$visualizat6)) !== null && _this$deps$visualizat5 !== void 0 ? _this$deps$visualizat5 : {}; if (this.input.noPadding !== undefined) { displayOptions = { ...displayOptions, noPadding: this.input.noPadding }; } return displayOptions; } } exports.Embeddable = Embeddable;