"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AnomalyDetails = void 0; var _react = _interopRequireWildcard(require("react")); var _i18n = require("@kbn/i18n"); var _i18nReact = require("@kbn/i18n-react"); var _lodash = require("lodash"); var _eui = require("@elastic/eui"); var _mlIsPopulatedObject = require("@kbn/ml-is-populated-object"); var _mlAnomalyUtils = require("@kbn/ml-anomaly-utils"); var _anomalies_table_constants = require("./anomalies_table_constants"); var _anomaly_details_utils = require("./anomaly_details_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; } /* * 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. */ /* * React component for displaying details of an anomaly in the expanded row section * of the anomalies table. */ const AnomalyDetails = ({ anomaly, examples, definition, isAggregatedData, filter, influencersLimit, influencerFilter, tabIndex, job }) => { if (examples !== undefined && examples.length > 0) { const tabs = [{ id: 'Details', name: _i18n.i18n.translate('xpack.ml.anomaliesTable.anomalyDetails.detailsTitle', { defaultMessage: 'Details' }), content: /*#__PURE__*/_react.default.createElement(Contents, { anomaly: anomaly, filter: filter, influencerFilter: influencerFilter, influencersLimit: influencersLimit, isAggregatedData: isAggregatedData, job: job }) }, { id: 'category-examples', name: _i18n.i18n.translate('xpack.ml.anomaliesTable.anomalyDetails.categoryExamplesTitle', { defaultMessage: 'Category examples' }), content: /*#__PURE__*/_react.default.createElement(CategoryExamples, { examples: examples, definition: definition }) }]; return /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, null, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, null, /*#__PURE__*/_react.default.createElement(_eui.EuiTabbedContent, { tabs: tabs, size: "s", initialSelectedTab: tabs[tabIndex], onTabClick: () => {} }))); } return /*#__PURE__*/_react.default.createElement(Contents, { anomaly: anomaly, filter: filter, influencerFilter: influencerFilter, influencersLimit: influencersLimit, isAggregatedData: isAggregatedData, job: job }); }; exports.AnomalyDetails = AnomalyDetails; const Contents = ({ anomaly, isAggregatedData, filter, influencersLimit, influencerFilter, job }) => { const { euiTheme: { colors } } = (0, _eui.useEuiTheme)(); const dividerStyle = (0, _react.useMemo)(() => { return (0, _mlIsPopulatedObject.isPopulatedObject)(anomaly.source.anomaly_score_explanation) ? { borderRight: `1px solid ${colors.lightShade}` } : {}; }, [colors, anomaly]); return /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, null, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, null, /*#__PURE__*/_react.default.createElement("div", { className: "ml-anomalies-table-details", "data-test-subj": "mlAnomaliesListRowDetails" }, /*#__PURE__*/_react.default.createElement(Description, { anomaly: anomaly }), /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "m" }), /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, { gutterSize: "l" }, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, { css: dividerStyle }, /*#__PURE__*/_react.default.createElement(Details, { anomaly: anomaly, isAggregatedData: isAggregatedData, filter: filter, job: job }), /*#__PURE__*/_react.default.createElement(Influencers, { anomaly: anomaly, influencerFilter: influencerFilter, influencersLimit: influencersLimit })), /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, null, /*#__PURE__*/_react.default.createElement(_anomaly_details_utils.AnomalyExplanationDetails, { anomaly: anomaly })))))); }; const Description = ({ anomaly }) => { const source = anomaly.source; let anomalyDescription = _i18n.i18n.translate('xpack.ml.anomaliesTable.anomalyDetails.anomalyInLabel', { defaultMessage: '{anomalySeverity} anomaly in {anomalyDetector}', values: { anomalySeverity: (0, _lodash.capitalize)((0, _mlAnomalyUtils.getSeverity)(anomaly.severity).label), anomalyDetector: anomaly.detector } }); if (anomaly.entityName !== undefined) { anomalyDescription += _i18n.i18n.translate('xpack.ml.anomaliesTable.anomalyDetails.foundForLabel', { defaultMessage: ' found for {anomalyEntityName} {anomalyEntityValue}', values: { anomalyEntityName: anomaly.entityName, anomalyEntityValue: anomaly.entityValue } }); } if (source.partition_field_name !== undefined && source.partition_field_name !== anomaly.entityName) { anomalyDescription += _i18n.i18n.translate('xpack.ml.anomaliesTable.anomalyDetails.detectedInLabel', { defaultMessage: ' detected in {sourcePartitionFieldName} {sourcePartitionFieldValue}', values: { sourcePartitionFieldName: source.partition_field_name, sourcePartitionFieldValue: source.partition_field_value } }); } // Check for a correlatedByFieldValue in the source which will be present for multivariate analyses // where the record is anomalous due to relationship with another 'by' field value. let mvDescription; if (source.correlated_by_field_value !== undefined) { mvDescription = _i18n.i18n.translate('xpack.ml.anomaliesTable.anomalyDetails.multivariateDescription', { defaultMessage: 'multivariate correlations found in {sourceByFieldName}; ' + '{sourceByFieldValue} is considered anomalous given {sourceCorrelatedByFieldValue}', values: { sourceByFieldName: source.by_field_name, sourceByFieldValue: source.by_field_value, sourceCorrelatedByFieldValue: source.correlated_by_field_value } }); } return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_eui.EuiText, { size: "xs" }, /*#__PURE__*/_react.default.createElement("h4", null, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.ml.anomaliesTable.anomalyDetails.descriptionTitle", defaultMessage: "Description" })), anomalyDescription), mvDescription !== undefined && /*#__PURE__*/_react.default.createElement(_eui.EuiText, { size: "xs" }, mvDescription)); }; const Details = ({ anomaly, isAggregatedData, filter, job }) => { var _anomaly$source$is_in, _anomaly$source; const isInterimResult = (_anomaly$source$is_in = (_anomaly$source = anomaly.source) === null || _anomaly$source === void 0 ? void 0 : _anomaly$source.is_interim) !== null && _anomaly$source$is_in !== void 0 ? _anomaly$source$is_in : false; return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_eui.EuiText, { size: "xs" }, isAggregatedData === true ? /*#__PURE__*/_react.default.createElement("h4", null, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.ml.anomaliesTable.anomalyDetails.detailsOnHighestSeverityAnomalyTitle", defaultMessage: "Details on highest severity anomaly" })) : /*#__PURE__*/_react.default.createElement("h4", null, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.ml.anomaliesTable.anomalyDetails.anomalyDetailsTitle", defaultMessage: "Anomaly details" })), isInterimResult === true && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_eui.EuiIcon, { type: "warning" }), /*#__PURE__*/_react.default.createElement("span", { className: "interim-result" }, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.ml.anomaliesTable.anomalyDetails.interimResultLabel", defaultMessage: "Interim result" })))), /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "xs" }), /*#__PURE__*/_react.default.createElement(_anomaly_details_utils.DetailsItems, { anomaly: anomaly, filter: filter, modelPlotEnabled: job.modelPlotEnabled })); }; const Influencers = ({ anomaly, influencersLimit, influencerFilter }) => { const [showAllInfluencers, setShowAllInfluencers] = (0, _react.useState)(false); const toggleAllInfluencers = setShowAllInfluencers.bind(null, prev => !prev); const anomalyInfluencers = anomaly.influencers; let listItems = []; let othersCount = 0; let numToDisplay = 0; if (anomalyInfluencers !== undefined) { numToDisplay = showAllInfluencers === true ? anomalyInfluencers.length : Math.min(influencersLimit, anomalyInfluencers.length); othersCount = Math.max(anomalyInfluencers.length - numToDisplay, 0); if (othersCount === 1) { // Display the 1 extra influencer as displaying "and 1 more" would also take up a line. numToDisplay++; othersCount = 0; } listItems = (0, _anomaly_details_utils.getInfluencersItems)(anomalyInfluencers, influencerFilter, numToDisplay); } if (listItems.length > 0) { return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "m" }), /*#__PURE__*/_react.default.createElement(_eui.EuiText, { size: "xs" }, /*#__PURE__*/_react.default.createElement("h4", null, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.ml.anomaliesTable.anomalyDetails.influencersTitle", defaultMessage: "Influencers" }))), listItems.map(({ title, description }) => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, { gutterSize: "none" }, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, { style: { width: '180px' }, grow: false }, title), /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, null, description)), /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "xs" }))), othersCount > 0 && /*#__PURE__*/_react.default.createElement(_eui.EuiLink, { onClick: () => toggleAllInfluencers() }, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.ml.anomaliesTable.anomalyDetails.anomalyDescriptionListMoreLinkText", defaultMessage: "and {othersCount} more", values: { othersCount } })), numToDisplay > influencersLimit + 1 && /*#__PURE__*/_react.default.createElement(_eui.EuiLink, { onClick: () => toggleAllInfluencers() }, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.ml.anomaliesTable.anomalyDetails.anomalyDescriptionShowLessLinkText", defaultMessage: "Show less" }))); } return null; }; const CategoryExamples = ({ definition, examples }) => { return /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, { direction: "column", justifyContent: "center", gutterSize: "m", className: "mlAnomalyCategoryExamples" }, definition !== undefined && definition.terms && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, { key: `example-terms` }, /*#__PURE__*/_react.default.createElement(_eui.EuiText, { size: "xs" }, /*#__PURE__*/_react.default.createElement("h4", { className: "mlAnomalyCategoryExamples__header" }, _i18n.i18n.translate('xpack.ml.anomaliesTable.anomalyDetails.termsTitle', { defaultMessage: 'Terms' })), "\xA0", /*#__PURE__*/_react.default.createElement(_eui.EuiIconTip, { "aria-label": _i18n.i18n.translate('xpack.ml.anomaliesTable.anomalyDetails.termsDescriptionAriaLabel', { defaultMessage: 'Description' }), type: "questionInCircle", color: "subdued", size: "s", content: /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.ml.anomaliesTable.anomalyDetails.termsDescriptionTooltip", defaultMessage: "A space separated list of the common tokens that are matched in values of the category (may have been truncated to a max character limit of {maxChars})", values: { maxChars: _anomalies_table_constants.MAX_CHARS } }) })), /*#__PURE__*/_react.default.createElement(_eui.EuiText, { size: "xs" }, definition.terms)), /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "xs" })), definition !== undefined && definition.regex && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, { key: `example-regex` }, /*#__PURE__*/_react.default.createElement(_eui.EuiText, { size: "xs" }, /*#__PURE__*/_react.default.createElement("h4", { className: "mlAnomalyCategoryExamples__header" }, _i18n.i18n.translate('xpack.ml.anomaliesTable.anomalyDetails.regexTitle', { defaultMessage: 'Regex' })), "\xA0", /*#__PURE__*/_react.default.createElement(_eui.EuiIconTip, { "aria-label": _i18n.i18n.translate('xpack.ml.anomaliesTable.anomalyDetails.regexDescriptionAriaLabel', { defaultMessage: 'Description' }), type: "questionInCircle", color: "subdued", size: "s", content: /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.ml.anomaliesTable.anomalyDetails.regexDescriptionTooltip", defaultMessage: "The regular expression that is used to search for values that match the category (may have been truncated to a max character limit of {maxChars})", values: { maxChars: _anomalies_table_constants.MAX_CHARS } }) })), /*#__PURE__*/_react.default.createElement(_eui.EuiText, { size: "xs" }, definition.regex)), /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "xs" })), examples.map((example, i) => { return /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, { key: `example${i}` }, i === 0 && definition !== undefined && /*#__PURE__*/_react.default.createElement(_eui.EuiText, { size: "s" }, /*#__PURE__*/_react.default.createElement("h4", null, _i18n.i18n.translate('xpack.ml.anomaliesTable.anomalyDetails.examplesTitle', { defaultMessage: 'Examples' }))), /*#__PURE__*/_react.default.createElement("span", { className: "mlAnomalyCategoryExamples__item" }, example)); })); };