"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.getDefaultAnomaliesTableState = exports.AnomaliesTableInternal = exports.AnomaliesTable = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _propTypes = _interopRequireDefault(require("prop-types")); var _lodash = require("lodash"); var _react = _interopRequireWildcard(require("react")); var _eui = require("@elastic/eui"); var _i18nReact = require("@kbn/i18n-react"); var _mlUrlState = require("@kbn/ml-url-state"); var _anomalies_table_columns = require("./anomalies_table_columns"); var _anomaly_details = require("./anomaly_details"); var _table_service = require("../../services/table_service"); var _rule_editor = require("../rule_editor"); var _ml_api_service = require("../../services/ml_api_service"); var _anomalies_table_constants = require("./anomalies_table_constants"); 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 table for displaying a list of anomalies. */ class AnomaliesTableInternal extends _react.Component { constructor(props) { super(props); (0, _defineProperty2.default)(this, "isShowingAggregatedData", () => { return this.props.tableData.interval !== 'second'; }); (0, _defineProperty2.default)(this, "toggleRow", async (item, tab = _anomalies_table_constants.ANOMALIES_TABLE_TABS.DETAILS) => { const itemIdToExpandedRowMap = { ...this.state.itemIdToExpandedRowMap }; if (itemIdToExpandedRowMap[item.rowId]) { delete itemIdToExpandedRowMap[item.rowId]; } else { const examples = item.entityName === 'mlcategory' ? (0, _lodash.get)(this.props.tableData, ['examplesByJobId', item.jobId, item.entityValue]) : undefined; let definition = undefined; if (examples !== undefined) { try { definition = await _ml_api_service.ml.results.getCategoryDefinition(item.jobId, item.source.mlcategory[0]); if (definition.terms && definition.terms.length > _anomalies_table_constants.MAX_CHARS) { definition.terms = `${definition.terms.substring(0, _anomalies_table_constants.MAX_CHARS)}...`; } if (definition.regex && definition.regex.length > _anomalies_table_constants.MAX_CHARS) { definition.terms = `${definition.regex.substring(0, _anomalies_table_constants.MAX_CHARS)}...`; } } catch (error) { console.log('Error fetching category definition for row item.', error); } } const job = this.props.selectedJobs.find(({ id }) => id === item.jobId); itemIdToExpandedRowMap[item.rowId] = /*#__PURE__*/_react.default.createElement(_anomaly_details.AnomalyDetails, { tabIndex: tab, anomaly: item, examples: examples, definition: definition, isAggregatedData: this.isShowingAggregatedData(), filter: this.props.filter, influencerFilter: this.props.influencerFilter, influencersLimit: _anomalies_table_constants.INFLUENCERS_LIMIT, job: job }); } this.setState({ itemIdToExpandedRowMap }); }); (0, _defineProperty2.default)(this, "onMouseOverRow", record => { if (this.mouseOverRecord !== undefined) { if (this.mouseOverRecord.rowId !== record.rowId) { // Mouse is over a different row, fire mouseleave on the previous record. _table_service.mlTableService.rowMouseleave$.next({ record: this.mouseOverRecord }); // fire mouseenter on the new record. _table_service.mlTableService.rowMouseenter$.next({ record }); } } else { // Mouse is now over a row, fire mouseenter on the record. _table_service.mlTableService.rowMouseenter$.next({ record }); } this.mouseOverRecord = record; }); (0, _defineProperty2.default)(this, "onMouseLeaveRow", () => { if (this.mouseOverRecord !== undefined) { _table_service.mlTableService.rowMouseleave$.next({ record: this.mouseOverRecord }); this.mouseOverRecord = undefined; } }); (0, _defineProperty2.default)(this, "setShowRuleEditorFlyoutFunction", func => { this.setState({ showRuleEditorFlyout: func }); }); (0, _defineProperty2.default)(this, "unsetShowRuleEditorFlyoutFunction", () => { const showRuleEditorFlyout = () => {}; this.setState({ showRuleEditorFlyout }); }); (0, _defineProperty2.default)(this, "onTableChange", ({ page, sort }) => { const { tableState, updateTableState } = this.props; const result = { pageIndex: page && page.index !== undefined ? page.index : tableState.pageIndex, pageSize: page && page.size !== undefined ? page.size : tableState.pageSize, sortField: sort && sort.field !== undefined && typeof sort.field === 'string' ? sort.field : tableState.sortField, sortDirection: sort && sort.direction !== undefined ? sort.direction : tableState.sortDirection }; updateTableState(result); }); this.state = { itemIdToExpandedRowMap: {}, showRuleEditorFlyout: () => {} }; } static getDerivedStateFromProps(nextProps, prevState) { // Update the itemIdToExpandedRowMap state if a change to the table data has resulted // in an anomaly that was previously expanded no longer being in the data. const itemIdToExpandedRowMap = prevState.itemIdToExpandedRowMap; const prevExpandedNotInData = Object.keys(itemIdToExpandedRowMap).find(rowId => { const matching = nextProps.tableData.anomalies.find(anomaly => { return anomaly.rowId === rowId; }); return matching === undefined; }); if (prevExpandedNotInData !== undefined) { // Anomaly data has changed and an anomaly that was previously expanded is no longer in the data. return { itemIdToExpandedRowMap: {} }; } // Return null to indicate no change to state. return null; } render() { const { bounds, tableData, filter, influencerFilter, tableState } = this.props; if (tableData === undefined || tableData.anomalies === undefined || tableData.anomalies.length === 0) { return /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, { justifyContent: "spaceAround" }, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, { grow: false }, /*#__PURE__*/_react.default.createElement(_eui.EuiText, null, /*#__PURE__*/_react.default.createElement("h4", null, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.ml.anomaliesTable.noMatchingAnomaliesFoundTitle", defaultMessage: "No matching anomalies found" }))))); } const columns = (0, _anomalies_table_columns.getColumns)(tableData.anomalies, tableData.jobIds, tableData.examplesByJobId, this.isShowingAggregatedData(), tableData.interval, bounds, tableData.showViewSeriesLink, this.state.showRuleEditorFlyout, this.state.itemIdToExpandedRowMap, this.toggleRow, filter, influencerFilter, this.props.sourceIndicesWithGeoFields); // Use auto table layout, unless any columns (categorization examples) have truncateText // set to true which only works with a fixed layout. const tableLayout = columns.some(column => column.truncateText === true) ? 'fixed' : 'auto'; const sorting = { sort: { field: tableState.sortField, direction: tableState.sortDirection } }; const getRowProps = item => { return { onMouseOver: () => this.onMouseOverRow(item), onMouseLeave: () => this.onMouseLeaveRow(), 'data-test-subj': `mlAnomaliesListRow row-${item.rowId}` }; }; const pagination = { pageIndex: tableState.pageIndex, pageSize: tableState.pageSize, totalItemCount: tableData.anomalies.length, pageSizeOptions: [10, 25, 100] }; return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_rule_editor.RuleEditorFlyout, { setShowFunction: this.setShowRuleEditorFlyoutFunction, unsetShowFunction: this.unsetShowRuleEditorFlyoutFunction }), /*#__PURE__*/_react.default.createElement(_eui.EuiInMemoryTable, { className: "ml-anomalies-table eui-textBreakWord", items: tableData.anomalies, columns: columns, tableLayout: tableLayout, pagination: pagination, sorting: sorting, itemId: "rowId", itemIdToExpandedRowMap: this.state.itemIdToExpandedRowMap, compressed: true, rowProps: getRowProps, "data-test-subj": "mlAnomaliesTable", onTableChange: this.onTableChange })); } } exports.AnomaliesTableInternal = AnomaliesTableInternal; const getDefaultAnomaliesTableState = () => ({ pageIndex: 0, pageSize: 25, sortField: 'severity', sortDirection: 'desc' }); exports.getDefaultAnomaliesTableState = getDefaultAnomaliesTableState; const AnomaliesTable = props => { const [tableState, updateTableState] = (0, _mlUrlState.usePageUrlState)('mlAnomaliesTable', getDefaultAnomaliesTableState()); return /*#__PURE__*/_react.default.createElement(AnomaliesTableInternal, (0, _extends2.default)({}, props, { tableState: tableState, updateTableState: updateTableState })); }; exports.AnomaliesTable = AnomaliesTable; AnomaliesTableInternal.propTypes = { bounds: _propTypes.default.object.isRequired, tableData: _propTypes.default.object, filter: _propTypes.default.func, influencerFilter: _propTypes.default.func, tableState: _propTypes.default.object.isRequired, updateTableState: _propTypes.default.func.isRequired, sourceIndicesWithGeoFields: _propTypes.default.object.isRequired, selectedJobs: _propTypes.default.array.isRequired };