"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useDataTablesStorage = exports.migrateTriggerActionsVisibleColumnsAlertTable88xTo89 = exports.migrateLegacyTimelinesToSecurityDataTable = exports.migrateColumnWidthToInitialWidth = exports.migrateColumnLabelToDisplayAsText = exports.migrateAlertTableStateToTriggerActionsState = exports.getDataTablesInStorageByIds = exports.getAllDataTablesInStorage = exports.addTableInStorage = exports.LOCAL_STORAGE_TABLE_KEY = void 0; var _fp = require("lodash/fp"); var _securitysolutionDataTable = require("@kbn/securitysolution-data-table"); var _constants = require("../../../../common/constants"); var _kibana = require("../../../common/lib/kibana"); /* * 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 LOCAL_STORAGE_TABLE_KEY = 'securityDataTable'; exports.LOCAL_STORAGE_TABLE_KEY = LOCAL_STORAGE_TABLE_KEY; const LOCAL_STORAGE_TIMELINE_KEY_LEGACY = 'timelines'; const EMPTY_TABLE = {}; /** * Migrates the values of the data table from the legacy timelines key to the securityDataTable key */ // eslint-disable-next-line @typescript-eslint/no-explicit-any const migrateLegacyTimelinesToSecurityDataTable = legacyTimelineTables => { if (!legacyTimelineTables) { return EMPTY_TABLE; } return Object.keys(legacyTimelineTables).reduce((acc, timelineTableId) => { const timelineModel = legacyTimelineTables[timelineTableId]; return { ...acc, [timelineTableId]: { defaultColumns: timelineModel.defaultColumns, dataViewId: timelineModel.dataViewId, excludedRowRendererIds: timelineModel.excludedRowRendererIds, filters: timelineModel.filters, indexNames: timelineModel.indexNames, loadingEventIds: timelineModel.loadingEventIds, isSelectAllChecked: timelineModel.isSelectAllChecked, itemsPerPage: timelineModel.itemsPerPage, itemsPerPageOptions: timelineModel.itemsPerPageOptions, showCheckboxes: timelineModel.showCheckboxes, graphEventId: timelineModel.graphEventId, sessionViewConfig: timelineModel.sessionViewConfig, selectAll: timelineModel.selectAll, id: timelineModel.id, title: timelineModel.title, initialized: timelineModel.initialized, updated: timelineModel.updated, sort: timelineModel.sort, selectedEventIds: timelineModel.selectedEventIds, deletedEventIds: timelineModel.deletedEventIds, expandedDetail: timelineModel.expandedDetail, totalCount: timelineModel.totalCount || 0, viewMode: _constants.VIEW_SELECTION.gridView, additionalFilters: { showBuildingBlockAlerts: false, showOnlyThreatIndicatorAlerts: false }, ...(Array.isArray(timelineModel.columns) ? { columns: timelineModel.columns.map(migrateColumnWidthToInitialWidth).map(migrateColumnLabelToDisplayAsText) } : {}) } }; }, {}); }; /* * * This migraiton only works for upgrading from * 8.7 -> 8.8. Please do not edit this migration for any * future release. * * If there is a migration that is required to be done for * any future release. It should written as a saperate piece of code * and should be called after this migration * * **/ exports.migrateLegacyTimelinesToSecurityDataTable = migrateLegacyTimelinesToSecurityDataTable; const migrateAlertTableStateToTriggerActionsState = (storage, legacyDataTableState) => { const triggerActionsStateKey = { [_securitysolutionDataTable.TableId.alertsOnAlertsPage]: `detection-engine-alert-table-${_constants.ALERTS_TABLE_REGISTRY_CONFIG_IDS.ALERTS_PAGE}-gridView`, [_securitysolutionDataTable.TableId.alertsOnRuleDetailsPage]: `detection-engine-alert-table-${_constants.ALERTS_TABLE_REGISTRY_CONFIG_IDS.RULE_DETAILS}-gridView` }; const triggersActionsState = Object.keys(legacyDataTableState).filter(tableKey => { return tableKey in triggerActionsStateKey && !storage.get(triggerActionsStateKey[tableKey]); }).map(tableKey => { const newKey = triggerActionsStateKey[tableKey]; return { [newKey]: { columns: legacyDataTableState[tableKey].columns, sort: legacyDataTableState[tableKey].sort.map(sortCandidate => ({ [sortCandidate.columnId]: { order: sortCandidate.sortDirection } })), visibleColumns: legacyDataTableState[tableKey].columns } }; }); triggersActionsState.forEach(stateObj => Object.keys(stateObj).forEach(key => { storage.set(key, stateObj[key]); })); }; /* * * Used for migrating Alert Table from 8.8 => 8.9 * */ exports.migrateAlertTableStateToTriggerActionsState = migrateAlertTableStateToTriggerActionsState; const migrateTriggerActionsVisibleColumnsAlertTable88xTo89 = storage => { const localStorageKeys = [`detection-engine-alert-table-${_constants.ALERTS_TABLE_REGISTRY_CONFIG_IDS.ALERTS_PAGE}-gridView`, `detection-engine-alert-table-${_constants.ALERTS_TABLE_REGISTRY_CONFIG_IDS.RULE_DETAILS}-gridView`]; localStorageKeys.forEach(key => { const alertTableData = storage.get(key); if (!alertTableData) { return; } if ('visibleColumns' in alertTableData) { const visibleColumns = alertTableData.visibleColumns; const v89CompliantFormat = visibleColumns.every(val => typeof val === 'string'); if (v89CompliantFormat) { return; } const newVisibleColumns = visibleColumns.map(visibleCol => { if (typeof visibleCol === 'string') { // if column format is 8.9 compliant already return visibleCol; } // if column format is 8.8 return visibleCol.id; }).filter(Boolean); storage.set(key, { ...alertTableData, visibleColumns: newVisibleColumns }); } }); }; /** * Migrates the value of the column's `width` property to `initialWidth` * when `width` is valid, and `initialWidth` is invalid */ exports.migrateTriggerActionsVisibleColumnsAlertTable88xTo89 = migrateTriggerActionsVisibleColumnsAlertTable88xTo89; const migrateColumnWidthToInitialWidth = column => ({ ...column, ...(Number.isInteger(column.width) && !Number.isInteger(column.initialWidth) ? { initialWidth: column.width } : column.initialWidth ? { initialWidth: column.initialWidth } : {}) }); /** * Migrates the value of the column's `label` property to `displayAsText` * when `label` is valid, and `displayAsText` is `undefined` */ exports.migrateColumnWidthToInitialWidth = migrateColumnWidthToInitialWidth; const migrateColumnLabelToDisplayAsText = column => ({ ...column, ...(!(0, _fp.isEmpty)(column.label) && column.displayAsText == null ? { displayAsText: column.label } : column.displayAsText ? { displayAsText: column.displayAsText } : {}) }); exports.migrateColumnLabelToDisplayAsText = migrateColumnLabelToDisplayAsText; const getDataTablesInStorageByIds = (storage, tableIds) => { let allDataTables = storage.get(LOCAL_STORAGE_TABLE_KEY); const legacyTimelineTables = storage.get(LOCAL_STORAGE_TIMELINE_KEY_LEGACY); if (!allDataTables) { if (legacyTimelineTables) { allDataTables = migrateLegacyTimelinesToSecurityDataTable(legacyTimelineTables); } else { return EMPTY_TABLE; } } migrateAlertTableStateToTriggerActionsState(storage, allDataTables); migrateTriggerActionsVisibleColumnsAlertTable88xTo89(storage); return tableIds.reduce((acc, tableId) => { const tableModel = allDataTables[tableId]; if (!tableModel) { return { ...acc }; } return { ...acc, [tableId]: { ...tableModel, ...(tableModel.sort != null && !Array.isArray(tableModel.sort) ? { sort: [tableModel.sort] } : {}) } }; }, {}); }; exports.getDataTablesInStorageByIds = getDataTablesInStorageByIds; const getAllDataTablesInStorage = storage => { let allDataTables = storage.get(LOCAL_STORAGE_TABLE_KEY); const legacyTimelineTables = storage.get(LOCAL_STORAGE_TIMELINE_KEY_LEGACY); if (!allDataTables) { if (legacyTimelineTables) { allDataTables = migrateLegacyTimelinesToSecurityDataTable(legacyTimelineTables); } else { return EMPTY_TABLE; } } return allDataTables; }; exports.getAllDataTablesInStorage = getAllDataTablesInStorage; const addTableInStorage = (storage, id, table) => { const tableToStore = getSerializingTableToStore(table); const tables = getAllDataTablesInStorage(storage); storage.set(LOCAL_STORAGE_TABLE_KEY, { ...tables, [id]: tableToStore }); }; exports.addTableInStorage = addTableInStorage; const getSerializingTableToStore = table => { // discard unneeded fields to make sure the object serialization works const { isLoading, loadingText, queryFields, unit, ...tableToStore } = table; return tableToStore; }; const useDataTablesStorage = () => { const { storage } = (0, _kibana.useKibana)().services; const getAllDataTables = () => getAllDataTablesInStorage(storage); const getDataTablesById = id => { var _getDataTablesInStora; return (_getDataTablesInStora = getDataTablesInStorageByIds(storage, [id])[id]) !== null && _getDataTablesInStora !== void 0 ? _getDataTablesInStora : null; }; const addDataTable = (id, table) => addTableInStorage(storage, id, table); return { getAllDataTables, getDataTablesById, addDataTable }; }; exports.useDataTablesStorage = useDataTablesStorage;