"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.UrlPanelContent = exports.ExportUrlAsType = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireWildcard(require("react")); var _eui = require("@elastic/eui"); var _url = require("url"); var _i18nReact = require("@kbn/i18n-react"); var _i18n = require("@kbn/i18n"); 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. */ let ExportUrlAsType; exports.ExportUrlAsType = ExportUrlAsType; (function (ExportUrlAsType) { ExportUrlAsType["EXPORT_URL_AS_SAVED_OBJECT"] = "savedObject"; ExportUrlAsType["EXPORT_URL_AS_SNAPSHOT"] = "snapshot"; })(ExportUrlAsType || (exports.ExportUrlAsType = ExportUrlAsType = {})); class UrlPanelContent extends _react.Component { constructor(props) { super(props); (0, _defineProperty2.default)(this, "mounted", void 0); (0, _defineProperty2.default)(this, "shortUrlCache", void 0); (0, _defineProperty2.default)(this, "isNotSaved", () => { return this.props.objectId === undefined || this.props.objectId === ''; }); (0, _defineProperty2.default)(this, "resetUrl", () => { if (this.mounted) { this.shortUrlCache = undefined; this.setState({ useShortUrl: false }, this.setUrl); } }); (0, _defineProperty2.default)(this, "updateUrlParams", url => { url = this.props.isEmbedded ? this.makeUrlEmbeddable(url) : url; url = this.state.urlParams ? this.getUrlParamExtensions(url) : url; return url; }); (0, _defineProperty2.default)(this, "getSavedObjectUrl", () => { if (this.isNotSaved()) { return; } const url = this.getSnapshotUrl(true); const parsedUrl = (0, _url.parse)(url); if (!parsedUrl || !parsedUrl.hash) { return; } // Get the application route, after the hash, and remove the #. const parsedAppUrl = (0, _url.parse)(parsedUrl.hash.slice(1), true); const formattedUrl = (0, _url.format)({ protocol: parsedUrl.protocol, auth: parsedUrl.auth, host: parsedUrl.host, pathname: parsedUrl.pathname, hash: (0, _url.format)({ pathname: parsedAppUrl.pathname, query: { // Add global state to the URL so that the iframe doesn't just show the time range // default. _g: parsedAppUrl.query._g } }) }); return this.updateUrlParams(formattedUrl); }); (0, _defineProperty2.default)(this, "getSnapshotUrl", forSavedObject => { let url = ''; if (forSavedObject && this.props.shareableUrlForSavedObject) { url = this.props.shareableUrlForSavedObject; } if (!url) { url = this.props.shareableUrl || window.location.href; } return this.updateUrlParams(url); }); (0, _defineProperty2.default)(this, "makeUrlEmbeddable", url => { const embedParam = '?embed=true'; const urlHasQueryString = url.indexOf('?') !== -1; if (urlHasQueryString) { return url.replace('?', `${embedParam}&`); } return `${url}${embedParam}`; }); (0, _defineProperty2.default)(this, "addUrlAnonymousAccessParameters", url => { if (!this.state.anonymousAccessParameters || !this.state.usePublicUrl) { return url; } const parsedUrl = new URL(url); for (const [name, value] of Object.entries(this.state.anonymousAccessParameters)) { parsedUrl.searchParams.set(name, value); } return parsedUrl.toString(); }); (0, _defineProperty2.default)(this, "getUrlParamExtensions", url => { const { urlParams } = this.state; return urlParams ? Object.keys(urlParams).reduce((urlAccumulator, key) => { const urlParam = urlParams[key]; return urlParam ? Object.keys(urlParam).reduce((queryAccumulator, queryParam) => { const isQueryParamEnabled = urlParam[queryParam]; return isQueryParamEnabled ? queryAccumulator + `&${queryParam}=true` : queryAccumulator; }, urlAccumulator) : urlAccumulator; }, url) : url; }); (0, _defineProperty2.default)(this, "makeIframeTag", url => { if (!url) { return; } return ``; }); (0, _defineProperty2.default)(this, "setUrl", () => { let url; if (this.state.exportUrlAs === ExportUrlAsType.EXPORT_URL_AS_SAVED_OBJECT) { url = this.getSavedObjectUrl(); } else if (this.state.useShortUrl) { url = this.shortUrlCache; } else { url = this.getSnapshotUrl(); } if (url) { url = this.addUrlAnonymousAccessParameters(url); } if (this.props.isEmbedded) { url = this.makeIframeTag(url); } this.setState({ url }); }); (0, _defineProperty2.default)(this, "handleExportUrlAs", optionId => { this.setState({ showWarningButton: Boolean(this.props.snapshotShareWarning) && optionId === ExportUrlAsType.EXPORT_URL_AS_SNAPSHOT, exportUrlAs: optionId }, this.setUrl); }); (0, _defineProperty2.default)(this, "handleShortUrlChange", async evt => { const isChecked = evt.target.checked; if (!isChecked || this.shortUrlCache !== undefined) { this.setState({ useShortUrl: isChecked }, this.setUrl); return; } // "Use short URL" is checked but shortUrl has not been generated yet so one needs to be created. this.createShortUrl(); }); (0, _defineProperty2.default)(this, "handlePublicUrlChange", () => { this.setState(({ usePublicUrl }) => { return { usePublicUrl: !usePublicUrl }; }, this.setUrl); }); (0, _defineProperty2.default)(this, "createShortUrl", async () => { this.setState({ isCreatingShortUrl: true, shortUrlErrorMsg: undefined }); try { const { shareableUrlLocatorParams } = this.props; if (shareableUrlLocatorParams) { const shortUrls = this.props.urlService.shortUrls.get(null); const shortUrl = await shortUrls.createWithLocator(shareableUrlLocatorParams); this.shortUrlCache = await shortUrl.locator.getUrl(shortUrl.params, { absolute: true }); } else { const snapshotUrl = this.getSnapshotUrl(); const shortUrl = await this.props.urlService.shortUrls.get(null).createFromLongUrl(snapshotUrl); this.shortUrlCache = shortUrl.url; } if (!this.mounted) { return; } this.setState({ isCreatingShortUrl: false, useShortUrl: true }, this.setUrl); } catch (fetchError) { if (!this.mounted) { return; } this.shortUrlCache = undefined; this.setState({ useShortUrl: false, isCreatingShortUrl: false, shortUrlErrorMsg: _i18n.i18n.translate('share.urlPanel.unableCreateShortUrlErrorMessage', { defaultMessage: 'Unable to create short URL. Error: {errorMessage}', values: { errorMessage: fetchError.message } }) }, this.setUrl); } }); (0, _defineProperty2.default)(this, "renderCopyButton", () => /*#__PURE__*/_react.default.createElement(_eui.EuiCopy, { beforeMessage: this.state.showWarningButton ? this.props.snapshotShareWarning : undefined, textToCopy: this.state.url || '', anchorClassName: "eui-displayBlock" }, copy => /*#__PURE__*/_react.default.createElement(_eui.EuiButton, { fill: true, fullWidth: true, onClick: copy, disabled: this.state.isCreatingShortUrl || this.state.url === '', "data-share-url": this.state.url, "data-test-subj": "copyShareUrlButton", size: "s", iconType: this.state.showWarningButton ? 'warning' : undefined, color: this.state.showWarningButton ? 'warning' : 'primary' }, this.props.isEmbedded ? /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "share.urlPanel.copyIframeCodeButtonLabel", defaultMessage: "Copy iFrame code" }) : /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "share.urlPanel.copyLinkButtonLabel", defaultMessage: "Copy link" })))); (0, _defineProperty2.default)(this, "renderExportUrlAsOptions", () => { const snapshotLabel = /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "share.urlPanel.snapshotLabel", defaultMessage: "Snapshot" }); return [{ id: ExportUrlAsType.EXPORT_URL_AS_SNAPSHOT, label: /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, this.renderWithIconTip(snapshotLabel, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "share.urlPanel.snapshotDescription", defaultMessage: "Snapshot URLs encode the current state of the {objectType} in the URL itself. Edits to the saved {objectType} won't be visible via this URL.", values: { objectType: this.props.objectType } }))), ['data-test-subj']: 'exportAsSnapshot' }, { id: ExportUrlAsType.EXPORT_URL_AS_SAVED_OBJECT, disabled: this.isNotSaved(), label: this.renderWithIconTip( /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "share.urlPanel.savedObjectLabel", defaultMessage: "Saved object" }), /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "share.urlPanel.savedObjectDescription", defaultMessage: "You can share this URL with people to let them load the most recent saved version of this {objectType}.", values: { objectType: this.props.objectType } })), ['data-test-subj']: 'exportAsSavedObject' }]; }); (0, _defineProperty2.default)(this, "renderWithIconTip", (child, tipContent) => { return /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, { gutterSize: "none", responsive: false }, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, { grow: false }, child), /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, { grow: false }, /*#__PURE__*/_react.default.createElement(_eui.EuiIconTip, { content: tipContent, position: "bottom" }))); }); (0, _defineProperty2.default)(this, "renderExportAsRadioGroup", () => { const generateLinkAsHelp = this.isNotSaved() ? /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "share.urlPanel.canNotShareAsSavedObjectHelpText", defaultMessage: "To share as a saved object, save the {objectType}.", values: { objectType: this.props.objectType } }) : undefined; return /*#__PURE__*/_react.default.createElement(_eui.EuiFormRow, { helpText: generateLinkAsHelp }, /*#__PURE__*/_react.default.createElement(_eui.EuiRadioGroup, { options: this.renderExportUrlAsOptions(), idSelected: this.state.exportUrlAs, onChange: this.handleExportUrlAs, legend: { children: /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "share.urlPanel.generateLinkAsLabel", defaultMessage: "Generate the link as" }) } })); }); (0, _defineProperty2.default)(this, "renderShortUrlSwitch", () => { if (this.state.exportUrlAs === ExportUrlAsType.EXPORT_URL_AS_SAVED_OBJECT || !this.props.allowShortUrl) { return null; } const shortUrlLabel = /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "share.urlPanel.shortUrlLabel", defaultMessage: "Short URL" }); const switchLabel = this.state.isCreatingShortUrl ? /*#__PURE__*/_react.default.createElement("span", null, /*#__PURE__*/_react.default.createElement(_eui.EuiLoadingSpinner, { size: "s" }), " ", shortUrlLabel) : shortUrlLabel; const switchComponent = /*#__PURE__*/_react.default.createElement(_eui.EuiSwitch, { label: switchLabel, checked: this.state.useShortUrl, onChange: this.handleShortUrlChange, "data-test-subj": "useShortUrl" }); const tipContent = /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "share.urlPanel.shortUrlHelpText", defaultMessage: "We recommend sharing shortened snapshot URLs for maximum compatibility. Internet Explorer has URL length restrictions, and some wiki and markup parsers don't do well with the full-length version of the snapshot URL, but the short URL should work great." }); return /*#__PURE__*/_react.default.createElement(_eui.EuiFormRow, { helpText: this.state.shortUrlErrorMsg, "data-test-subj": "createShortUrl" }, this.renderWithIconTip(switchComponent, tipContent)); }); (0, _defineProperty2.default)(this, "renderPublicUrlSwitch", () => { if (!this.state.anonymousAccessParameters || !this.state.showPublicUrlSwitch) { return null; } const switchLabel = /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "share.urlPanel.publicUrlLabel", defaultMessage: "Public URL" }); const switchComponent = /*#__PURE__*/_react.default.createElement(_eui.EuiSwitch, { label: switchLabel, checked: this.state.usePublicUrl, onChange: this.handlePublicUrlChange, "data-test-subj": "usePublicUrl" }); const tipContent = /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "share.urlPanel.publicUrlHelpText", defaultMessage: "Use public URL to share with anyone. It enables one-step anonymous access by removing the login prompt." }); return /*#__PURE__*/_react.default.createElement(_eui.EuiFormRow, { "data-test-subj": "createPublicUrl" }, this.renderWithIconTip(switchComponent, tipContent)); }); (0, _defineProperty2.default)(this, "renderUrlParamExtensions", () => { if (!this.props.urlParamExtensions) { return; } const setParamValue = paramName => (values = {}) => { const stateUpdate = { urlParams: { ...this.state.urlParams, [paramName]: { ...values } } }; this.setState(stateUpdate, this.state.useShortUrl ? this.createShortUrl : this.setUrl); }; return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, this.props.urlParamExtensions.map(({ paramName, component: UrlParamComponent }) => /*#__PURE__*/_react.default.createElement(_eui.EuiFormRow, { key: paramName }, /*#__PURE__*/_react.default.createElement(UrlParamComponent, { setParamValue: setParamValue(paramName) })))); }); this.shortUrlCache = undefined; this.state = { exportUrlAs: ExportUrlAsType.EXPORT_URL_AS_SNAPSHOT, useShortUrl: false, usePublicUrl: false, isCreatingShortUrl: false, url: '', anonymousAccessParameters: null, showPublicUrlSwitch: false, showWarningButton: Boolean(this.props.snapshotShareWarning) }; } componentWillUnmount() { window.removeEventListener('hashchange', this.resetUrl); this.mounted = false; } componentDidMount() { this.mounted = true; this.setUrl(); window.addEventListener('hashchange', this.resetUrl, false); if (this.props.anonymousAccess) { (async () => { const { accessURLParameters: anonymousAccessParameters } = await this.props.anonymousAccess.getState(); if (!this.mounted) { return; } if (!anonymousAccessParameters) { return; } let showPublicUrlSwitch = false; if (this.props.showPublicUrlSwitch) { const anonymousUserCapabilities = await this.props.anonymousAccess.getCapabilities(); if (!this.mounted) { return; } try { showPublicUrlSwitch = this.props.showPublicUrlSwitch(anonymousUserCapabilities); } catch { showPublicUrlSwitch = false; } } this.setState({ anonymousAccessParameters, showPublicUrlSwitch }); })(); } } render() { const shortUrlSwitch = this.renderShortUrlSwitch(); const publicUrlSwitch = this.renderPublicUrlSwitch(); const copyButton = this.renderCopyButton(); const urlRow = (!!shortUrlSwitch || !!publicUrlSwitch) && /*#__PURE__*/_react.default.createElement(_eui.EuiFormRow, { label: /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "share.urlPanel.urlGroupTitle", defaultMessage: "URL" }) }, /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: 's' }), shortUrlSwitch, publicUrlSwitch)); return /*#__PURE__*/_react.default.createElement(_i18nReact.I18nProvider, null, /*#__PURE__*/_react.default.createElement(_eui.EuiForm, { className: "kbnShareContextMenu__finalPanel", "data-test-subj": "shareUrlForm" }, this.renderExportAsRadioGroup(), this.renderUrlParamExtensions(), urlRow, /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "m" }), copyButton)); } } exports.UrlPanelContent = UrlPanelContent;