"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.Flyout = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireWildcard(require("react")); var _eui = require("@elastic/eui"); var _instruction_steps = require("../instruction_steps"); var _public = require("@kbn/kibana-utils-plugin/public"); var _constants = require("../../../../common/constants"); var _i18n = require("@kbn/i18n"); var _i18nReact = require("@kbn/i18n-react"); var _constants2 = require("../constants"); var _legacy_shims = require("../../../legacy_shims"); var _formatting = require("../../setup_mode/formatting"); 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. */ const storage = new _public.Storage(window.localStorage); const ES_MONITORING_URL_KEY = `${_constants.STORAGE_KEY}.mb_migration.esMonitoringUrl`; const DEFAULT_ES_MONITORING_URL = 'http://localhost:9200'; class Flyout extends _react.Component { constructor(props) { super(props); (0, _defineProperty2.default)(this, "setEsMonitoringUrl", esMonitoringUrl => { storage.set(ES_MONITORING_URL_KEY, esMonitoringUrl); this.setState({ esMonitoringUrl }); }); let _esMonitoringUrl = storage.get(ES_MONITORING_URL_KEY); if (!_esMonitoringUrl) { _esMonitoringUrl = props.monitoringHosts ? props.monitoringHosts[0] : DEFAULT_ES_MONITORING_URL; } this.checkInterval = null; let activeStep = _constants2.INSTRUCTION_STEP_SET_MONITORING_URL; if (props.product && props.product.isPartiallyMigrated) { activeStep = _constants2.INSTRUCTION_STEP_DISABLE_INTERNAL; } this.state = { activeStep, esMonitoringUrl: _esMonitoringUrl, checkedStatusByStep: { [_constants2.INSTRUCTION_STEP_ENABLE_METRICBEAT]: false, [_constants2.INSTRUCTION_STEP_DISABLE_INTERNAL]: false, userAcknowledgedNoClusterUuidPrompt: false } }; } finishedFlyout() { const { onClose } = this.props; onClose(); } renderActiveStep() { const { product, productName, onClose, meta } = this.props; const { activeStep, esMonitoringUrl, checkedStatusByStep } = this.state; switch (activeStep) { case _constants2.INSTRUCTION_STEP_SET_MONITORING_URL: return /*#__PURE__*/_react.default.createElement(_eui.EuiForm, null, /*#__PURE__*/_react.default.createElement(_eui.EuiFormRow, { fullWidth: true, label: _i18n.i18n.translate('xpack.monitoring.metricbeatMigration.flyout.step1.monitoringUrlLabel', { defaultMessage: 'URL of monitoring cluster' }), helpText: _i18n.i18n.translate('xpack.monitoring.metricbeatMigration.flyout.step1.monitoringUrlHelpText', { defaultMessage: `Typically a single URL. If multiple URLs, separate with a comma. The running Metricbeat instance must be able to communicate with these Elasticsearch servers.` }) }, /*#__PURE__*/_react.default.createElement(_eui.EuiFieldText, { fullWidth: true, value: esMonitoringUrl, onChange: e => this.setEsMonitoringUrl(e.target.value) }))); case _constants2.INSTRUCTION_STEP_ENABLE_METRICBEAT: case _constants2.INSTRUCTION_STEP_DISABLE_INTERNAL: const esMonitoringUrls = esMonitoringUrl.split(',').map(url => `"${url}"`); const instructionSteps = (0, _instruction_steps.getInstructionSteps)(productName, product, activeStep, meta, { doneWithMigration: onClose, esMonitoringUrl: esMonitoringUrls, hasCheckedStatus: checkedStatusByStep[activeStep] }); return /*#__PURE__*/_react.default.createElement(_react.Fragment, null, /*#__PURE__*/_react.default.createElement(_eui.EuiSteps, { steps: instructionSteps })); } return null; } renderActiveStepNextButton() { const { product, productName } = this.props; const { activeStep, esMonitoringUrl, userAcknowledgedNoClusterUuidPrompt } = this.state; // It is possible that, during the migration steps, products are not reporting // monitoring data for a period of time outside the window of our server-side check // and this is most likely temporary so we want to be defensive and not error out // and hopefully wait for the next check and this state will be self-corrected. if (!product) { return null; } let willDisableDoneButton = !product.isFullyMigrated; let willShowNextButton = activeStep !== _constants2.INSTRUCTION_STEP_DISABLE_INTERNAL; if (activeStep === _constants2.INSTRUCTION_STEP_ENABLE_METRICBEAT) { if (productName === _constants.ELASTICSEARCH_SYSTEM_ID) { willShowNextButton = false; // ES can be fully migrated for net new users willDisableDoneButton = !product.isPartiallyMigrated && !product.isFullyMigrated; } else { // Do not bother taking them to the disable internal step for non ES use cases // since disabling is an individual action per node, versus ES where it is // a cluster setting willShowNextButton = !product.isFullyMigrated; willDisableDoneButton = !product.isFullyMigrated; } } // This is a possible scenario that come up during testing where logstash/beats // is not outputing to ES, but has monitorining enabled. In these scenarios, // the monitoring documents will not have a `cluster_uuid` so once migrated, // the instance/node will actually live in the standalone cluster listing // instead of the one it currently lives in. We need the user to understand // this so we're going to force them to acknowledge a prompt saying this if (product.isFullyMigrated && product.clusterUuid === null) { // Did they acknowledge the prompt? if (!userAcknowledgedNoClusterUuidPrompt) { willDisableDoneButton = true; } } if (willShowNextButton) { let isDisabled = false; let nextStep = null; if (activeStep === _constants2.INSTRUCTION_STEP_SET_MONITORING_URL) { isDisabled = !esMonitoringUrl || esMonitoringUrl.length === 0; if (product.isPartiallyMigrated || product.isFullyMigrated) { nextStep = _constants2.INSTRUCTION_STEP_DISABLE_INTERNAL; } else { nextStep = _constants2.INSTRUCTION_STEP_ENABLE_METRICBEAT; } } else if (activeStep === _constants2.INSTRUCTION_STEP_ENABLE_METRICBEAT) { isDisabled = !product.isPartiallyMigrated && !product.isFullyMigrated; nextStep = _constants2.INSTRUCTION_STEP_DISABLE_INTERNAL; } return /*#__PURE__*/_react.default.createElement(_eui.EuiButton, { type: "submit", fill: true, iconType: "sortRight", iconSide: "right", isDisabled: isDisabled, onClick: () => this.setState({ activeStep: nextStep }) }, _i18n.i18n.translate('xpack.monitoring.metricbeatMigration.flyout.nextButtonLabel', { defaultMessage: 'Next' })); } return /*#__PURE__*/_react.default.createElement(_eui.EuiButton, { type: "submit", fill: true, isDisabled: willDisableDoneButton, onClick: () => this.finishedFlyout() }, _i18n.i18n.translate('xpack.monitoring.metricbeatMigration.flyout.doneButtonLabel', { defaultMessage: 'Done' })); } getDocumentationTitle() { const { productName } = this.props; let documentationUrl = null; if (productName === _constants.KIBANA_SYSTEM_ID) { documentationUrl = _legacy_shims.Legacy.shims.docLinks.links.monitoring.monitorKibana; } else if (productName === _constants.ELASTICSEARCH_SYSTEM_ID) { documentationUrl = _legacy_shims.Legacy.shims.docLinks.links.monitoring.monitorElasticsearch; } if (!documentationUrl) { return null; } return /*#__PURE__*/_react.default.createElement(_eui.EuiText, { size: "s" }, /*#__PURE__*/_react.default.createElement(_eui.EuiLink, { href: documentationUrl, target: "_blank" }, _i18n.i18n.translate('xpack.monitoring.metricbeatMigration.flyout.learnMore', { defaultMessage: 'Learn about why.' }))); } render() { const { onClose, instance, productName, product } = this.props; const instanceIdentifier = (0, _formatting.getIdentifier)(productName); const instanceName = instance && instance.name || (0, _formatting.formatProductName)(productName); let title = _i18n.i18n.translate('xpack.monitoring.metricbeatMigration.flyout.flyoutTitle', { defaultMessage: 'Monitor `{instanceName}` {instanceIdentifier} with Metricbeat', values: { instanceName, instanceIdentifier } }); if (product.isNetNewUser) { title = _i18n.i18n.translate('xpack.monitoring.metricbeatMigration.flyout.flyoutTitleNewUser', { defaultMessage: 'Monitor {instanceName} {instanceIdentifier} with Metricbeat', values: { instanceIdentifier, instanceName } }); } let noClusterUuidPrompt = null; if (product.isFullyMigrated && product.clusterUuid === null) { noClusterUuidPrompt = /*#__PURE__*/_react.default.createElement(_react.Fragment, null, /*#__PURE__*/_react.default.createElement(_eui.EuiCallOut, { color: "warning", iconType: "help", title: _i18n.i18n.translate('xpack.monitoring.metricbeatMigration.flyout.noClusterUuidTitle', { defaultMessage: 'No cluster detected' }) }, /*#__PURE__*/_react.default.createElement("p", null, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.monitoring.metricbeatMigration.flyout.noClusterUuidDescription", defaultMessage: "This {productName} {instanceIdentifier} is not connected to an Elasticsearch cluster so once fully migrated, this {productName} {instanceIdentifier} will appear in the Standalone cluster instead of this one. {link}", values: { productName, instanceIdentifier, link: /*#__PURE__*/_react.default.createElement(_eui.EuiLink, { href: `#/overview?_g=(cluster_uuid:__standalone_cluster__)`, target: "_blank" }, "Click here to view the Standalone cluster.") } })), /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "s" }), /*#__PURE__*/_react.default.createElement(_eui.EuiCheckbox, { id: "monitoringFlyoutNoClusterUuidCheckbox", label: _i18n.i18n.translate('xpack.monitoring.metricbeatMigration.flyout.noClusterUuidCheckboxLabel', { defaultMessage: `Yes, I understand that I will need to look in the Standalone cluster for this {productName} {instanceIdentifier}.`, values: { productName, instanceIdentifier } }), checked: this.state.userAcknowledgedNoClusterUuidPrompt, onChange: e => this.setState({ userAcknowledgedNoClusterUuidPrompt: e.target.checked }) })), /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "s" })); } return /*#__PURE__*/_react.default.createElement(_eui.EuiFlyout, { onClose: onClose, "aria-labelledby": "flyoutTitle" }, /*#__PURE__*/_react.default.createElement(_eui.EuiFlyoutHeader, { hasBorder: true }, /*#__PURE__*/_react.default.createElement(_eui.EuiTitle, { size: "m" }, /*#__PURE__*/_react.default.createElement("h2", { id: "flyoutTitle" }, title))), /*#__PURE__*/_react.default.createElement(_eui.EuiFlyoutBody, null, this.renderActiveStep(), noClusterUuidPrompt), /*#__PURE__*/_react.default.createElement(_eui.EuiFlyoutFooter, { style: { marginBottom: '64px' } }, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, { justifyContent: "spaceBetween" }, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, { grow: false }, /*#__PURE__*/_react.default.createElement(_eui.EuiButtonEmpty, { iconType: "cross", onClick: onClose, flush: "left" }, _i18n.i18n.translate('xpack.monitoring.metricbeatMigration.flyout.closeButtonLabel', { defaultMessage: 'Close' }))), /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, { grow: false }, this.renderActiveStepNextButton())))); } } exports.Flyout = Flyout;