"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.getLensServices = getLensServices; exports.mountApp = mountApp; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _react = _interopRequireWildcard(require("react")); var _i18nReact = require("@kbn/i18n-react"); var _sharedUxRouter = require("@kbn/shared-ux-router"); var _reactDom = require("react-dom"); var _i18n = require("@kbn/i18n"); var _reactRedux = require("react-redux"); var _public = require("@kbn/kibana-utils-plugin/public"); var _sharedUxPageAnalyticsNoData = require("@kbn/shared-ux-page-analytics-no-data"); var _public2 = require("@kbn/ui-actions-plugin/public"); var _public3 = require("@kbn/visualizations-plugin/public"); var _public4 = require("@kbn/kibana-react-plugin/public"); var _eui = require("@elastic/eui"); var _public5 = require("@kbn/data-plugin/public"); var _app = require("./app"); var _help_menu_util = require("../help_menu_util"); var _constants = require("../../common/constants"); var _state_management = require("../state_management"); var _lens_slice = require("../state_management/lens_slice"); var _lens_inspector_service = require("../lens_inspector_service"); var _locator = require("../../common/locator/locator"); var _persistence = require("../persistence"); 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; you may not use this file except in compliance with the Elastic License * 2.0. */ function getInitialContext(history) { const historyLocationState = history.location.state; if (historyLocationState) { if (historyLocationState.type === _locator.LENS_SHARE_STATE_ACTION) { return { contextType: historyLocationState.type, initialStateFromLocator: historyLocationState.payload }; } // get state from location, used for navigating from Visualize/Discover to Lens if ([_public2.ACTION_VISUALIZE_LENS_FIELD, _public3.ACTION_CONVERT_TO_LENS].includes(historyLocationState.type)) { return { contextType: historyLocationState.type, initialContext: historyLocationState.payload, originatingApp: historyLocationState.originatingApp }; } } } async function getLensServices(coreStart, startDependencies, attributeService, initialContext, locator) { const { data, inspector, navigation, embeddable, eventAnnotation, savedObjectsTagging, usageCollection, fieldFormats, spaces, share, unifiedSearch, serverless } = startDependencies; const storage = new _public.Storage(localStorage); const stateTransfer = embeddable === null || embeddable === void 0 ? void 0 : embeddable.getStateTransfer(); const embeddableEditorIncomingState = stateTransfer === null || stateTransfer === void 0 ? void 0 : stateTransfer.getIncomingEditorState(_constants.APP_ID); const eventAnnotationService = await eventAnnotation.getService(); return { data, storage, inspector: (0, _lens_inspector_service.getLensInspectorService)(inspector), navigation, fieldFormats, stateTransfer, usageCollection, savedObjectsTagging, attributeService, eventAnnotationService, executionContext: coreStart.executionContext, http: coreStart.http, uiActions: startDependencies.uiActions, chrome: coreStart.chrome, overlays: coreStart.overlays, uiSettings: coreStart.uiSettings, settings: coreStart.settings, application: coreStart.application, notifications: coreStart.notifications, savedObjectStore: new _persistence.SavedObjectIndexStore(startDependencies.contentManagement.client), presentationUtil: startDependencies.presentationUtil, dataViewEditor: startDependencies.dataViewEditor, dataViewFieldEditor: startDependencies.dataViewFieldEditor, dashboard: startDependencies.dashboard, charts: startDependencies.charts, getOriginatingAppName: () => { var _embeddableEditorInco; const originatingApp = (_embeddableEditorInco = embeddableEditorIncomingState === null || embeddableEditorIncomingState === void 0 ? void 0 : embeddableEditorIncomingState.originatingApp) !== null && _embeddableEditorInco !== void 0 ? _embeddableEditorInco : initialContext === null || initialContext === void 0 ? void 0 : initialContext.originatingApp; return originatingApp ? stateTransfer === null || stateTransfer === void 0 ? void 0 : stateTransfer.getAppNameFromId(originatingApp) : undefined; }, dataViews: startDependencies.dataViews, // Temporarily required until the 'by value' paradigm is default. dashboardFeatureFlag: startDependencies.dashboard.dashboardFeatureFlagConfig, spaces, share, unifiedSearch, docLinks: coreStart.docLinks, locator, serverless }; } async function mountApp(core, params, mountProps) { const { createEditorFrame, attributeService, getPresentationUtilContext, topNavMenuEntryGenerators, locator } = mountProps; const [[coreStart, startDependencies], instance] = await Promise.all([core.getStartServices(), createEditorFrame()]); const { contextType, initialContext, initialStateFromLocator, originatingApp } = getInitialContext(params.history) || {}; const lensServices = await getLensServices(coreStart, startDependencies, attributeService, initialContext, locator); const { stateTransfer, data, savedObjectStore } = lensServices; const embeddableEditorIncomingState = stateTransfer === null || stateTransfer === void 0 ? void 0 : stateTransfer.getIncomingEditorState(_constants.APP_ID); (0, _help_menu_util.addHelpMenuToAppChrome)(coreStart.chrome, coreStart.docLinks); if (!lensServices.application.capabilities.visualize.save) { coreStart.chrome.setBadge({ text: _i18n.i18n.translate('xpack.lens.badge.readOnly.text', { defaultMessage: 'Read only' }), tooltip: _i18n.i18n.translate('xpack.lens.badge.readOnly.tooltip', { defaultMessage: 'Unable to save visualizations to the library' }), iconType: 'glasses' }); } coreStart.chrome.docTitle.change(_i18n.i18n.translate('xpack.lens.pageTitle', { defaultMessage: 'Lens' })); const getInitialInput = (id, editByValue) => { if (editByValue) { return embeddableEditorIncomingState === null || embeddableEditorIncomingState === void 0 ? void 0 : embeddableEditorIncomingState.valueInput; } if (id) { return { savedObjectId: id }; } }; const redirectTo = (history, savedObjectId) => { if (!savedObjectId) { history.push({ pathname: '/', search: history.location.search }); } else { history.push({ pathname: `/edit/${savedObjectId}`, search: history.location.search }); } }; const redirectToOrigin = props => { var _embeddableEditorInco2; const contextOriginatingApp = initialContext && 'originatingApp' in initialContext ? initialContext.originatingApp : null; const mergedOriginatingApp = (_embeddableEditorInco2 = embeddableEditorIncomingState === null || embeddableEditorIncomingState === void 0 ? void 0 : embeddableEditorIncomingState.originatingApp) !== null && _embeddableEditorInco2 !== void 0 ? _embeddableEditorInco2 : contextOriginatingApp; if (!mergedOriginatingApp) { throw new Error('redirectToOrigin called without an originating app'); } let embeddableId = embeddableEditorIncomingState === null || embeddableEditorIncomingState === void 0 ? void 0 : embeddableEditorIncomingState.embeddableId; if (initialContext && 'embeddableId' in initialContext) { embeddableId = initialContext.embeddableId; } if (stateTransfer && props !== null && props !== void 0 && props.input) { const { input, isCopied } = props; stateTransfer.navigateToWithEmbeddablePackage(mergedOriginatingApp, { path: embeddableEditorIncomingState === null || embeddableEditorIncomingState === void 0 ? void 0 : embeddableEditorIncomingState.originatingPath, state: { embeddableId: isCopied ? undefined : embeddableId, type: _constants.LENS_EMBEDDABLE_TYPE, input, searchSessionId: data.search.session.getSessionId() } }); } else { coreStart.application.navigateToApp(mergedOriginatingApp, { path: embeddableEditorIncomingState === null || embeddableEditorIncomingState === void 0 ? void 0 : embeddableEditorIncomingState.originatingPath }); } }; if (contextType === _public2.ACTION_VISUALIZE_LENS_FIELD && initialContext !== null && initialContext !== void 0 && initialContext.originatingApp) { // remove originatingApp from context when visualizing a field in Lens // so Lens does not try to return to the original app on Save // see https://github.com/elastic/kibana/issues/128695 delete initialContext.originatingApp; } if (embeddableEditorIncomingState !== null && embeddableEditorIncomingState !== void 0 && embeddableEditorIncomingState.searchSessionId) { data.search.session.continue(embeddableEditorIncomingState.searchSessionId); } const { datasourceMap, visualizationMap } = instance; const storeDeps = { lensServices, datasourceMap, visualizationMap, embeddableEditorIncomingState, initialContext, initialStateFromLocator }; const lensStore = (0, _state_management.makeConfigureStore)(storeDeps); const EditorRenderer = /*#__PURE__*/_react.default.memo(props => { const [editorState, setEditorState] = (0, _react.useState)('loading'); (0, _react.useEffect)(() => { const kbnUrlStateStorage = (0, _public.createKbnUrlStateStorage)({ history: props.history, useHash: lensServices.uiSettings.get('state:storeInSessionStorage'), ...(0, _public.withNotifyOnErrors)(lensServices.notifications.toasts) }); const { stop: stopSyncingQueryServiceStateWithUrl } = (0, _public5.syncGlobalQueryStateWithUrl)(data.query, kbnUrlStateStorage); return () => { stopSyncingQueryServiceStateWithUrl(); }; }, [props.history]); const redirectCallback = (0, _react.useCallback)(id => { redirectTo(props.history, id); }, [props.history]); const initialInput = (0, _react.useMemo)(() => { return getInitialInput(props.id, props.editByValue); }, [props.editByValue, props.id]); const initCallback = (0, _react.useCallback)(() => { // Clear app-specific filters when navigating to Lens. Necessary because Lens // can be loaded without a full page refresh. // If the user navigates to Lens from Discover, or comes from a Lens share link we keep the filters if (!initialContext) { data.query.filterManager.setAppFilters([]); } // if user comes from a dashboard to convert a legacy viz to a Lens chart // we clear up the dashboard filters and query if (initialContext && 'isEmbeddable' in initialContext && initialContext.isEmbeddable) { data.query.filterManager.setAppFilters([]); data.query.queryString.clearQuery(); } lensStore.dispatch((0, _state_management.setState)((0, _lens_slice.getPreloadedState)(storeDeps))); lensStore.dispatch((0, _state_management.loadInitial)({ redirectCallback, initialInput, history: props.history })); }, [initialInput, props.history, redirectCallback]); (0, _react.useEffect)(() => { (async () => { const hasUserDataView = await data.dataViews.hasData.hasUserDataView().catch(() => false); if (!hasUserDataView) { setEditorState('no_data'); return; } setEditorState('data'); initCallback(); })(); }, [initCallback, initialInput, props.history, redirectCallback]); if (editorState === 'loading') { return /*#__PURE__*/_react.default.createElement(_eui.EuiLoadingSpinner, null); } if (editorState === 'no_data') { const analyticsServices = { coreStart, dataViews: data.dataViews, dataViewEditor: startDependencies.dataViewEditor }; return /*#__PURE__*/_react.default.createElement(_sharedUxPageAnalyticsNoData.AnalyticsNoDataPageKibanaProvider, analyticsServices, /*#__PURE__*/_react.default.createElement(_sharedUxPageAnalyticsNoData.AnalyticsNoDataPage, { onDataViewCreated: () => { setEditorState('data'); initCallback(); } })); } return /*#__PURE__*/_react.default.createElement(_reactRedux.Provider, { store: lensStore }, /*#__PURE__*/_react.default.createElement(_app.App, { incomingState: embeddableEditorIncomingState, editorFrame: instance, initialInput: initialInput, redirectTo: redirectCallback, redirectToOrigin: redirectToOrigin, onAppLeave: params.onAppLeave, setHeaderActionMenu: params.setHeaderActionMenu, history: props.history, datasourceMap: datasourceMap, visualizationMap: visualizationMap, initialContext: initialContext, contextOriginatingApp: originatingApp, topNavMenuEntryGenerators: topNavMenuEntryGenerators, theme$: core.theme.theme$, coreStart: coreStart, savedObjectStore: savedObjectStore })); }); const EditorRoute = routeProps => { return /*#__PURE__*/_react.default.createElement(EditorRenderer, { id: routeProps.match.params.id, history: routeProps.history, editByValue: routeProps.editByValue }); }; function NotFound() { return /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.lens.app404", defaultMessage: "404 Not Found" }); } // dispatch synthetic hash change event to update hash history objects // this is necessary because hash updates triggered by using popState won't trigger this event naturally. const unlistenParentHistory = params.history.listen(() => { window.dispatchEvent(new HashChangeEvent('hashchange')); }); params.element.classList.add('lnsAppWrapper'); const PresentationUtilContext = getPresentationUtilContext(); (0, _reactDom.render)( /*#__PURE__*/_react.default.createElement(_public4.KibanaThemeProvider, { theme$: coreStart.theme.theme$ }, /*#__PURE__*/_react.default.createElement(_i18nReact.I18nProvider, null, /*#__PURE__*/_react.default.createElement(_public4.KibanaContextProvider, { services: lensServices }, /*#__PURE__*/_react.default.createElement(PresentationUtilContext, null, /*#__PURE__*/_react.default.createElement(_sharedUxRouter.HashRouter, null, /*#__PURE__*/_react.default.createElement(_sharedUxRouter.Routes, null, /*#__PURE__*/_react.default.createElement(_sharedUxRouter.Route, { exact: true, path: "/edit/:id", component: EditorRoute }), /*#__PURE__*/_react.default.createElement(_sharedUxRouter.Route, { exact: true, path: `/${_constants.LENS_EDIT_BY_VALUE}`, render: routeProps => /*#__PURE__*/_react.default.createElement(EditorRoute, (0, _extends2.default)({}, routeProps, { editByValue: true })) }), /*#__PURE__*/_react.default.createElement(_sharedUxRouter.Route, { exact: true, path: "/", component: EditorRoute }), /*#__PURE__*/_react.default.createElement(_sharedUxRouter.Route, { path: "/", component: NotFound }))))))), params.element); return () => { var _stateTransfer$clearE; data.search.session.clear(); (0, _reactDom.unmountComponentAtNode)(params.element); lensServices.inspector.close(); unlistenParentHistory(); lensStore.dispatch((0, _state_management.navigateAway)()); (_stateTransfer$clearE = stateTransfer.clearEditorState) === null || _stateTransfer$clearE === void 0 ? void 0 : _stateTransfer$clearE.call(stateTransfer, _constants.APP_ID); }; }